unsigned int pos;
+static int n_dims;
+
#define XSTR(x) #x
#define STR(x) XSTR(x)
#define WHERE __FILE__":" STR(__LINE__)
match_u16_assert(0xffff);
match_u16_assert(0);
match_string2_assert(name);
+ printf("%#x: %s\n", pos, name);
}
static void
static void parse_flexible(void);
+static int count;
static void
parse_DspString(void)
{
- printf("%#x: DspString(", pos);
+ printf("%#x: DspString#%d(", pos, count++);
if (match_byte(2))
{
printf("%f, \"", get_double());
put_safe(get_string1());
printf("\")\n");
}
+
}
static void
}
static void
-match_DspSimpleText(void)
-{ /* 03 80 */
- match_byte_assert(3);
- match_byte_assert(0x80);
+parse_DspSimpleText(void)
+{
match_byte_assert(0);
if (match_byte(0))
{
match_byte_assert(0);
match_zeros_assert(4);
}
+ /* Followed by DspString or DspNumber. */
+}
+
+static void
+match_DspSimpleText(void)
+{ /* 03 80 */
+ match_byte_assert(3);
+ match_byte_assert(0x80);
+ parse_DspSimpleText();
}
static void
}
static void
-match_NavTreeViewItem(void)
+parse_NavTreeViewItem(void)
{ /* 07 80 */
- match_byte_assert(7);
- match_byte_assert(0x80);
+ int start_pos = pos;
match_zeros_assert(1);
- if (!match_byte(0) && !match_byte(7) && !match_byte(2))
+ if (!match_byte(0) && !match_byte(7) && !match_byte(2) && !match_byte(0xc))
match_byte_assert(8);
match_zeros_assert(3);
pos++;
match_zeros_assert(3);
}
//fprintf(stderr, "%#x ", pos - 16);
+ hex_dump(stdout, start_pos, pos - start_pos);
+}
+
+static void
+match_NavTreeViewItem(void)
+{
+ match_byte_assert(7);
+ match_byte_assert(0x80);
+ parse_NavTreeViewItem();
}
static void
parse_DspNumber(void)
{
+ printf("%#x: DspNumber#%d(", pos, count++);
match_byte_assert(1);
- printf("DspNumber(");
parse_format();
match_byte_assert(0x80);
match_byte(2);
static void
match_DspNumber(void)
{
- match_byte_assert(0x2a);
+ if (!match_byte(0x18) && !match_byte(0x19))
+ match_byte_assert(0x2a);
match_byte_assert(0x80);
parse_DspNumber();
}
parse_DspCell(void)
{
match_byte_assert(0);
- match_DspSimpleText();
- parse_flexible(); /* DspString or DspNumber. */
}
static void
}
static void
-parse_PMModelItemInfo(void)
-{ /* 54 80 */
- match_byte_assert(0);
- pos += 1; /* Counter */
- match_zeros_assert(7);
- pos += 3;
- if (!match_byte(0))
- match_byte_assert(0xe);
+parse_category(int j)
+{
+ get_u16(); match_byte_assert(0);
+ get_u16(); match_byte_assert(0);
+ match_u32_assert(j);
+ match_u32_assert(0);
+ if (get_u16() == 0xffff)
+ match_u16_assert(0xffff);
+ else
+ match_u16_assert(0x0e74);
match_byte_assert(0);
+ match_DspSimpleText();
+ match_DspString();
+ match_u32_assert(0);
+}
+
+static void
+parse_dimension(int i)
+{
+ printf ("%#x: dimension %d\n", pos, i);
+ if (i == 0)
+ {
+ match_zeros_assert(5);
+ match_u32_assert(1);
+ get_u16(); match_u16_assert(0x0e74); match_byte_assert(0);
+ match_DspSimpleText();
+ match_DspString();
+
+ int n_categories = get_u32();
+ for (int j = 0; j < n_categories; j++)
+ parse_category(j);
+ }
+ else
+ {
+ match_zeros_assert(6);
+
+ int n_units16 = get_u32();
+ match_u16_assert(1);
+ for (int j = 0; j < n_units16; j++)
+ get_u16();
+
+ match_byte_assert(0);
+
+ int n_units32 = get_u32();
+ match_u16_assert(0);
+ for (int j = 0; j < n_units32; j++)
+ get_u32();
+
+ get_u16(); match_byte_assert(0);
+
+ get_u16(); match_byte_assert(0);
+ get_u16(); match_byte_assert(0);
+ match_u32_assert(0);
+ match_u32_assert(1);
+
+ get_u16(); match_u16_assert(0x0e74); match_byte_assert(0);
+ match_DspSimpleText();
+ match_DspString();
+
+ int n_categories = get_u32();
+ for (int j = 0; j < n_categories; j++)
+ parse_category(j);
+ }
+}
+
+static void
+parse_PMModelItemInfo(void)
+{
+ for (int i = 0; i < n_dims; i++)
+ parse_dimension(i);
+ printf("%#x: end of model\n", pos);
+ exit(0);
}
static void
match_byte_assert(0x54);
match_byte_assert(0x80);
parse_PMModelItemInfo();
- match_DspSimpleText();
- match_DspString();
+ /* DspSimpleText */
+ /* DspString */
}
static void
if (!match_byte(1))
match_byte_assert(0);
match_zeros_assert(3);
- match_DspSimpleText();
- parse_flexible();
+ /* DspSimpleText */
}
static void
parse_PVPivotView(void)
{
match_byte_assert(5);
- match_zeros_assert(4);
+ printf ("PVPivotView(%d)\n", get_u32());
}
static void
parse_NDimensional__DspCell(void)
{
match_byte_assert(0);
- match_u32_assert(1);
+ n_dims = get_u32();
+ printf ("NDimensional__DspCell(n_dims=%d)\n", n_dims);
}
static void
parse_IndexedCollection(void)
{
- match_byte_assert(0);
- if (match_byte(0))
+ printf("IndexedCollection");
+ for (size_t i = 0; ; i++)
{
- match_zeros_assert(12);
- }
- else
- {
- get_u32();
+ match_byte_assert(0);
+ printf("%c%d", i ? 'x' : '(', get_u32());
match_u16_assert(1);
+ if (!match_u16(0x8011))
+ break;
}
+ printf(")\n");
}
static void
match_zeros_assert(2);
}
+static void
+skip_item(const char *name)
+{
+ int start_pos = pos;
+ printf("%#x: skipping %s bytes...", pos, name);
+ while (data[pos + 1] != 0x80
+ && !(data[pos] == 0xff && data[pos + 1] == 0xff
+ && data[pos + 2] == 0 && data[pos + 3] == 0))
+ {
+ assert(pos < n);
+ pos++;
+ }
+ printf("until %#x:", pos);
+ hex_dump(stdout, start_pos, pos - start_pos);
+}
+
static void
parse_flexible(void)
{
{
match_u16_assert(0);
char *heading = get_string2();
- if (!strcmp(heading, "DspCell"))
+ printf("%#x: %s\n", pos, heading);
+ if (!strcmp(heading, "NavRoot"))
+ {
+ match_byte_assert(2);
+ match_zeros_assert(32);
+ }
+ else if (!strcmp(heading, "NavPivot"))
+ {
+ hex_dump(stdout, pos, 021);
+ pos += 0x21;
+ }
+ else if (!strcmp(heading, "DspCell"))
parse_DspCell();
+ else if (!strcmp(heading, "DspSimpleText"))
+ parse_DspSimpleText();
else if (!strcmp(heading, "DspNumber"))
parse_DspNumber();
else if (!strcmp(heading, "DspString"))
parse_DspString();
else if (!strcmp(heading, "NavHead"))
parse_NavHead();
+ else if (!strcmp(heading, "NavTreeViewItem"))
+ {
+ if (0)
+ parse_NavTreeViewItem();
+ else
+ skip_item(heading);
+ }
else if (!strcmp(heading, "IndexedCollection"))
parse_IndexedCollection();
else if (!strcmp(heading, "NavOleItem"))
parse_PVSeparatorStyle();
else if (!strcmp(heading, "PVCellStyle"))
parse_PVCellStyle();
+ else if (!strcmp(heading, "PVTextStyle"))
+ exit(0);
else
{
fprintf(stderr, "don't know %s at offset 0x%x: ", heading, start);
}
else if (data[pos + 1] == 0x80)
{
- if (data[pos] == 0x2a && data[pos + 1] == 0x80)
+ if ((data[pos] == 0x2a || data[pos] == 0x18 || data[pos] == 0x19) && data[pos + 1] == 0x80)
match_DspNumber();
else if (data[pos] == 0x27 && data[pos + 1] == 0x80)
match_DspCell();
{
/* 3c 80 */
/* 39 80 */
+ printf("%#x: %02x %02x ", pos, data[pos], data[pos + 1]);
pos += 2;
parse_format();
+ printf ("\n");
/* match_byte_assert(0x01);
match_byte_assert(0x02);
match_byte_assert(0x0d); */
if (match_byte(2))
{
printf ("15 80(%f", get_double());
- printf (" %s)\n", get_string1());
+ printf (" \"%s\")\n", get_string1());
if (match_byte(1))
{
match_byte_assert(0);
match_byte_assert(0);
if (match_u32(0xc))
match_u16_assert(1);
- else
- match_zeros_assert(13);
}
}
else if (data[pos] == 0x9 && data[pos + 1] == 0x80)
match_NavOleItem();
else if (data[pos] == 0x11 || data[pos] == 0x13)
{
+ int type = data[pos];
pos += 2;
match_byte_assert(0);
- if (match_u32(0xc) || match_u32(0xd))
- match_u16_assert(1);
+ if (data[pos] != 0)
+ {
+ int x = get_u32();
+ int y = get_u16();
+ if (y == 0)
+ {
+ int index = get_u32();
+ printf("%02x 80(footnote %d)\n", type, index);
+ }
+ else
+ printf("%02x 80(%d %d)\n", type, x, y);
+ }
else
match_zeros_assert(13);
}
data[pos] == 0x3e ||
data[pos] == 0x46)
{
+ printf ("%#x: %02x %02x(%02x %02x %02x)\n",
+ pos, data[pos], data[pos + 1],
+ data[pos + 2], data[pos + 3], data[pos + 4]);
pos += 2;
- parse_format();
+ pos += 3;
}
else
{
}
}
#endif
- else //if (match_u16(2) || match_u16(3) || match_u16(4) || match_u16(5) || match_u16(6) || match_u16(7) || match_u16(8) || match_u16(9))
+ else if (match_u16(1))
{
- while (data[pos + 1] != 0x80
- && (data[pos] != 0xff || data[pos + 1] != 0xff))
- {
- assert(pos < n);
- pos++;
- }
+ int start_pos = pos;
+ char *title = get_string1();
+ printf("%#x: title(\"%s\", ", start_pos, title);
+ match_u32_assert(0);
+ char *id = get_string1();
+ printf("\"%s\")\n", id);
+ match_byte_assert(0);
+ match_u32_assert(3);
+ match_u16_assert(1);
}
+ else //if (match_u16(2) || match_u16(3) || match_u16(4) || match_u16(5) || match_u16(6) || match_u16(7) || match_u16(8) || match_u16(9))
+ skip_item("unknown");
#if 0
else if (match_byte(7) || match_byte(4) || match_byte(5) || match_byte(6) || match_byte(8) || match_byte(9) || match_byte(0xb) || match_byte(0xc) || match_byte(0x15) || match_byte(0x16) || match_byte(0x17) || match_byte(0x18) || match_byte(0x1e) || match_byte(0x1a))
{
data[n + i] = i % 2 ? 0xaa : 0x55;
close(fd);
- setvbuf (stdout, NULL, _IOLBF, 0);
+ setvbuf (stdout, NULL, _IONBF, 0);
match_byte_assert(4);
match_u32_assert(0);
match_u32_assert(1);
match_byte_assert(0x63);
+ for (;;)
+ {
+ if (data[pos] == 0)
+ {
+ //printf("zero\n");
+ pos++;
+ }
+ else
+ parse_flexible();
+ }
+ exit(0);
+
parse_heading("NavRoot");
match_byte_assert(2);
match_zeros_assert(32);
for (;;)
{
if (data[pos] == 0)
- pos++;
+ {
+ //printf("zero\n");
+ pos++;
+ }
else
parse_flexible();
}
while (data[pos] != 1)
{
if (data[pos] == 0)
- pos++;
+ {
+ printf("zero\n");
+ pos++;
+ }
else
parse_flexible();
}