significant progess on SPOs
authorBen Pfaff <blp@cs.stanford.edu>
Thu, 2 Jan 2020 16:04:03 +0000 (16:04 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Thu, 2 Jan 2020 16:04:03 +0000 (16:04 +0000)
dump-float.c
dump-spo.c
spo-notes

index 4257ca17cd063bb2f1904b2fefccc5c11c6c86fb..84e4115e1915e7e8663241f54640d382c1efb769 100644 (file)
@@ -9,7 +9,7 @@ main (void)
       uint8_t b[8];
       double d;
     }
-  x = { .b = { 0xfa, 0x3c, 0x00, 0x00, 0x3b, 0x5a, 0x01, 0x00 } };
+  x = { .b = { 0x18, 0x00, 0x00, 0x1c, 0xf0, 0xff, 0xff, 0x5f } };
   printf ("%f\n", x.d);
   return 0;
 }
index ac53ece628894626236a24d2c2d9a91537d33b12..35cd8b5dcc072e837b32ce051198419e99870bd5 100644 (file)
@@ -179,6 +179,15 @@ match_bytes(int start, const int *bytes, size_t n_bytes)
   return true;
 }
 
+static char *
+xmemdup0(const void *p, size_t n)
+{
+  char *s = malloc(n + 1);
+  memcpy(s, p, n);
+  s[n] = 0;
+  return s;
+}
+
 static bool
 get_bool(void)
 {
@@ -516,7 +525,7 @@ format_to_string (int type)
     case 38: return "EDATE";
     case 39: return "SDATE";
     default:
-      abort();
+      assert(false);
       sprintf(tmp, "<%d>", type);
       return tmp;
     }
@@ -1312,13 +1321,30 @@ format_name (int format, char *buf)
 int
 main(int argc, char *argv[])
 {
-  if (argc != 2)
+  bool print_offsets = false;
+  for (;;)
+    {
+      int c = getopt (argc, argv, "o");
+      if (c == -1)
+        break;
+
+      switch (c)
+        {
+        case 'o':
+          print_offsets = true;
+          break;
+
+        case '?':
+          exit (-1);
+        }
+    }
+  if (argc - optind != 1)
     {
       fprintf (stderr, "usage: %s FILE.bin", argv[0]);
       exit (1);
     }
 
-  filename = argv[1];
+  const char *filename = argv[optind];
   int fd = open(filename, O_RDONLY);
   if (fd < 0)
     {
@@ -1346,6 +1372,10 @@ main(int argc, char *argv[])
     }
   close(fd);
 
+  setvbuf (stdout, NULL, _IOLBF, 0);
+
+  int sum = 0;
+  
 #if 0
   unsigned int prev_end = 0;
   for (pos = 0; pos + 50 < n; pos++)
@@ -1375,7 +1405,8 @@ main(int argc, char *argv[])
           !all_utf8((char *) &data[pos + 3], 1) &&
           data[pos - 1] != 'v')
         {
-          //printf ("%04x: ", pos);
+          if (print_offsets)
+            printf ("%04x: ", pos);
           unsigned int p = pos;
           while (all_utf8 ((char *) &data[p], 1))
             p--;
@@ -1384,11 +1415,14 @@ main(int argc, char *argv[])
     }
 #endif
   unsigned int prev_end = 0;
+  char *title = "";
   for (pos = 2; pos + 50 < n; pos++)
     {
       static const int cell_prefix[] = {
         0x00, 0x03,
-        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1,
+        0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -1 /* 00 or 10 */, 0x00, 0x00, 0x00, 0x00, -1,
+
+        /*14    15  16  17  18  19 */
         0x80, 0x01, -1, -1, -1, -1,
       };
       size_t cell_prefix_len = sizeof cell_prefix / sizeof *cell_prefix;
@@ -1396,8 +1430,19 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x ", prev_end);
+              if (print_offsets)
+                printf ("%04x ", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
+
+              if (!strcmp (title, "DspNumber")
+                  && pos - prev_end == 2
+                  && data[prev_end + 1] == 0x80)
+                {
+                  static int already = false;
+                  if (!already)
+                    fprintf (stderr, " sum=%d %02x\n", sum, data[prev_end]);
+                  already = true;
+                }
             }
 
           char buf[64];
@@ -1435,13 +1480,13 @@ main(int argc, char *argv[])
                   len = 22 + count;
                 }
               else
-                abort ();
+                assert (false);
             }
-          else if (data[pos + 19] == 128)
+          else if (data[pos + 19] == 128 && data[pos + 20] == 2)
             {
-              /* pos + 13 is usually 22...53 but also 5 or 69 */
-              /* pos + 20 is 2 most of the time, occasionally 1 */
-              printf ("%d %d ", data[pos + 13], data[pos + 20]);
+              /* pos + 13 is usually 22...53, and it's 3 more than the
+                 " xx 80" separator between cells  */
+              printf ("xxx%x ", data[pos + 13]);
               double d = *(double *) &data[pos + 21];
               len = 29;
               const union
@@ -1451,17 +1496,48 @@ main(int argc, char *argv[])
                 }
               sysmis = {.b = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff}};
               if (d == sysmis.d)
-                printf ("sysmis\n");
+                printf ("sysmis");
+              else
+                printf ("%f", d);
+
+              if (data[pos + 29] < 0xff
+                  && all_utf8((char *) &data[pos + 30], data[pos + 29]))
+                {
+                  printf (" \"%.*s\"", (int) data[pos + 29],
+                          &data[pos + 30]);
+                  len += data[pos + 29] + 1;
+                }
               else
-                printf ("%f\n", d);
+                assert (false);
+
+              putchar ('\n');
+            }
+          else if (data[pos + 19] == 128 && data[pos + 20] == 1 &&
+                   data[pos + 21] == 0)
+            {
+              if (data[pos + 23] < 0xff
+                  && all_utf8((char *) &data[pos + 24], data[pos + 23]))
+                {
+                  printf (" \"%.*s\"\n", (int) data[pos + 23],
+                          &data[pos + 24]);
+                  len = 24 + data[pos + 23];
+                }
+              else
+                assert (false);
             }
           else
-            abort ();
+            {
+              printf ("xxx%d %d %d %d\n",
+                      data[pos + 19], data[pos + 20],
+                      data[pos + 21], data[pos + 22]);
+              assert(false);
+            }
           pos += len - 1;
           prev_end = pos + 1;
           continue;
         }
 
+#if 0
       static const int col_prefix[] = {
         0x11, 0x80, 0x00, -1, 0x00, 0x00, 0x00, 0x01, 0x00
       };
@@ -1470,7 +1546,8 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x ", prev_end);
+              if (print_offsets)
+                printf ("%04x ", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
 
@@ -1479,35 +1556,37 @@ main(int argc, char *argv[])
           prev_end = pos + 1;
           continue;
         }
-
+#endif
+      
       static const int record_prefix[] = {
         0xff, 0xff, 0x00, 0x00,
       };
       size_t record_prefix_len = sizeof record_prefix / sizeof *record_prefix;
       if (match_bytes(pos, record_prefix, record_prefix_len))
         {
-          if (prev_end != pos)
-            {
-              //printf ("%04x ", prev_end);
-              hex_dump (stdout, prev_end, pos - prev_end);
-            }
-
-          putchar ('\n');
-
-          //printf ("%d ", pos % 4);
           int len = record_prefix_len;
           int slen = data[pos + 4] + (data[pos + 5] << 8);
-          if (slen > 2 && slen < 256 && all_utf8((char *) &data[pos + 6], slen))
+          if (slen >= 2 && slen < 256 && all_utf8((char *) &data[pos + 6], slen))
             {
-              printf ("%.*s ", slen, &data[pos + 6]);
+              if (prev_end != pos)
+                {
+                  if (print_offsets)
+                    printf ("%04x ", prev_end);
+                  hex_dump (stdout, prev_end, pos - prev_end);
+                }
+
+              putchar ('\n');
+
+              printf ("rec:%-20.*s ", slen, &data[pos + 6]);
               len = slen + 6;
-            }
-          else
-            printf ("notitle ");
+              title = xmemdup0(&data[pos + 6], slen);
+              fprintf (stderr, "%s%d ", title, data[pos + len]);
+              sum += data[pos+len];
 
-          pos += len - 1;
-          prev_end = pos + 1;
-          continue;
+              pos += len - 1;
+              prev_end = pos + 1;
+              continue;
+            }
         }
 
       static const int number_prefix[] = {
@@ -1518,18 +1597,41 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x ", prev_end);
+              if (print_offsets)
+                printf ("%04x ", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
           prev_end = pos;
 
           double d = *(double *) &data[pos + number_prefix_len];
-          printf ("float%f ", d);
-          pos += 10 - 9;
+          printf ("float %f\n", d);
+
+          pos += 10 - 1;
           prev_end = pos + 1;
           continue;
         }
 
+      if (!memcmp (&data[pos + 4], "{\\rtf", 5))
+        {
+          int len = data[pos] + (data[pos + 1] << 8) + (data[pos + 2] << 16)
+            + (data[pos + 3] << 24);
+          if (len < n - pos - 4)
+            {
+              if (prev_end != pos)
+                {
+                  if (print_offsets)
+                    printf ("%04x ", prev_end);
+                  hex_dump (stdout, prev_end, pos - prev_end);
+                }
+              prev_end = pos;
+
+              printf ("rtf\n");
+              pos += 4 + len - 1;
+              prev_end = pos + 1;
+              continue;
+            }
+        }
+
       static const int string_prefix[] = {
         0x80, 0x01, 0x02, 0x28, 0x05, 0x00, 0x01
       };
@@ -1538,24 +1640,33 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x ", prev_end);
+              if (print_offsets)
+                printf ("%04x ", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
           prev_end = pos;
 
-          printf ("\nstring %.*s\n", (int) data[pos + 7], &data[pos + 8]);
+          int len = data[pos + 7];
+          printf ("string %.*s\n", len, &data[pos + 8]);
+          pos += 8 + len - 1;
+          prev_end = pos + 1;
+          continue;
         }
       if (match_bytes(pos, string_prefix, string_prefix_len) && data[pos + string_prefix_len] == 255)
         {
           if (prev_end != pos)
             {
-              //printf ("%04x ", prev_end);
+              if (print_offsets)
+                printf ("%04x ", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
           prev_end = pos;
 
           int len = data[pos + 8] + (data[pos + 9] << 8);
           printf ("\nlongstring %.*s\n", len, &data[pos + 10]);
+          pos += 10 + len - 1;
+          prev_end = pos + 1;
+          continue;
         }
 
       
@@ -1572,7 +1683,8 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x ", prev_end);
+              if (print_offsets)
+                printf ("%04x ", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
 
@@ -1582,6 +1694,7 @@ main(int argc, char *argv[])
           continue;
         }
 
+#if 0
       static const int font_prefix[] = {
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x80, 0x00, 0x01, 0x00,
         0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, -1,
@@ -1596,7 +1709,8 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x", prev_end);
+              if (print_offsets)
+            printf ("%04x", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
 
@@ -1609,7 +1723,8 @@ main(int argc, char *argv[])
           prev_end = pos + 1;
           continue;
         }
-
+#endif
+      
       static const int table_prefix[] = {
         -1 /* ed or e9 */, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x02, 0x00, 0x00,
@@ -1624,7 +1739,8 @@ main(int argc, char *argv[])
         {
           if (prev_end != pos)
             {
-              //printf ("%04x", prev_end);
+              if (print_offsets)
+                printf ("%04x", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
 
@@ -1633,49 +1749,28 @@ main(int argc, char *argv[])
           prev_end = pos + 1;
           continue;
         }
-#endif
 
       static const int dim_prefix[] = {
         0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, -1,
-        0x00, 0x00, 0x00, 0x00, -1, 0x80, 0x01, 0x02, -1,
-        -1, -1, -1 /* 00 or 01 */,
+        0x00, 0x00, 0x00, 0x00, 0x05, 0x80, 0x01, 0x02, 0x28,
+        0x05, 0x00,
       };
       size_t dim_prefix_len = sizeof dim_prefix / sizeof *dim_prefix;
       if (match_bytes(pos, dim_prefix, dim_prefix_len))
         {
           if (prev_end != pos)
             {
-              //printf ("%04x", prev_end);
+              if (print_offsets)
+                printf ("%04x", prev_end);
               hex_dump (stdout, prev_end, pos - prev_end);
             }
 
-          printf ("dim %d %d %d %d %d\n", data[pos + 8], data[pos + 13],
-                  data[pos + 17], data[pos + 18], data[pos + 19]);
+          printf ("dim %d\n", data[pos + 8]);
           pos += dim_prefix_len - 1;
           prev_end = pos + 1;
           continue;
         }
-
-      static const int dim2_prefix[] = {
-        0x50, 0x80, 0x00, 0x52, 0x80, 0x00, -1, 0x00, 0x00, 0x00, -1, 0, 0, 0,
-        -1, -1, -1, -1
-      };
-      size_t dim2_prefix_len = sizeof dim2_prefix / sizeof *dim2_prefix;
-      if (match_bytes(pos, dim2_prefix, dim2_prefix_len))
-        {
-          if (prev_end != pos)
-            {
-              //printf ("%04x", prev_end);
-              hex_dump (stdout, prev_end, pos - prev_end);
-            }
-
-          int16_t x = *(int16_t *) &data[pos + 14];
-          int16_t y = *(int16_t *) &data[pos + 16];
-          printf ("dim2 %d %d %d %d\n", data[pos + 6], data[pos + 10], x, y);
-          pos += dim2_prefix_len - 1;
-          prev_end = pos + 1;
-          continue;
-        }
+#endif
 
       if (!is_ascii(data[pos]))
         continue;
@@ -1711,10 +1806,12 @@ main(int argc, char *argv[])
       unsigned real_start = start - length_bytes;
       if (prev_end != real_start)
         {
-          //printf ("%04x ", prev_end);
+          if (print_offsets)
+            printf ("%04x ", prev_end);
           hex_dump (stdout, prev_end, real_start - prev_end);
         }
-      //printf ("%04x ", real_start);
+      if (print_offsets)
+        printf ("%04x ", real_start);
       printf ("\"%.*s\"\n", 
               (int) end - start, (char *) &data[start]);
       prev_end = end;
index b8099132f93d82235f1335a79a0a921974691310..25d124a71a7e8ccd9f5c4eb697afed689b918efd 100644 (file)
--- a/spo-notes
+++ b/spo-notes
@@ -25,6 +25,27 @@ and the DspString case:
        01 02 28 (00|05) 00 (00|01)
        often followed by a string
 
+DspString is the label of the object that is currently selected.
+
+The currently selected object is always the first in the file
+regardless of the output hierarchy and order
+
+The entire rec:NavPivot contents, minus the final 00 byte, appear
+later in the file to identify the selected object.  However, the
+initial 02 02*8 can disappear into a "float 0.0" if there's a leading
+80.
+
+Each object has a small negative number, e.g. 0xfffffe91 == -390.
+
+Objects:
+  NavRoot: root output object
+  NavLog: log object
+  NavHead: heading with subobjects
+    NavTreeViewItem: assocated with NavHead somehow
+  NavTitle: title within a heading
+  NavNote: notes table
+  NavPivot: table
+
 The start of the file might be a version number
 
 x and y are either 0 or 2-3 byte values, e.g. 0x670b or 0x3b989.
@@ -159,5 +180,154 @@ ffff 0000 "DspNumber"
 
 NavTitle  02 00 00 00 00 00 00 00 00 18 00 00 00 03 .. .. .. 00 04 00 00 .. .. ff ff 02 00 00 00 01 00 00
 
-80 01 02 28 05 00 01 ff
-80 01 02 28 05 00 01
+80 02 <double>
+80 01 02 28 05 00 01 <len1> <string>
+80 01 02 28 05 00 01 ff <len2> <string>
+80 01 03 28 05 80 02 <double> 
+
+80 00 03
+80 00 00 00 00 00 00 00 00 00 00 ..
+80 01 .. .. .. ..
+
+DspNumber:
+       01 <decimals> <width> <type>
+
+NDimensional__DspCell:
+       00 int32[ndims]
+
+IndexedCollection: 7+(9*ndims) bytes
+       00 0e 00 00 00 01 00
+
+       00 22 00 00 00 01 00
+  11 80 00 08 00 00 00 01 00
+
+       00 5c 00 00 00 01 00
+  13 80 00 5c 00 00 00 01 00
+  13 80 00 05 00 00 00 01 00
+
+       00 01 00 00 00 01 00
+  11 80 00 02 00 00 00 01 00
+  11 80 00 03 00 00 00 01 00
+  11 80 00 03 00 00 00 01 00
+
+           ^^ number of categories
+
+----------------------------------------------------------------------
+ab1.dump
+
+3 dimensions, 92x92x5:
+    NDimensional__DspCell  00 03 00 00 00
+
+    IndexedCollection  00 5c 00 00 00 01 00 13 80 00 5c 00 00 00 01 00 13 80 00 05 00 00 00 01 00
+
+The cells are in order last dimension changes most quickly.
+
+----------------------------------------------------------------------
+
+ZMAW_zaj3.dump
+
+4-dimensions, 1x2x3x3, 18 cells
+
+16 80 -> next 4th dim
+11 80 00 03 00 00 00 01 00 -> increment another dim
+
+----------------------------------------------------------------------
+
+rec:PMModelItemInfo
+ .. .. .. .. .. .. .. .. .. .. .. .. ..                            cell F40.2 "Contents"
+ 07 .. .. .. 55 80 .. 57 80 .. .. .. .. .. .. .. .. .. 07 .. 74 0e cell F40.2   "Output Created"
+ .. .. .. .. 55 80 .. 57 80 .. 01 .. .. .. .. .. .. .. 08 .. 74 0e cell F40.2   "Comments"
+ .. .. .. .. 55 80 .. 57 80 .. .. .. .. .. .. .. .. .. .. .. .. .. cell F40.2   "Input"
+ 06 .. .. .. 55 80 .. 57 80 .. 02 .. .. .. .. .. .. .. 0a .. 74 0e cell F40.2     "Data"
+ .. .. .. .. 55 80 .. 57 80 .. 03 .. .. .. .. .. .. .. .. .. .. .. cell F40.2     "Active Dataset"
+ .. .. .. .. 55 80 .. 57 80 .. 04 .. .. .. .. .. .. .. 0e .. 74 0e cell F40.2     "Filter"
+ .. .. .. .. 55 80 .. 57 80 .. 05 .. .. .. .. .. .. .. 11 .. 74 0e cell F40.2     "Weight"
+ .. .. .. .. 55 80 .. 57 80 .. 06 .. .. .. .. .. .. .. 12 .. 74 0e cell F40.2     "Split File"
+ .. .. .. .. 55 80 .. 57 80 .. 07 .. .. .. .. .. .. .. 13 .. 74 0e cell F40.2     "N of Rows in Working Data File"
+ .. .. .. .. 55 80 .. 57 80 .. .. .. .. .. .. .. .. .. .. .. .. .. cell F40.2   "Missing Value Handling"
+ 02 .. .. .. 55 80 .. 57 80 .. 08 .. .. .. .. .. .. .. .. .. .. .. cell F40.2     "Definition of Missing"
+ .. .. .. .. 55 80 .. 57 80 .. 09 .. .. .. .. .. .. .. .. .. .. .. cell F40.2     "Cases Used"
+ .. .. .. .. 55 80 .. 57 80 .. 0a .. .. .. .. .. .. .. 17 .. 74 0e cell F40.2   "Weight Handling"
+ .. .. .. .. 55 80 .. 57 80 .. 0b .. .. .. .. .. .. .. 18 .. 74 0e cell F40.2   "Syntax"
+ .. .. .. .. 55 80 .. 57 80 .. .. .. .. .. .. .. .. .. .. .. .. .. cell F40.2   "Resources"
+ 03 .. .. .. 55 80 .. 57 80 .. 0c .. .. .. .. .. .. .. 1b .. 74 0e cell F40.2     "Elapsed Time"
+ .. .. .. .. 55 80 .. 57 80 .. 0d .. .. .. .. .. .. .. .. .. .. .. cell F40.2     "Maximum Memory Required"
+ .. .. .. .. 55 80 .. 57 80 .. 0e .. .. .. .. .. .. .. .. .. .. .. cell F40.2     "Processor Time"
+
+rec:PMModelItemInfo
+                            .. .. .. .. .. 01 .. .. .. ff ff ff ff cell F40.2       "score"
+ 01 .. .. .. 86 80 .. 88 80 .. .. .. .. .. .. .. .. .. f4 0e 74 0e cell F40.2         "Valid"
+ 09 .. .. .. 86 80 .. 88 80 .. .. .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "17..."
+ .. .. .. .. 86 80 .. 88 80 .. 01 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "22..."
+ .. .. .. .. 86 80 .. 88 80 .. 02 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "26..."
+ .. .. .. .. 86 80 .. 88 80 .. 03 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "29..."
+ .. .. .. .. 86 80 .. 88 80 .. 04 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "33..."
+ .. .. .. .. 86 80 .. 88 80 .. 05 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "37..."
+ .. .. .. .. 86 80 .. 88 80 .. 06 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "40..."
+ .. .. .. .. 86 80 .. 88 80 .. 07 .. .. .. .. .. .. .. ff ff ff ff cell F40.2 xxx19     "48..."
+ .. .. .. .. 86 80 .. 88 80 .. 08 .. .. .. .. .. .. .. f2 0e 74 0e cell F40.2         "Total"
+ .. .. .. .. .. .. .. .. .. .. 09 .. .. .. 01 .. 90 .. 94 .. 98 .. 9c .. a0 .. a4 .. a8 .. ac .. b0 .. .. 09 .. .. .. .. .. .. .. .. .. 01 .. .. .. 02 .. .. .. 03 .. .. .. 04 .. .. .. 05 .. .. .. 06 .. .. .. 07 .. .. .. 08 .. ..
+ .. 84 80 .. 86 80 .. 88 80 .. .. .. .. .. 01 .. .. .. eb 0e 74 0e cell F40.2       "Statistics"
+ 04 .. .. .. 86 80 .. 88 80 .. .. .. .. .. .. .. .. .. dc 0e 74 0e cell F40.2         "Frequency"
+ .. .. .. .. 86 80 .. 88 80 .. 01 .. .. .. .. .. .. .. e6 0e 74 0e cell F40.2         "Percent"
+ .. .. .. .. 86 80 .. 88 80 .. 02 .. .. .. .. .. .. .. f5 0e 74 0e cell F40.2         "Valid Percent"
+ .. .. .. .. 86 80 .. 88 80 .. 03 .. .. .. .. .. .. .. da 0e 74 0e cell F40.2         "Cumulative Percent"
+ .. .. .. .. .. .. .. .. .. .. 04 .. .. .. 01 .. b9 .. bd .. c1 .. c5 .. .. 04 .. .. .. .. .. .. .. .. .. 01 .. .. .. 02 .. .. .. 03 .. .. .. .. .. .. .. .. 01 .. .. 11 .. .. .. .. .. .. .. .. .. 4b .. .. .. .. .. .. .. .. .. .. ..
+
+rec:PMModelItemInfo
+                            .. .. .. .. .. 01 .. .. .. 91 1a 74 0e cell F40.2 "Statistics"
+ 05 .. .. .. ff 7f 69 78 02 80 .. ff 7f 6b 78 02 80 .. .. .. .. .. .. .. .. .. 98 1a 74 0e cell F40.2   "Pearson Correlation"
+ .. .. .. .. ff 7f 69 78 02 80 .. ff 7f 6b 78 02 80 .. 01 .. .. .. .. .. .. .. 99 1a 74 0e cell F40.2   "Sig. (2-tailed)"
+ .. .. .. .. ff 7f 69 78 02 80 .. ff 7f 6b 78 02 80 .. 02 .. .. .. .. .. .. .. 96 1a 74 0e cell F40.2   "Sum of Squares and Cross-products"
+ .. .. .. .. ff 7f 69 78 02 80 .. ff 7f 6b 78 02 80 .. 03 .. .. .. .. .. .. .. 97 1a 74 0e cell F40.2   "Covariance"
+ .. .. .. .. ff 7f 69 78 02 80 .. ff 7f 6b 78 02 80 .. 04 .. .. .. .. .. .. .. 94 1a 74 0e cell F40.2   "N"
+ .. .. .. .. .. .. .. .. .. .. 05 .. .. .. 01 .. ff 7f 6f 78 02 .. ff 7f 73 78 02 .. ff 7f 77 78 02 .. ff 7f 7b 78 02 .. ff 7f 7f 78 02 .. .. 05 .. .. .. .. .. .. .. .. .. 01 .. .. .. 02 .. .. .. 03 .. .. .. 04 .. .. .. ff 7f 67 78 02 80 .. ff 7f 69 78 02 80 .. ff 7f 6b 78 02 80 .. .. .. .. .. 01 .. .. .. 90 1a 74 0e ..................ox....sx....wx....{x.....x...............................gx.....ix.....kx.............t.
+
+
+ff is a way to say that there's a 4-byte number instead of 1-byte?
+
+
+01 01 ed ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 bc 02 00 00 00 00 00 00 00 00 00 22 41 72 69 61 6c 00 61 00 6c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00
+07 80 00 02 00 00 00 0a 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00
+01 01 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 01 00 00 00 00 00 00 00 00 00 22 43 6f 75 72 69 65 72 20 4e 65 77 00 72 00 20 00 4e 00 65 00 77 00 00 00 00 00 00 00 00 00 00 00 50 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00
+07 80 00 00 00 00 00 0f 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00
+00
+
+
+ .. .. .. .. .. .. a9 80 .. 01 .. .. .. .. .. ff ff ff .. .. .. ab 80 .. 01 .. .. .. c8 .. 78 .. 78 .. 14 .. 14 .. .. .. 01 .. f3 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22
+ .. .. .. .. .. .. a9 80 .. 01 .. .. .. .. .. ff ff ff .. .. .. ab 80 .. 01 .. .. .. c8 .. 78 .. a0 .. 14 .. 14 .. .. .. 01 .. ef ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22
+ .. .. .. .. .. .. a9 80 .. 01 .. .. .. .. .. ff ff ff .. .. .. ab 80 .. 01 .. .. .. c8 .. 78 .. a0 .. 14 .. 14 .. .. .. 01 .. f2 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. bc 02 .. .. 01 .. .. .. .. .. .. 12
+ .. .. .. .. .. .. a9 80 .. 01 .. .. .. .. .. ff ff ff .. .. .. ab 80 .. 01 .. .. .. c8 .. 78 .. a0 .. 14 .. 14 .. .. .. 01 .. f2 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22
+ 80 .. 80 .. .. .. a9 80 .. 01 .. .. .. .. .. ff ff ff .. .. .. ab 80 .. 01 .. .. .. c8 .. 78 .. a0 .. 14 .. 14 .. .. .. 01 .. f3 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22
+
+
+
+record type 02
+==============
+
+02 int16*4 int32*4
+
+
+
+rec:NavLog
+
+02 .. .. .. .. .. .. .. ..
+18 .. .. .. .. .. .. .. b3 02 .. .. 30 f8 ff ff 01 .. .. .. 01 .. .. cell F40.2 "LogA" 07 80 .. 02 .. .. .. 0f .. 01 .. .. .. .. .. .. .. .. .. 01 .. .. .. .. .. .. 01 01 f5 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22 41 72 69 61 6c .. .. .. .. .. .. .. .. .. .. .. .. .. .. rtf .. 0e float 0.......
+18 .. .. .. 0e f8 ff ff b3 02 .. .. 3e f0 ff ff 01 .. .. .. 01 .. .. cell F40.2 "LogB" 07 80 .. 02 .. .. .. 13 .. 01 .. .. .. .. .. .. .. .. .. 01 .. .. .. .. .. .. 01 01 f5 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22 41 72 69 61 6c .. .. .. .. .. .. .. .. .. .. .. .. .. .. rtf .. 0e float 0.......
+18 .. .. .. 1c f0 ff ff 5f 02 .. .. 4c e8 ff ff 01 .. .. .. 01 .. .. cell F40.2 "LogC" 07 80 .. 02 .. .. .. 17 .. 01 .. .. .. .. .. .. .. .. .. 01 .. .. .. .. .. .. 01 01 f5 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22 41 72 69 61 6c .. .. .. .. .. .. .. .. .. .. .. .. .. .. rtf .. 0e float 0.......
+18 .. .. .. 2a e8 ff ff 5f 02 .. .. 5a e0 ff ff 01 .. .. .. 01 .. .. cell F40.2 "LogD" 07 80 .. 02 .. .. .. 1b .. 01 .. .. .. .. .. .. .. .. .. 01 .. .. .. .. .. .. 01 01 f5 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22 41 72 69 61 6c .. .. .. .. .. .. .. .. .. .. .. .. .. .. rtf .. 0e float 0.......
+18 .. .. .. 38 e0 ff ff 5f 02 .. .. 68 d8 ff ff 01 .. .. .. 01 .. .. cell F40.2 "LogE" 07 80 .. 02 .. .. .. 1f .. 01 .. .. .. .. .. .. .. .. .. 01 .. .. .. .. .. .. 01 01 f5 ff ff ff .. .. .. .. .. .. .. .. .. .. .. .. 90 01 .. .. .. .. .. .. .. .. .. 22 41 72 69 61 6c .. .. .. .. .. .. .. .. .. .. .. .. .. .. rtf .. 02 .. 02 .. .. ..
+
+
+NavTreeViewItem:
+
+last bit is the number of children plus one, e.g. here it has 0x12+1
+children:
+
+rec:NavTreeViewItem       .. .. .. .. .. 02 .. 01 .. .. .. .. .. .. .. .. .. 01 .. .. .. .. .. .. .. .. .. 18 .. .. .. .. .. .. .. de ff ff ff 18 .. .. .. .. .. .. .. 28 .. .. .. 28 .. .. .. cb 02 .. .. f0 86 .. .. .. .. .. .. .. f8 2a .. .. 34 21 .. .. 01 .. 0f .. 02 .. f6 04 .. .. f6 04 .. .. f6 04 .. .. f6 04 .. .. .. .. f0 .. .. .. 7c 02 01 .. ...............................................(...(.................*..4!..............................|...
+"(Continued)"
+ 01 01 .. .. ..
+rtf
+ 01 01 .. .. ..
+rtf
+ .. 13 ..