home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / CODING / CPP / METAKIT.ZIP / EXAMPLES / DUMP / DUMP.CPP next >
Encoding:
C/C++ Source or Header  |  1996-12-09  |  9.9 KB  |  347 lines

  1. //  dump.cpp  -  datafile dump utility sample code
  2. //
  3. //  This is a part of the MetaKit library.
  4. //  Copyright (c) 1996 Meta Four Software.
  5. //  All rights reserved.
  6. /////////////////////////////////////////////////////////////////////////////
  7. //
  8. //  This command-line utility displays different aspects of a datafile
  9. //  created with the MetaKit library: field structure (-f), low-level
  10. //  table structure (-s), low-level table contents dump (-d), or a
  11. //  normal dump of the entire view contents (default).
  12. //
  13. /////////////////////////////////////////////////////////////////////////////
  14.  
  15. #include "m4kit.h"
  16. #include "k4field.h"
  17. #include "k4table.h"
  18.  
  19. #include <stdio.h>
  20. #include <string.h>        // memcpy
  21.  
  22. #if defined (unix)
  23.     #define try
  24.     #define catch(x)    if (0)
  25. #endif     
  26.  
  27. #if defined (macintosh)
  28.     #include /**/ <console.h>
  29.     #define d4_InitMain(c,v)    c = ccommand(&v)
  30. #endif
  31.  
  32. typedef unsigned char    uchar;
  33. typedef unsigned long    ulong;
  34.  
  35. /////////////////////////////////////////////////////////////////////////////
  36. // Recursively display the field structure, table contents is not used here.
  37.  
  38. static void FieldDisplay(c4_Field& f_, int l_ =0)
  39. {
  40.     printf("%*s FIELD %s  off %d, width %d, depth %d : %s\n",
  41.                     l_, "",
  42.                     f_.IsRepeating() ? "[*] " : "",
  43.                     f_.Offset(), f_.Width(), f_.Depth(),
  44.                     (const char*) f_.Tag());
  45.  
  46.     int nc = f_.NumSubColumns();
  47.     if (nc > 0)
  48.     {
  49.         printf("%*s   columns:", l_, "");
  50.         for (int i = 0; i < nc; ++i)
  51.             printf(" %d.%s", i, (const char*) f_.SubColumn(i).Name());
  52.         printf("\n");
  53.     }
  54.  
  55.     int nf = f_.NumSubFields();
  56.     if (nf > 0)
  57.     {
  58.         printf("%*s    fields:", l_, "");
  59.         for (int i = 0; i < nf; ++i)
  60.             printf(" %d.%s", i, (const char*) f_.SubField(i).Name());
  61.         printf("\n");
  62.  
  63.         for (int j = 0; j < nf; ++j)
  64.                 // skip first field in root to avoid infinite recursion
  65.             if (l_ > 0 || j > 0)
  66.                 FieldDisplay(f_.SubField(j), l_ + 2);
  67.     }
  68. }
  69.  
  70. /////////////////////////////////////////////////////////////////////////////
  71. // Recursively display the raw table structure (optionally also contents).
  72. // This code does not use views, and attempts to continue after all errors.
  73.  
  74. static bool TableDisplay(c4_Table& t_, bool full_, int l_ =0)
  75. {
  76.     int errors = 0;
  77.  
  78.     int nr = t_.NumRows();
  79.     int nc = t_.NumColumns();
  80.  
  81.     printf("%*s TABLE %5d rows, %d cols\n", l_, "", nr, nc);
  82.  
  83.     for (int i = 0; i < nc; ++i)
  84.     {
  85.         c4_Field& f = t_.Field(i);
  86.  
  87.         if (f.IsRepeating())
  88.         {
  89.             for (int k = 0; k < nr; ++k)
  90.             {
  91.                 printf("%*s %4d: subtable [%d] %s\n", l_, "", i, k,
  92.                         (const char*) f.Name());
  93.  
  94.                     // skip first field in root to avoid infinite recursion
  95.                 if (l_ > 0 || i > 0)
  96.                     try
  97.                     {
  98.                         if (!TableDisplay(t_.SubTable(i, k), full_, l_ + 2))
  99.                             ++errors;
  100.                     }
  101.                     catch (...)
  102.                     {
  103.                         printf("*** Error in subtable (%s[%d].%s) ***\n",
  104.                                     (const char*) t_.Definition().Tag(),
  105.                                         k, (const char*) f.Name());
  106.                         ++errors;
  107.                     }
  108.  
  109.                 if (errors >= 5)
  110.                 {
  111.                     printf("*** Too many errors, bailing out ***\n");
  112.                     break;
  113.                 }
  114.             }
  115.         }
  116.         else
  117.         {
  118.             c4_Column& c = t_.Column(i);
  119.             printf("%*s %4d:%5u @ %-5lu %s", l_, "", i,
  120.                     c.Size(), c.Position(), (const char*) f.Name());
  121.  
  122.             if (full_)
  123.             {
  124.                 uchar data [16];
  125.  
  126.                     // produces a readable hex/ascii dump of column c
  127.                 for (ulong j = 0; j < c.Size(); j += 16)
  128.                 {
  129.                     int n1;
  130.                     const uchar* ptr = t_.LoadColumn(i, j, n1);
  131.                     if (n1 > 16)
  132.                         n1 = 16;
  133.                     memcpy(data, ptr, n1);
  134.  
  135.                     if (n1 < 16)
  136.                     {
  137.                         int n2;
  138.                         ptr = t_.LoadColumn(i, j + n1, n2);
  139.                         if (n1 + n2 > 16)
  140.                             n1 = 16 - n2;
  141.                         memcpy(data + n1, ptr, n2);
  142.                     }
  143.                     
  144.                     printf("\n %22lu: ", j);
  145.  
  146.                     for (int k = 0; k < 16; ++k)
  147.                     {
  148.                         if (k % 4 == 0)
  149.                             printf(" ");
  150.  
  151.                         if (j + k < c.Size())
  152.                             printf("%02X", data[k]);
  153.                         else
  154.                             printf("  ");
  155.                     }
  156.  
  157.                     printf("  ");
  158.  
  159.                     for (int l = 0; l < 16; ++l)
  160.                     {
  161.                         int ch = ' ';
  162.                         if (j + l < c.Size())
  163.                         {
  164.                             ch = data[l] & 0x7F;
  165.                             if (ch < ' ' || ch > '~')
  166.                                 ch = ' ';
  167.                         }
  168.  
  169.                         printf("%c", ch);
  170.                     }
  171.                 }
  172.             }
  173.  
  174.             printf("\n");
  175.         }
  176.     }
  177.  
  178.     return errors == 0;
  179. }
  180.  
  181. /////////////////////////////////////////////////////////////////////////////
  182. // Recursively display the entire view contents. The results shown do not
  183. // depend on file layout (free space, file positions, flat vs. on-demand).
  184.  
  185. static void ViewDisplay(const c4_View& v_, int l_ =0)
  186. {
  187.     c4_String types;
  188.     bool hasData = false, hasSubs = false;
  189.  
  190.         // display header info and collect all data types
  191.     printf("%*s VIEW %5d rows =", l_, "", v_.GetSize());
  192.     for (int n = 0; n < v_.NumProperties(); ++n)
  193.     {
  194.         c4_Property prop = v_.NthProperty(n);
  195.         char t = prop.Type();
  196.  
  197.         printf(" %s:%c", (const char*) prop.Name(), t);
  198.         
  199.         types += t;
  200.     
  201.         if (t == 'V')
  202.             hasSubs = true;
  203.         else
  204.             hasData = true;
  205.     }
  206.     printf("\n");
  207.  
  208.     for (int j = 0; j < v_.GetSize(); ++j)
  209.     {
  210.         if (hasData)    // data properties are all shown on the same line
  211.         {
  212.             printf("%*s %4d:", l_, "", j);
  213.             c4_RowRef r = v_[j];
  214.  
  215.             for (int k = 0; k < types.GetLength(); ++k)
  216.             {
  217.                 c4_Property p = v_.NthProperty(k);
  218.  
  219.                 switch (types[k])
  220.                 {
  221.                 case 'I':
  222.                     printf(" %ld", (long) ((c4_IntProp&) p) (r));
  223.                     break;
  224.  
  225.                 case 'F':
  226.                     printf(" %g", (double) ((c4_FloatProp&) p) (r));
  227.                     break;
  228.  
  229.                 case 'D':
  230.                     printf(" %.12g", (double) ((c4_DoubleProp&) p) (r));
  231.                     break;
  232.  
  233.                 case 'S':
  234.                     printf(" '%s'", (const char*) (c4_String)
  235.                                         ((c4_StringProp&) p) (r));
  236.                     break;
  237.  
  238.                 default:
  239.                     if (types[k] != 'V')
  240.                         printf(" (%c?)", types[k]);
  241.                 }
  242.             }
  243.  
  244.             printf("\n");
  245.         }
  246.  
  247.         if (hasSubs)    // subviews are then shown, each as a separate block
  248.         {
  249.             for (int k = 0; k < types.GetLength(); ++k)
  250.             {
  251.                 if (types[k] == 'V')
  252.                 {
  253.                     c4_Property prop = v_.NthProperty(k);
  254.  
  255.                     printf("%*s %4d: subview '%s'\n", l_, "", j,
  256.                             (const char*) prop.Name());
  257.  
  258.                     if (l_ > 0 || k > 0)
  259.                     {
  260.                         c4_ViewProp& vp = (c4_ViewProp&) prop;
  261.  
  262.                         ViewDisplay(vp (v_[j]), l_ + 2);
  263.                     }
  264.                 }
  265.             }
  266.         }
  267.     }
  268. }
  269.  
  270. /////////////////////////////////////////////////////////////////////////////
  271.  
  272. int main(int argc, char** argv)
  273. {
  274.     #ifdef d4_InitMain
  275.         d4_InitMain(argc, argv);
  276.     #endif
  277.  
  278.     bool sFlag = false, dFlag = false, fFlag = false, wFlag = false;
  279.  
  280.     while (argc > 1 && (argv[1][0] == '-' || argv[1][0] == '/'))
  281.     {
  282.         --argc;
  283.         switch ((*++argv)[1])
  284.         {
  285.         case 's': case 'S':     sFlag = true; break;
  286.         case 'd': case 'D':     dFlag = true; break;
  287.         case 'f': case 'F':     fFlag = true; break;
  288.         case 'w': case 'W':     wFlag = true; break;
  289.         }
  290.     }
  291.  
  292.     const char* msg = 0;
  293.     
  294.     if (argc != 2)
  295.         fprintf(stderr, "Usage: DUMP [-s|-d|-f|-w] file\n");
  296.     else
  297.         try
  298.         {
  299.             msg = "could not open data file";
  300.  
  301.             c4_Storage store (argv[1], false);
  302.  
  303.             msg = "file may be damaged";
  304.  
  305.             c4_View base = store.Contents().Container();
  306.  
  307.             printf("%s: %d properties\n  %s\n\n",
  308.                                     argv[1], base.NumProperties(),
  309.                                     (const char*) store.Description());
  310.  
  311.                 
  312.             if (sFlag || dFlag || fFlag)
  313.             {
  314.                 c4_Table& root = store.RootTable();
  315.                 c4_Field& field = root.Definition();
  316.  
  317.                 if (fFlag)
  318.                 {
  319.                     FieldDisplay(field);
  320.                     msg = 0;
  321.                 }
  322.                 else if (TableDisplay(root, dFlag))
  323.                     msg = 0;
  324.             }
  325.             else
  326.             {
  327.                 ViewDisplay(base);
  328.  
  329.                 msg = 0;
  330.             }
  331.         }
  332.         catch (...)
  333.         {
  334.         }
  335.     
  336.     if (msg)
  337.         fprintf(stderr, "Abnormal termination, %s\n", msg);
  338.  
  339.     if (wFlag)
  340.         getchar();
  341.  
  342.     return msg ? 1 : 0;
  343. }
  344.  
  345. /////////////////////////////////////////////////////////////////////////////
  346. // $Id: dump.cpp,v 1.6 1996/12/06 22:33:10 jcw Exp $
  347.