Rev 307 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
package test.display;
import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.io.RandomAccessFile;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import uk.me.parabola.imgfmt.Utils;
import uk.me.parabola.imgfmt.app.BufferedImgFileReader;
import uk.me.parabola.imgfmt.app.ImgFileReader;
import uk.me.parabola.imgfmt.app.lbl.LBLFileReader;
import uk.me.parabola.imgfmt.app.net.NETFileReader;
import uk.me.parabola.imgfmt.app.trergn.TREFileReader;
import uk.me.parabola.imgfmt.fs.DirectoryEntry;
import uk.me.parabola.imgfmt.fs.FileSystem;
import uk.me.parabola.imgfmt.fs.ImgChannel;
import uk.me.parabola.imgfmt.sys.FileImgChannel;
import uk.me.parabola.imgfmt.sys.ImgFS;
import test.files.RgnFile;
/**
* Common code for files that have the 'common header' in a .img file.
*/
public abstract class CommonDisplay
{
public static final int COMMON_HEADER_LEN =
21;
// You will always have a reader.
protected ImgFileReader reader
;
// You may not have a filesystem.
private FileSystem fs
;
protected PrintStream outStream =
new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.
out)));
private int headerLen
;
protected long filelen
;
// The sections in the file, if any.
protected SectList sections =
new SectList
();
protected LBLFileReader lbl
;
protected TREFileReader tre
;
protected RgnFile rgn
;
protected NETFileReader net
;
protected abstract void print
();
protected void readCommonHeader
() {
Displayer d =
new Displayer
(reader
);
d.
setTitle("Common Header");
headerLen = d.
charValue("Header length %d");
d.
stringValue(10,
"File type %s");
d.
byteValue("???");
d.
byteValue("Set if locked");
DisplayItem item = d.
rawItem(7);
Date date = Utils.
makeCreationTime(item.
getBytes());
DateFormat df =
new SimpleDateFormat("HH:mm:ss d MMM yyyy");
item.
addText(df.
format(date
));
d.
print(outStream
);
}
protected void readHeaderLen
() {
reader.
position(0);
headerLen = reader.
getChar();
reader.
position(COMMON_HEADER_LEN
);
}
/**
* Read the common combination offset + size (+ record size) in file headers.
* Utility function for subclasses.
*
* @param d The Displayer to use.
* @param name The name of the subfile.
* @param number The section number.
* @param hasRecSize There is a record size to be read.
* @param hasMagic Has an 4 byte integer value following the header information. Otherwise
* false and any extra values must be read explicitly.
* @return The section information. It has also been saved for retrieval with getSection.
*/
protected Section readSection
(Displayer d,
String name,
int number,
boolean hasRecSize,
boolean hasMagic
) {
assert number
!=
0;
d.
gap();
int start = d.
intValue(name +
" at offset %#08x");
int len = d.
intValue(name +
" length %d");
Section section =
new Section
(name, start, len
);
d.
item().
addText("End of section %08x, len %#08x", start + len, len
);
if (hasRecSize
) {
int recordSize = d.
charValue(name +
" record size %02x");
if (recordSize
!=
0) {
//assert len % recordSize == 0 : "sect" + number + ", len=" + len + ", recsize=" + recordSize;
d.
item().
addText("Number of records %d", len / recordSize
);
if (len
% recordSize
!=
0)
d.
item().
addText("FRACTIONAL RECORD");
}
section.
setRecordSize(recordSize
);
}
if (hasMagic
) {
int magic = d.
intValue(name +
" header flags %04x");
section.
setMagic(magic
);
}
while (sections.
size() < number-
1)
sections.
add(null);
sections.
add(number-
1, section
);
return section
;
}
protected Section getSection
(int n
) {
assert n
!=
0;
return sections.
get(n-
1);
}
protected int numberOfSections
() {
return sections.
size();
}
/**
* This is used when you want to open a plain file.
* @param name The name of the file to open.
*/
protected void display
(String name
) {
RandomAccessFile raf =
null;
try {
raf =
new RandomAccessFile(name,
"r");
filelen = raf.
length();
ImgChannel chan =
new FileImgChannel
(raf.
getChannel());
this.
reader =
new BufferedImgFileReader
(chan
);
print
();
outStream.
flush();
} catch (FileNotFoundException e
) {
System.
err.
println("Could not open file: " + name
);
} catch (IOException e
) {
System.
err.
println("Could not get file size or read file " + name
);
} finally {
if (raf
!=
null) {
try {
raf.
close();
} catch (IOException e
) {
// ok
}
}
}
}
/**
* This is used to open a file within an img file.
*
* @param name The name of the .img file.
* @param fileExt The file to get. It is found by extension.
*/
protected void display
(String name,
String fileExt
) {
if (name.
toLowerCase().
endsWith(fileExt.
toLowerCase())) {
display
(name
);
return;
}
try {
fs = ImgFS.
openFs(name
);
ImgChannel chan = findFile
(fileExt
);
this.
reader =
new BufferedImgFileReader
(chan
);
print
();
outStream.
flush();
} catch (FileNotFoundException e
) {
System.
err.
println("Could not open file: " + name
);
} finally {
if (fs
!=
null) {
fs.
close();
}
}
}
protected ImgChannel findFile
(String fileExt
) throws FileNotFoundException {
if (fs ==
null)
throw new FileNotFoundException("Not an img file");
List<DirectoryEntry
> entries = fs.
list();
ImgChannel chan =
null;
for (DirectoryEntry ent : entries
) {
if (ent.
getExt().
equals(fileExt
)) {
filelen = ent.
getSize();
chan = fs.
open(ent.
getFullName(),
"r");
}
}
if (chan ==
null)
throw new FileNotFoundException("No file with " + fileExt +
" extension");
return chan
;
}
protected void openLbl
() {
try {
ImgChannel chan = findFile
("LBL");
lbl =
new LBLFileReader
(chan
);
} catch (FileNotFoundException e
) {
System.
err.
println("Could not open LBL file");
}
}
protected String fetchLabel
(int laboff
) {
if (lbl ==
null)
return "";
return lbl.
fetchLabel(laboff
).
getText();
}
protected void openTre
() {
try {
ImgChannel chan = findFile
("TRE");
tre =
new TREFileReader
(chan
);
} catch (FileNotFoundException e
) {
System.
err.
println("Could not open TRE file");
}
}
protected void openRgn
() {
if (lbl ==
null)
openLbl
();
try {
ImgChannel chan = findFile
("RGN");
rgn =
new RgnFile
(chan
);
rgn.
setLblFile(lbl
);
} catch (FileNotFoundException e
) {
System.
err.
println("Could not open RGN file");
}
}
protected void openNet
() {
try {
ImgChannel chan = findFile
("NET");
net =
new NETFileReader
(chan
);
} catch (FileNotFoundException e
) {
System.
err.
println("Could not open RGN file");
}
}
protected void setOutStream
(PrintStream outStream
) {
this.
outStream = outStream
;
}
protected int getHeaderLen
() {
return headerLen
;
}
protected void analyze
(PrintStream outStream
) {
sections.
analyze(outStream
);
}
protected void addSection
(Section section
) {
sections.
add(section
);
}
}