Rev 548 |
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.List;
import java.util.Locale;
/**
* 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<>();
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 setBytes4
(int in
) {
value = in
;
setBytes
(in,
4);
return in
;
}
public int setBytes3
(int in
) {
value = in
;
setBytes
(in,
3);
return in
;
}
public int setBytes2
(int in
) {
value = in
;
setBytes
(in,
2);
return in
;
}
public int setBytes1
(int in
) {
value = in
;
setBytes
(in,
1);
return in
;
}
public int getValue
() {
return value
;
}
private void 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
;
}
public void print
(PrintStream out
) {
bytelines =
(nbytes +
7) /
8 ;
int nlines =
Math.
max(bytelines, getTextLines
());
StringBuilder sb =
new StringBuilder(128);
long pos = startPos
;
for (int i =
0; i
< nlines
; i++, pos+=
8) {
if (pos
>= startPos + nbytes
)
sb.
append(" | ");
else {
// out.format("%08x | ", pos);
// much faster:
final String s =
Long.
toHexString(pos
);
int padding =
8 - s.
length();
if (padding
> 0)
sb.
append("00000000".
substring(0, padding
));
sb.
append(s
).
append(" | ");
}
printSectOff
(sb, pos
);
printBytes
(sb, i
);
printLines
(sb, i
);
out.
println(sb.
toString());
sb.
setLength(0);
}
}
private void printSectOff
(StringBuilder sb,
long pos
) {
if (sectStart ==
0)
return;
if (pos
>= startPos + nbytes
) {
sb.
append(" | ");
} else {
final String s =
Long.
toHexString(pos - sectStart
);
int padding =
6 - s.
length();
if (padding
> 0)
sb.
append("00000000".
substring(0, padding
));
sb.
append(s
).
append(" | ");
}
}
private void printLines
(StringBuilder sb,
int lineno
) {
if (lineno
>= getTextLines
())
return;
String s = texts.
get(lineno
);
if (s
!=
null)
sb.
append(s
);
}
private void printBytes
(StringBuilder sb,
int lineno
) {
int pos = lineno
* 8;
for (int i =
0; i
< 8; i++, pos++
) {
if (lineno
>= bytelines ||
(8*lineno + i
) >= nbytes
) {
sb.
append(" ");
} else {
String s =
Integer.
toHexString(bytes
[pos
] & 0xff
);
if (s.
length() < 2)
sb.
append('0');
sb.
append(s
).
append(' ');
}
}
sb.
append("| ");
}
public void addText
(String text
) {
texts.
add(text
);
}
public DisplayItem addText
(String s,
Object ...
val) {
texts.
add(String.
format(Locale.
ENGLISH, s, val
));
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
;
}
}