<p>If you set the background colour of a textbox, but make
no changes to the text,
</section>
+ <section><title>Structure of CONTENTS</title>
+ <p>First we have "CHNKINK ", followed by 24 bytes.</p>
+ <p>Next we have 20 sequences of 24 bytes each. If the first two bytes
+ at 0x1800, then that sequence entry exists, but if it's 0x0000 then
+ the entry doesn't exist. If it does exist, we then have 4 bytes of
+ upper case ASCII text, followed by three little endian shorts.
+ The first of these seems to be the count of that type, the second is
+ usually 1, the third is usually zero. The we have another 4 bytes of
+ upper case ASCII text, normally but not always the same as the first
+ text. Finally, we have an unsigned little endian 32 bit offset to
+ the start of the data for this, then an unsigned little endian
+ 32 bit offset of the length of this section.</p>
+ <p>Normally, the first sequence entry is for TEXT, and the text data
+ will start at 0x200. After that is normally two or three STSH entries
+ (so the first short has values 0, then 1, then 2). After that it
+ seems to vary.</p>
+ <p>At 0x200 we have the text, stored as little endian 16 bit unicode.</p>
+ <p>After the text comes all sorts of other stuff, presumably as
+ described by the sequences.</p>
+ </section>
</body>
</document>
// 00 00 00 88 1E 00 00 00
}
- public void dumpCONTENTS(DirectoryNode dir) throws IOException {
+ public void dumpCONTENTSraw(DirectoryNode dir) throws IOException {
byte[] data = getData(dir, "CONTENTS");
System.out.println("");
System.out.println("CONTENTS - " + data.length + " bytes long:");
// Between the start and 0x200 we have
- // CHNKINK(space) + 24 bytes + 0x1800
+ // CHNKINK(space) + 24 bytes
+ // 0x1800
// TEXT + 6 bytes
- // TEXT + 8 bytes + 0x1800
+ // TEXT + 8 bytes
+ // 0x1800
// STSH + 6 bytes
- // STSH + 8 bytes + 0x1800
+ // STSH + 8 bytes
+ // 0x1800
// STSH + 6 bytes
- // STSH + 8 bytes + 0x1800
+ // STSH + 8 bytes
// but towards 0x200 the pattern may
// break down a little bit
// The hyperlinks may come before the fonts,
// or slightly in front
}
+ public void dumpCONTENTSguessed(DirectoryNode dir) throws IOException {
+ byte[] data = getData(dir, "CONTENTS");
+
+ System.out.println("");
+ System.out.println("CONTENTS - " + data.length + " bytes long:");
+
+ String[] startType = new String[20];
+ String[] endType = new String[20];
+ int[] optA = new int[20];
+ int[] optB = new int[20];
+ int[] optC = new int[20];
+ int[] from = new int[20];
+ int[] len = new int[20];
+
+ for(int i=0; i<20; i++) {
+ int offset = 0x20 + i*24;
+ if(data[offset] == 0x18 && data[offset+1] == 0x00) {
+ // Has data
+ startType[i] = new String(data, offset+2, 4);
+ optA[i] = LittleEndian.getUShort(data, offset+6);
+ optB[i] = LittleEndian.getUShort(data, offset+8);
+ optC[i] = LittleEndian.getUShort(data, offset+10);
+ endType[i] = new String(data, offset+12, 4);
+ from[i] = (int)LittleEndian.getUInt(data, offset+16);
+ len[i] = (int)LittleEndian.getUInt(data, offset+20);
+ } else {
+ // Doesn't have data
+ }
+ }
+
+ String text = StringUtil.getFromUnicodeLE(
+ data, from[0], len[0]/2
+ );
+
+ // Dump
+ for(int i=0; i<20; i++) {
+ String num = Integer.toString(i);
+ if(i < 10) {
+ num = "0" + i;
+ }
+ System.out.print(num + " ");
+
+ if(startType[i] == null) {
+ System.out.println("(not present)");
+ } else {
+ System.out.println(
+ "\t" +
+ startType[i] + " " +
+ optA[i] + " " +
+ optB[i] + " " +
+ optC[i]
+ );
+ System.out.println(
+ "\t" +
+ endType[i] + " " +
+ "from: " +
+ Integer.toHexString(from[i]) +
+ " (" + from[i] + ")" +
+ ", len: " +
+ Integer.toHexString(len[i]) +
+ " (" + len[i] + ")"
+ );
+ }
+ }
+ System.out.println("");
+ System.out.println(text);
+ }
protected void dump001CompObj(DirectoryNode dir) {
// TODO
quillDir.getEntry("QuillSub");
dump001CompObj(quillSubDir);
- dumpCONTENTS(quillSubDir);
+ dumpCONTENTSraw(quillSubDir);
+ dumpCONTENTSguessed(quillSubDir);
}
}