+ int type = get_be32();
+ int stroke = get_be32();
+ int color = get_be32();
+ printf(" <border type=\"%d\" stroke=\"%s\" color=\"#%06x\"/>\n",
+ type,
+ (stroke == 0 ? "none"
+ : stroke == 1 ? "solid"
+ : stroke == 2 ? "dashed"
+ : stroke == 3 ? "thick"
+ : stroke == 4 ? "thin"
+ : stroke == 5 ? "double"
+ : "<error>"),
+ color);
+ }
+ bool grid = get_byte();
+ pos += 3;
+ printf(" <grid show=\"%s\"/>\n", grid ? "yes" : "no");
+ printf("</borders>\n");
+ assert(pos == x1_end);
+
+ int skip = get_u32();
+ assert(skip == 18 || skip == 25);
+ pos += skip;
+
+ int x3 = get_u32();
+ int x3_end = pos + x3;
+ if (version == 3)
+ {
+ match_be32_assert(1);
+ get_be32();
+ printf("<settings layer=\"%d\"", get_be32());
+ if (!get_bool())
+ printf(" skipempty=\"false\"");
+ if (!get_bool())
+ printf(" showdimensionincorner=\"false\"");
+ if (!get_bool())
+ printf(" markers=\"numeric\"");
+ if (!get_bool())
+ printf(" footnoteposition=\"subscript\"");
+ get_byte();
+ int nbytes = get_be32();
+ int end = pos + nbytes;
+ printf("\n");
+ while (pos + 4 <= end)
+ printf(" %d", get_be32());
+ pos = end;
+ printf("\n");
+ pos += nbytes;
+ char *notes = get_string_be();
+ if (notes[0])
+ printf(" notes=\"%s\"", notes);
+ char *look = get_string_be();
+ if (look[0])
+ printf(" look=\"%s\"", look);
+ printf(">\n");
+ }
+ pos = x3_end;
+
+ /* Manual column widths, if present. */
+ int count = get_u32();
+ if (count > 0)
+ {
+ printf("<columnwidths>");
+ for (int i = 0; i < count; i++)
+ {
+ if (i)
+ putchar(' ');
+ printf("%d", get_u32());
+ }
+ printf("</columnwidths>\n");
+ }
+
+ const char *locale = get_string();
+ printf ("<locale>%s</locale>\n", locale);
+
+ printf ("<layer>%d</layer>\n", get_u32());
+ if (!match_byte(0))
+ match_byte_assert(1);
+ if (!match_byte(0))
+ match_byte_assert(1);
+ if (!match_byte(0))
+ match_byte_assert(1);
+ printf("<epoch>%d</epoch>\n", get_u32());
+
+ int decimal = data[pos];
+ int grouping = data[pos + 1];
+ if (match_byte('.'))
+ {
+ if (!match_byte(',') && !match_byte('\''))
+ match_byte_assert(' ');
+ }
+ else
+ {
+ match_byte_assert(',');
+ if (!match_byte('.') && !match_byte(' ') && !match_byte(','))
+ match_byte_assert(0);
+ }
+ printf("<format decimal=\"%c\"", decimal);
+ if (grouping)
+ printf(" grouping=\"%c\"", grouping);
+ printf("\"/>\n");
+ if (match_u32(5))
+ {
+ for (int i = 0; i < 5; i++)
+ printf("<CC%c>%s</CC%c>\n", 'A' + i, get_string(), 'A' + i);
+ }
+ else
+ match_u32_assert(0);
+
+ /* The last chunk is an outer envelope that contains two inner envelopes.
+ The second inner envelope has some interesting data like the encoding and
+ the locale. */
+ int outer_end = get_end();
+ if (version == 3)
+ {
+ /* First inner envelope: byte*33 int[n] int*[n]. */
+ int inner_len = get_u32();
+ int inner_end = pos + inner_len;
+ int array_start = pos + 33;
+ match_byte_assert(0);
+ pos++; /* 0, 1, 10 seen. */
+ get_bool();
+
+ /* 0=en 1=de 2=es 3=it 5=ko 6=pl 8=zh-tw 10=pt_BR 11=fr */
+ printf("lang=%d ", get_byte());
+
+ printf ("variable_mode=%d\n", get_byte());
+ printf ("value_mode=%d\n", get_byte());
+ if (!match_u64(0))
+ match_u64_assert(UINT64_MAX);
+ match_u32_assert(0);
+ match_u32_assert(0);
+ match_u32_assert(0);
+ match_u32_assert(0);
+ match_byte_assert(0);
+ get_bool();
+ match_byte_assert(1);
+ pos = array_start;
+
+ assert(get_end() == inner_end);
+ printf("<heights>");
+ int n_heights = get_u32();
+ for (int i = 0; i < n_heights; i++)