1//  Datafile dump utility sample code
2
3#include "mk4.h"
4#include "mk4str.h"
5
6#include <stdio.h>
7
8#if defined (unix)
9#define try
10#define catch(x)  if (0)
11#endif
12
13#if defined (macintosh)
14#include /**/ <console.h>
15#define d4_InitMain(c,v)  c = ccommand(&v)
16#endif
17
18/////////////////////////////////////////////////////////////////////////////
19// Recursively display the entire view contents. The results shown do not
20// depend on file layout (free space, file positions, flat vs. on-demand).
21
22static void ViewDisplay(const c4_View& v_, int l_ =0)
23{
24  c4_String types;
25  bool hasData = false, hasSubs = false;
26
27    // display header info and collect all data types
28  printf("%*s VIEW %5d rows =", l_, "", v_.GetSize());
29  for (int n = 0; n < v_.NumProperties(); ++n)
30  {
31    c4_Property prop = v_.NthProperty(n);
32    char t = prop.Type();
33
34    printf(" %s:%c", (const char*) prop.Name(), t);
35
36    types += t;
37
38    if (t == 'V')
39      hasSubs = true;
40    else
41      hasData = true;
42  }
43  printf("\n");
44
45  for (int j = 0; j < v_.GetSize(); ++j)
46  {
47    if (hasData)  // data properties are all shown on the same line
48    {
49      printf("%*s %4d:", l_, "", j);
50      c4_RowRef r = v_[j];
51      c4_Bytes data;
52
53      for (int k = 0; k < types.GetLength(); ++k)
54      {
55        c4_Property p = v_.NthProperty(k);
56
57        switch (types[k])
58        {
59        case 'I':
60          printf(" %ld", (long) ((c4_IntProp&) p) (r));
61          break;
62
63#if !q4_TINY
64        case 'F':
65          printf(" %g", (double) ((c4_FloatProp&) p) (r));
66          break;
67
68        case 'D':
69          printf(" %.12g", (double) ((c4_DoubleProp&) p) (r));
70          break;
71#endif
72
73        case 'S':
74          printf(" '%s'", (const char*) ((c4_StringProp&) p) (r));
75          break;
76
77        case 'M': // backward compatibility
78        case 'B':
79          (p (r)).GetData(data);
80          printf(" (%db)", data.Size());
81          break;
82
83        default:
84          if (types[k] != 'V')
85            printf(" (%c?)", types[k]);
86        }
87      }
88
89      printf("\n");
90    }
91
92    if (hasSubs)  // subviews are then shown, each as a separate block
93    {
94      for (int k = 0; k < types.GetLength(); ++k)
95      {
96        if (types[k] == 'V')
97        {
98          c4_Property prop = v_.NthProperty(k);
99
100          printf("%*s %4d: subview '%s'\n", l_, "", j,
101              (const char*) prop.Name());
102
103          c4_ViewProp& vp = (c4_ViewProp&) prop;
104
105          ViewDisplay(vp (v_[j]), l_ + 2);
106        }
107      }
108    }
109  }
110}
111
112/////////////////////////////////////////////////////////////////////////////
113
114int main(int argc, char** argv)
115{
116#ifdef d4_InitMain
117  d4_InitMain(argc, argv);
118#endif
119
120  const char* msg = 0;
121
122  if (argc != 2)
123    fprintf(stderr, "Usage: DUMP file\n");
124  else
125    try
126    {
127      msg = "could not open data file";
128
129      c4_Storage store (argv[1], false);
130
131      msg = "file may be damaged";
132
133      printf("%s: %d properties\n  %s\n\n",
134                  argv[1], store.NumProperties(),
135                  (const char*) store.Description());
136      ViewDisplay(store);
137
138      msg = 0;
139    }
140    catch (...)
141    {
142    }
143
144  if (msg)
145    fprintf(stderr, "Abnormal termination, %s\n", msg);
146
147  return msg ? 1 : 0;
148}
149
150/////////////////////////////////////////////////////////////////////////////
151