To save space, Offset and Length are variable size fields (probably up to 8 bytes), and an element is written in this crunched format:
Offset in nibble to the beginning of the element | Length | Description |
---|---|---|
0 | 1 | F=Size of the Offset field |
1 | 1 | L=Size of the Length field |
2 | 2*L | Length of the run |
2+2*L | 2*F | Offset to the starting LCN of the previous element |
The layout of the runlist must take account of the data compression: the set of VCNs containing the stream of a compressed file attribute is divided in compression units (also called chunks) of 16 clusters: VCNs 0 to 15 constitutes the 1st compression unit, VCNs 16 to 31 the 2nd one, and so on... For each compression unit,
21 14 00 01 11 10 18 11 05 15 01 27 11 20 05First, we have to decrunch it. We obtain the readable format used to initialize the runlist[] table in the following example of C code. Second, we have to execute this program (a short code is sometimes better that long and confusing explanations):
/* printf */ #include <stdio.h> struct s_element { int Offset, Length; }; struct s_element runlist[] = { {0x100, 0x14}, { 0x18, 0x10}, { 0x15, 0x5}, { 0x0, 0x27}, { 0x5, 0x20} }; int main(int argc, char **argv) { int index, V, L, LRef, R, cont; struct s_element begin, end; index = 0; end = runlist[index]; L = LRef = end.Offset; V = 0; do { R = 16 - (V%16); if (R == 16) { printf ("Compression unit beginning at VCN %x\n", V); begin = end; } if (end.Length >= R) { if (begin.Offset) if (end.Offset) printf (" %x clusters at LCN %x\n" " Unit not compressed\n", R, L); else printf (" %x unused clusters: compressed unit\n", R); else printf (" 10 zeroed clusters: sparse unit\n"); L += R; V += R; end.Length -= R; } else { printf (" %x clusters at LCN %x\n", end.Length, L); V += end.Length; end.Length = 0; } if (end.Length) cont = 1; else if (++index < (sizeof(runlist)/sizeof(struct s_element))) { end = runlist[index]; L = LRef += end.Offset; cont = 1; } else cont = 0; } while (cont); exit(0); }The above program finally produces the following output:
Compression unit beginning at VCN 0 10 clusters at LCN 100 Unit not compressed Compression unit beginning at VCN 10 4 clusters at LCN 110 c clusters at LCN 118 Unit not compressed Compression unit beginning at VCN 20 4 clusters at LCN 124 5 clusters at LCN 12d 7 unused clusters: compressed unit Compression unit beginning at VCN 30 10 zeroed clusters: sparse unit Compression unit beginning at VCN 40 10 zeroed clusters: sparse unit Compression unit beginning at VCN 50 10 clusters at LCN 132 Unit not compressed Compression unit beginning at VCN 60 10 clusters at LCN 142 Unit not compressedAs you can see, the runlist format is really brain-damaged:)
Note: If you have a shorter code that can produce the same output, please let me know.