Subversion Repositories display

Rev

Rev 277 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (C) 2007 Steve Ratcliffe
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *
 * Author: Steve Ratcliffe
 * Create date: Dec 16, 2007
 */

package test.display;

import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Formatter;
import java.util.List;

/**
 * An item to display.  By item we mean a byte,int,string or arbitary length
 * set of bytes.  The address of the object will be printed on the left, a hex
 * dump will be in the middle and comments will be on the right.
 *
 * You can add any number of comments, they will be printed on separate lines, in
 * the right column.
 *
 * The general look of the output is similar to imgdecode by John Mechalas.
 *
 * @author Steve Ratcliffe
 */

public class DisplayItem {
        private long startPos;

        private byte[] bytes;
        private int value;
        private int nbytes;

        private final List<String> texts = new ArrayList<String>();
        private int bytelines;
        private long sectStart;

        public void setStartPos(long startPos) {
                this.startPos = startPos;
        }

        /**
         * If this is set, then you also get another column with offsets into the
         * section.  This is in addition to the offsets into the file.
         *
         * @param sectStart The start offset of the section with respect to the
         * beginning of the (sub)-file.  (ie. NOT absolute in the .img file).
         */

        void setSectStart(long sectStart) {
                this.sectStart = sectStart;
        }

        public int setBytes(int in) {
                value = in;
                return setBytes(in, 4);
        }

        public int setBytes(char in) {
                value = in & 0xffff;
                return setBytes(in, 2);
        }

        public int setBytes(byte in) {
                value = in & 0xff;
                return setBytes(in, 1);
        }

        public int setBytes3(int in) {
                value = in & 0xffffff;
                return setBytes(in, 3) & 0xffffff;
        }

        public int getValue() {
                return value;
        }

        private int setBytes(int in, int n) {
                byte[] newbytes = new byte[nbytes + n];

                if (bytes != null)
                        System.arraycopy(bytes, 0, newbytes, 0, bytes.length);

                bytes = newbytes;
                for (int i = 0; i < n; i++) {
                        bytes[nbytes+i] = (byte) (in >> (i) * 8 & 0xff);
                }
                nbytes += n;
                return in;
        }

        public void print(PrintStream out) {
                bytelines = (nbytes + 7) / 8 ;
                int nlines = Math.max(bytelines, getTextLines());

                long pos = startPos;

                for (int i = 0; i < nlines; i++, pos+=8) {
                        if (pos >= startPos + nbytes)
                                out.print("         | ");
                        else
                                out.format("%08x | ", pos);
                        printSectOff(out, pos);
                        printBytes(out, i);
                        printLines(out, i);
                        out.println();
                }
        }

        private void printSectOff(PrintStream out, long pos) {
                if (sectStart == 0)
                        return;

                if (pos >= startPos + nbytes) {
                        out.print("       | ");
                } else {
                        out.format("%06x | ", (pos - sectStart));
                }
        }

        private void printLines(PrintStream out, int lineno) {
                if (lineno >= getTextLines())
                        return;

                String s = texts.get(lineno);
                if (s != null)
                        out.print(s);
        }

        private void printBytes(PrintStream out, int lineno) {
                int pos = lineno * 8;
                for (int i = 0; i < 8; i++, pos++) {
                        if (lineno >= bytelines || (8*lineno + i) >= nbytes) {
                                out.print("   ");
                        } else {
                                out.format("%02x ", bytes[pos]);
                        }
                }
                out.print("| ");
        }

        public void addText(String text) {
                texts.add(text);
        }

        public DisplayItem addText(String s, Object ... val) {
                StringBuffer sb = new StringBuffer();
                Formatter fmt = new Formatter(sb);
                fmt.format(s, val);
                texts.add(sb.toString());
                return this;
        }

        public byte[] setBytes(byte[] buf) {
                return setBytes(buf, buf.length);
        }

        protected byte[] setBytes(byte[] buf, int len) {
                assert this.bytes == null;
                this.bytes = buf;
                this.nbytes = len;
                return buf;
        }

        private int getTextLines() {
                return texts.size();
        }

        public byte[] getBytes() {
                return bytes;
        }
}