Rev 578 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2009.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 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.
*/
package test.display;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Standalone program to display an MDR file. There is no freely available
* knowledge of the file format.
*
* Can produce a massive file, so may take some time to write.
*
* @author Steve Ratcliffe
*/
public class MdrSummary
extends CommonDisplay
{
private static final int NSECT =
41;
private final Section
[] sections =
new Section
[NSECT
];
// Sections to be displayed
private final boolean[] wanted =
new boolean[NSECT
];
protected void print
() {
readHeaderLen
();
readHeader
();
Section end =
new Section
("END OF FILE", filelen,
0);
sections
[sections.
length -
1] = end
;
printDetails
();
printReverseDetails
();
}
private void printReverseDetails
() {
Section section = sections
[1];
if (section.
getRecordSize() ==
4)
return;
reader.
position(section.
getStart());
long end = section.
getEnd();
List<Integer> offsets =
new ArrayList<Integer>();
while ((reader.
position() < end
)) {
reader.
get4();
int offset = reader.
get4();
offsets.
add(offset
);
}
Integer[] subtotals =
new Integer[20];
for (int off : offsets
) {
reader.
position(off
);
int len = reader.
get2u();
int sub =
0;
int lastLen =
0;
while (reader.
position() < off + len
) {
sub++
;
reader.
get4();
int sublen
;
if (sub ==
2)
sublen = lastLen
;
else
sublen = reader.
get4();
lastLen = sublen
;
if (sublen
> 0) {
if (subtotals
[sub
] ==
null)
subtotals
[sub
] =
0;
subtotals
[sub
] += sublen
;
}
}
}
int sub =
0;
for (Integer tot : subtotals
) {
if (tot
!=
null)
System.
out.
printf("Sub%-2d %-5s total %d\n", sub, Mdr1SubFileDisplay.
subToMdr(sub
), tot
);
sub++
;
}
}
private void printDetails
() {
int number =
0;
for (Section s : sections
) {
if (s
!=
null) {
if (s.
getLen() > 0)
System.
out.
printf("MDR %-2d ", number
);
else
System.
out.
printf(" %-2d ", number
);
if (s.
getRecordSize() > 0)
System.
out.
printf("NR=%-7d(%06x) RS=%-2d ",
s.
getNumberOfRecords(),
s.
getNumberOfRecords(),
s.
getRecordSize());
else
System.
out.
printf("DS=%-10d(%08x) ", s.
getLen(), s.
getLen());
System.
out.
printf("magic=0x%08x\n", s.
getMagic());
}
number++
;
}
}
private void readHeader
() {
int codePage = reader.
get2u();
int id1 = reader.
get2u();
int id2 = reader.
get2u();
int unk3 = reader.
get2u();
System.
out.
printf("codePage=%d id1=%d id2=%d unk=0x%04x hdrLen=%d\n", codePage, id1, id2, unk3, getHeaderLen
());
addSection
(1,
true,
true);
addSection
(2,
true,
true);
addSection
(3,
true,
true);
addSection
(4,
true,
true);
addSection
(5,
true,
true);
addSection
(6,
true,
true);
addSection
(7,
true,
true);
addSection
(8,
true,
true);
addSection
(9,
true,
true);
addSection
(10,
false,
true);
addSection
(11,
true,
true);
addSection
(12,
true,
true);
addSection
(13,
true,
true);
addSection
(14,
true,
true);
addSection
(15,
false,
false); // could consider compressed string flag as 1 byte magic
int flag = reader.
get();
System.
out.
printf("Compressed strings flag=0x%04x\n", flag
);
addSection
(16,
true,
true);
addSection
(17,
false,
true);
addSection
(18,
true,
true);
addSection
(19,
true,
true);
// seen headers stop here: 286 / 0x011e
addSection
(20,
true,
true);
addSection
(21,
true,
true);
addSection
(22,
true,
true);
addSection
(23,
true,
true);
addSection
(24,
true,
true);
addSection
(25,
true,
true);
addSection
(26,
true,
true);
addSection
(27,
true,
true);
addSection
(28,
true,
true);
addSection
(29,
true,
true);
// seen headers stop here: 426 / 0x01aa
addSection
(30,
true,
true);
addSection
(31,
false,
false);
addSection
(32,
true,
true);
addSection
(33,
false,
false);
addSection
(34,
true,
true);
addSection
(35,
true,
true);
addSection
(36,
true,
true);
addSection
(37,
true,
true);
addSection
(38,
true,
true);
addSection
(39,
true,
true);
addSection
(40,
true,
true);
// seen headers stop here: 568 / 0x0238
// looks like three sections, two with 4 ints, one with 5 ints
// seen headers stop here: 620 / 0x26c
// mostly zeros
// seen headers stop here: 668 / 0x029c
// possibly some sections, but mostly zeros so difficult to tell
// seen headers stop here: 700 / 0x02bc
// seen headers stop here: 708 / 0x02c4
// at 0x02dc, maybe 5 sections without magic or recsize
// not seen anything after 772 / 0x0304
}
private Section addSection
(int n,
boolean withReclen,
boolean withMagic
) {
if (reader.
position() >= getHeaderLen
())
return null;
long start = reader.
get4();
int len = reader.
get4();
Section section =
new Section
("MDR " + n, start, len
);
if (withReclen
) {
int reclen = reader.
get2u();
section.
setRecordSize(reclen
);
}
if (withMagic
) {
int magic = reader.
get4();
section.
setMagic(magic
);
}
sections
[n
] = section
;
return section
;
}
/**
* Print a summary of an mdr file.
*/
public static void main
(String[] args
) {
if (args.
length < 1) {
System.
err.
println("Usage: mdrsummary <filename>");
System.
exit(1);
}
MdrSummary md =
new MdrSummary
();
String name = args
[0];
if (args.
length > 1) {
if (args
[1].
equals("!")) {
Arrays.
fill(md.
wanted,
true);
for (String a :
Arrays.
asList(args
).
subList(2, args.
length))
md.
wanted[Integer.
parseInt(a
)] =
false;
} else {
for (String a :
Arrays.
asList(args
).
subList(1, args.
length))
md.
wanted[Integer.
parseInt(a
)] =
true;
}
} else {
Arrays.
fill(md.
wanted,
true);
}
md.
display(name,
"MDR");
}
}