home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / c++advio 2.3 / Advanced i⁄o / voc.h < prev    next >
Encoding:
Text File  |  1997-03-05  |  14.1 KB  |  421 lines  |  [TEXT/ALFA]

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /*
  3.  ************************************************************************
  4.  *
  5.  *                Vocabulary service
  6.  *
  7.  * Multilevel/interrelated vocabularies with named slots are at the
  8.  * center of everything
  9.  *
  10.  * Vocabularies are polymorphic: a vocabulary slot may contain a simple
  11.  * data type (int, double, or a string, that is, const char *), a reference
  12.  * to another vocabulary, or just a (sub)vocabulary. Homogeneous vocabulary
  13.  * are those whose slots have exactly the same structure, which is reinforced
  14.  * when new entries are added.
  15.  * Vocabulary of vocabularies contains all full-fledged vocabularies: that
  16.  * is, each vocabulary is inserted in some other (parent) vocabulary,
  17.  * which in many cases is the Vocabulary of vocabularies (note, a
  18.  * vocabulary can be referenced from many vocabulary slots).
  19.  * A vocabulary path is a list of vocabularies to search for a named slot
  20.  * in, in order of appearance in the path.
  21.  *
  22.  * Vocabularies can be referred to from within other vocabularies by
  23.  * special vocabulary items, vocabulary references. A reference either
  24.  * points to a vocabulary (when it's completely "resolved") or just
  25.  * keeps the name of the referred vocabulary, which is to be looked up
  26.  * when needed (lazy reference). The reference may also contain a file
  27.  * name, from which the vocabulary would be loaded when it failed to
  28.  * be located otherwise. If the file name is relative (that is, does
  29.  * not start with '/'), it's prepended by dir names specified in
  30.  * the special env variable VOCPATH.
  31.  *
  32.  * A vocabulary supports the main basic functions: lookup, insert, delete,
  33.  * traverse. Looking up a slot (or a slot value) is the main function,
  34.  * and exists in many varieties.
  35.  * There is a function to look up a slot in the current dictionary, 
  36.  * in all dictionaries in the path (the top dictionary in the path
  37.  * is searched first, the dictionary underneath is search only if the
  38.  * lookup in the top dictionary failed, etc).
  39.  *
  40.  * Path search provides something like system-wide and specific
  41.  * environments/databases (a hierarchy of system/local environments).
  42.  * Previous incarnation of this pacakage was so-called task_env service
  43.  *
  44.  * Note, vocabulary objects and their slots are non-standard C++ objects.
  45.  * There is no public constructor/destructor available for them.
  46.  * When one creates a vocabulary, it is always inserted into the vocabulary
  47.  * of vocabularies, and, at the same time, put at the top of the vocabulary
  48.  * path (which makes it the current vocabulary). When an item is created, its
  49.  * memory is allocated dynamically, and it is inserted automatically into
  50.  * the current vocabulary. So, an item or a vocabulary cannot exist
  51.  * by itself, not being a part of some vocabulary. Therefore, a user
  52.  * is never given a vocabulary or slot object themselves, only references
  53.  * to them.
  54.  *
  55.  * Note, a vocabulary can contain another vocabulary (or a reference to
  56.  * another vocabulary). Subvocabularies are usually treated differently:
  57.  * they are not inserted into the Vocabulary of vocabularies, rather they
  58.  * are present only in the parent vocabulary (and die with it).
  59.  *
  60.  * $Id: voc.h,v 1.2 1997/03/04 21:02:18 oleg Exp oleg $
  61.  *
  62.  ************************************************************************
  63.  */
  64.  
  65. #ifndef __GNUC__
  66. #pragma once
  67. #endif
  68.  
  69. #ifndef _voc_h
  70. #define _voc_h 1
  71.  
  72. #ifdef __GNUC__
  73. #pragma interface
  74. #endif
  75.  
  76. #include "myenv.h"
  77.  
  78. //------------------------------------------------------------------------
  79. //        Data structures that represent the vocabulary
  80. // Note the only operation one can do on Voc Items is to create them
  81. // through a special (non-standard) creator that always creates an
  82. // object on heap and places an item into the current vocabulary.
  83. // So a vocabulary item cannot exist by itself, it can only be in
  84. // some vocabulary
  85.  
  86. #ifndef MSIPL_IOSTREAM_H
  87. class ostream;                // Opaque i/o classes
  88. class istream;
  89. #endif
  90.  
  91. class Voc;                // Forward decl of the Vocabulary
  92. class VocRefItem;            // Forward decl of the Vocabulary
  93. class VocPathPrivate;
  94.  
  95.                 // This is an abstract class that describes
  96.                 // the most generic item
  97. class GenericVocItem
  98. {
  99.   friend class Voc;
  100.   friend class VocRefItem;
  101.   friend class VocPathPrivate;
  102.  
  103. public:
  104.   enum Type { Int, Double, String, Vocab, VocRef, Last }; // Type of voc value
  105.   union TypeSet                // Union of all voc types
  106.   { int _int; double _double; const char * _str;  Voc * _voc; };
  107.  
  108. private:
  109.   GenericVocItem * next;        // Ptr to the next element or 0
  110.  
  111.                 // The following aren't implemented. But
  112.                 // since they are private, this makes any
  113.                 // (explicit or implicit) assignment impossible
  114. //  GenericVocItem(const GenericVocItem& another);
  115. //  GenericVocItem& operator=(const GenericVocItem& another);
  116.  
  117. protected:
  118.   char name[33];            // Name of the item, should not
  119.                     // contain "=" or non-ascii chars
  120.   const enum Type val_type;
  121.                     // Item value would follow in the
  122.                     // derived classes
  123.  
  124.                 // The derived classes must redefine the
  125.                 // following functions
  126.   virtual TypeSet get_value(void) const = 0;
  127.   virtual void write_down(ostream& outs) const;
  128.  
  129.                 // Don't allow laymen to construct the item
  130.                 // or destroy it
  131.   GenericVocItem(const char * _name, const Type type);
  132.   virtual ~GenericVocItem(void) { assert( next == 0 ); }
  133.  
  134.   void catalog(void);        // Add this item to the current vocabulary
  135.  
  136.                 // Read in and parse val_type & name, create
  137.                 // and return an item of an appropriate
  138.                 // type
  139.   static GenericVocItem * read_in(istream& ins);
  140.  
  141. public:
  142.   const char * q_name(void) const    { return name; }
  143.   enum Type    q_type(void) const    { return val_type; }
  144.   virtual void print(const char * title) const;
  145. };
  146.  
  147.                 // Some elementary voc items
  148. class IntVocItem : public GenericVocItem
  149. {
  150.   friend class GenericVocItem;
  151.  
  152.   int value;
  153.  
  154.   IntVocItem(const char * _name, const int _val) :
  155.       GenericVocItem(_name,GenericVocItem::Int), value(_val) {}
  156.   IntVocItem(const char * _name, istream& ins); // read the value in
  157.  
  158.                 // Standard interface
  159.   virtual TypeSet get_value(void) const
  160.           { TypeSet tset; tset._int = value; return tset; }
  161.   virtual void write_down(ostream& outs) const;
  162.  
  163. public:
  164.   friend const IntVocItem & new_IntVocItem(const char * _name, const int _val)
  165.     { IntVocItem& item = * new IntVocItem(_name,_val); item.catalog();
  166.       return item; }
  167. //  friend const IntVocItem & new_IntVocItem(const char * _name, istream& ins);
  168.   virtual void print(const char * title) const;
  169. };
  170.  
  171. class DoubleVocItem : public GenericVocItem
  172. {
  173.   friend class GenericVocItem;
  174.  
  175.   double value;
  176.  
  177.   DoubleVocItem(const char * _name, const double _val) :
  178.       GenericVocItem(_name,GenericVocItem::Double), value(_val) {}
  179.   DoubleVocItem(const char * _name, istream& ins); // read the value in
  180.  
  181.                 // Standard interface
  182.   virtual TypeSet get_value(void) const
  183.           { TypeSet tset; tset._double = value; return tset; }
  184.   virtual void write_down(ostream& outs) const;
  185.  
  186. public:
  187.   friend const DoubleVocItem & new_DoubleVocItem(const char * _name,
  188.                          const double _val)
  189.     { DoubleVocItem& item = * new DoubleVocItem(_name,_val);
  190.       item.catalog(); return item; }
  191. //  friend const DoubleVocItem & new_DoubleVocItem(const char * _name,
  192. //                         istream& ins);
  193.   virtual void print(const char * title) const;
  194. };
  195.  
  196.                 // String voc item
  197. class StrVocItem : public GenericVocItem
  198. {
  199.   friend class GenericVocItem;
  200.  
  201.   const char * value;
  202.  
  203.   StrVocItem(const char * _name, const char * _val);
  204.   StrVocItem(const char * _name, istream& ins); // read the value in
  205.   ~StrVocItem(void);
  206.  
  207.                 // Standard interface
  208.   virtual TypeSet get_value(void) const
  209.           { TypeSet tset; tset._str = value; return tset; }
  210.   virtual void write_down(ostream& outs) const;
  211.  
  212. public:
  213.   friend const StrVocItem& new_StrVocItem(const char * _name, 
  214.                       const char * _val)
  215.     { StrVocItem& item = * new StrVocItem(_name,_val); item.catalog();
  216.       return item; }
  217.   const StrVocItem& new_StrVocItem(const char * _name, istream& ins);
  218.   virtual void print(const char * title) const;
  219. };
  220.  
  221.  
  222.                 // Vocabulary: a collection of VocItem's
  223. class Voc : public GenericVocItem
  224. {
  225.   friend class GenericVocItem;
  226.   friend class VocRefItem;
  227.   friend class VocPathPrivate;
  228.   
  229.   GenericVocItem * first;
  230.   GenericVocItem * last;
  231.  
  232.   const char * comment;
  233.  
  234.   void ok_to_modify(void);        // Make sure it's ok to modify; set
  235.                     // the dirty bit if so
  236.  
  237.                     // if the dictionary is homogeneous
  238.   void homogenity_checking(GenericVocItem& item);
  239.                     // and non-empty, the item being added
  240.                     // should be structurally equivalent
  241.                     // to the item on the top of the
  242.                     // dictionary
  243.  
  244.  
  245.   void VocOfVoc_catalog(void);        // Add this Voc to the VocOfVoc
  246.   void make_current(void);        // Make this vocabulary current
  247.  
  248.                 // Find a slot with the specified name and
  249.                 // type. Return 0 if not found
  250.   virtual GenericVocItem * find(const char * _name, const Type type) const;
  251.  
  252. protected:
  253.   enum Option { ReadOnly = 1, Homogeneous = 2, Dirty = 8 } options;
  254.   int check_option(const Option opt) const    { return options & opt; }
  255.   void set_option(const Option opt)        { (int&)options |= opt; }
  256.   void reset_option(const Option opt)        { (int&)options &= ~opt; }
  257.  
  258.   Voc(const char * name, const char * comment);
  259.   ~Voc(void);
  260.  
  261.   Voc(istream& ins);                // Load from the istream
  262.   static Voc& load(const char * file_name);    // Load from the file (using
  263.                         // VOCPATH) & catalog
  264.  
  265.   virtual TypeSet get_value(void) const
  266.           { TypeSet tset; tset._voc = (Voc *)this; return tset; }
  267.   virtual void write_down(ostream& outs) const;
  268.  
  269.   void operator += (GenericVocItem& item);    // Add an item at the top
  270.   GenericVocItem& remove_top(void);        // Remove the item at the top
  271.  
  272. public:
  273.                 // Create an empty dictionary and make it
  274.                 // current
  275.   friend Voc& new_Voc(const char * _name, const char * _comment)
  276.     { Voc& voc = * new Voc(_name,_comment); 
  277.       voc.VocOfVoc_catalog(); voc.make_current(); return voc; }
  278.  
  279.                 // Read in a dictionary and make it
  280.                 // current
  281.   friend Voc& new_Voc(istream& ins)
  282.     { Voc& voc = * new Voc(ins);
  283.       voc.VocOfVoc_catalog(); voc.make_current(); return voc; }
  284.  
  285.                 // Create an empty dictionary and insert it
  286.                 // into the current vocabulary
  287.   friend Voc& new_subVoc(const char * _name, const char * _comment)
  288.     { Voc& voc = * new Voc(_name,_comment); 
  289.       voc.catalog(); return voc; }
  290.  
  291.  
  292.   void info(void) const;        // Just give brief info about the voc
  293.  
  294.                     // Deep vocabulary printing
  295.   virtual void print(const char * title) const;
  296.  
  297.   friend ostream& operator << (ostream& outs, const Voc& voc)
  298.   { voc.write_down(outs); return outs; }
  299.  
  300.   int q_empty(void) const        { return first == 0; }
  301.   const GenericVocItem& top(void) const;
  302.   const GenericVocItem& bottom(void) const;
  303.   int count(void) const;        // How many items in a dictionary
  304.  
  305.  
  306.                 // Retrieving functions, raise an exception if
  307.                 // the slot is not found
  308.   const char * find_str(const char * name) const;
  309.   int find_int(const char * name) const;
  310.   double find_double(const char * name) const;
  311.   Voc& find_voc(const char * name) const;
  312.  
  313.                 // Retrieving functions with a default value
  314.                 // (which is returned if the slot is not found)
  315.   const char * find_with_default(const char * name, 
  316.                  const char * default_val) const;
  317.   int find_with_default(const char * name, 
  318.                  const int default_val) const;
  319.   double find_with_default(const char * name, 
  320.                  const double default_val) const;
  321.   Voc& find_with_default(const char * name, 
  322.                  Voc& default_val) const;
  323. };
  324.  
  325.                 // Voc reference item - reference to another
  326.                 // vocabulary. The vocabulary may already
  327.                 // exist, or it can be represented by its
  328.                 // file name. It would be loaded when this
  329.                 // VocRefItem gets "dereferenced"
  330. class VocRefItem : public GenericVocItem
  331. {
  332.   friend class Voc;
  333.   friend class GenericVocItem;
  334.   friend class VocPathPrivate;
  335.  
  336.   Voc * value;
  337.   const char * voc_file_name;
  338.  
  339.   VocRefItem(const Voc& _voc) :        // Refer to an existing vocabulary
  340.       GenericVocItem(_voc.q_name(),GenericVocItem::VocRef), 
  341.       value((Voc *)&_voc), voc_file_name(0) {}
  342.   VocRefItem(const char * name);    // Look up the named vocabulary
  343.                     // and take its reference
  344.  
  345.                     // Create a proxy
  346.   VocRefItem(const char * name, const char * file_name);
  347.  
  348.   ~VocRefItem(void);
  349.  
  350.                 // Standard interface
  351.   virtual TypeSet get_value(void) const;    // Loads when necessary
  352.   virtual void write_down(ostream& outs) const;
  353.  
  354. public:
  355.   friend const VocRefItem& new_VocRefItem(Voc& _val)
  356.     { VocRefItem& item = * new VocRefItem(_val); item.catalog();
  357.       return item; }
  358.   friend const VocRefItem& new_VocRefItem(const char * voc_name)
  359.     { VocRefItem& item = * new VocRefItem(voc_name); item.catalog();
  360.       return item; }
  361.   friend const VocRefItem& new_VocProxy(const char * voc_name,
  362.                     const char * voc_file_name)
  363.     { VocRefItem& item = * new VocRefItem(voc_name,voc_file_name);
  364.       item.catalog(); return item; }
  365.   virtual void print(const char * title) const;
  366. };
  367.  
  368. void print_all_vocabularies(void);
  369.  
  370. extern Voc& Dummy_Voc;
  371.  
  372. class VocPathPrivate;
  373.                 // Path of current vocabularies
  374.                 // Note the current class provides only access
  375.                 // to the path, the path (data) are allocated
  376.                 // beforehand and stay this way
  377. class VocPath
  378. {
  379.   friend class VocPathPrivate;
  380.  
  381. public:
  382.   static void print(void);
  383.  
  384.                 // Retrieving functions, raise an exception if
  385.                 // the slot is not found
  386.   static const char * find_str(const char * name);
  387.   static int find_int(const char * name);
  388.   static double find_double(const char * name);
  389.   static Voc& find_voc(const char * name);
  390.  
  391.                 // Retrieving functions with a default value
  392.                 // (which is returned if the slot is not found)
  393.   static const char * find_with_default(const char * name, 
  394.                  const char * default_val);
  395.   static int find_with_default(const char * name, 
  396.                  const int default_val);
  397.   static double find_with_default(const char * name, 
  398.                  const double default_val);
  399.   static Voc& find_with_default(const char * name, 
  400.                  Voc& default_val);
  401.  
  402.                 // Find a vocabulary with a specified name
  403.   static void push(const char * name);
  404.                 // (in all the vocab in the path) and put it
  405.                 // at the top of the stack
  406.   static void pop(void);    // Remove the top (current) vocabulary
  407.  
  408. };
  409.  
  410.             // Mark the current state of the VocPath stack
  411. class VocPathMark
  412. {
  413.   const int vocpath_count;
  414. public:
  415.   void back_off(void) const;        // Back off to the marked state of VPath
  416.   VocPathMark(void);            // Note the current state of VocPath
  417.   ~VocPathMark(void)     { back_off(); }
  418. };
  419.  
  420. #endif
  421.