home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / base / stream.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  5KB  |  207 lines

  1.  
  2.  
  3.  
  4.  
  5. /*
  6.  *
  7.  *          Copyright (C) 1994, M. A. Sridhar
  8.  *  
  9.  *
  10.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  11.  *     to copy, modify or distribute this software  as you see fit,
  12.  *     and to use  it  for  any  purpose, provided   this copyright
  13.  *     notice and the following   disclaimer are included  with all
  14.  *     copies.
  15.  *
  16.  *                        DISCLAIMER
  17.  *
  18.  *     The author makes no warranties, either expressed or implied,
  19.  *     with respect  to  this  software, its  quality, performance,
  20.  *     merchantability, or fitness for any particular purpose. This
  21.  *     software is distributed  AS IS.  The  user of this  software
  22.  *     assumes all risks  as to its quality  and performance. In no
  23.  *     event shall the author be liable for any direct, indirect or
  24.  *     consequential damages, even if the  author has been  advised
  25.  *     as to the possibility of such damages.
  26.  *
  27.  */
  28.  
  29.  
  30.  
  31.  
  32. #ifdef __GNUC__
  33. #pragma implementation
  34. #endif
  35.  
  36.  
  37. #include <stdarg.h>
  38. #include <stdio.h>
  39.  
  40. #include "base/stream.h"
  41. #include "base/error.h"
  42. #include "base/string.h"
  43. #include "base/map.h"
  44.  
  45.  
  46. // Have to resort to allocating this struct here, rather than making them
  47. // instance variables, just to please the #@!$% GCC compiler's template
  48. // instantiation quirks. -- MAS 7/16/94
  49.  
  50. struct MapStruct { 
  51.     CL_IntIntMap _readMap;
  52.     CL_IntIntMap _writeMap;
  53. };
  54.  
  55.  
  56. const short REAL_OBJECT = 'O', OBJ_REF = 'R', NULL_POINTER = 'N';
  57.  
  58. CL_Stream::CL_Stream ()
  59. {
  60.     _remembering = FALSE;
  61.     _maps = new MapStruct;
  62. }
  63.  
  64.  
  65.  
  66. CL_Stream::~CL_Stream ()
  67. {
  68.     if (_maps)
  69.         delete (MapStruct*) _maps;
  70. }
  71.  
  72.  
  73.  
  74.  
  75. bool CL_Stream::Read (CL_Object& obj) const
  76. {
  77.     short flag;
  78.     CL_ClassId id;
  79.     if (!Read (flag))
  80.         return FALSE;
  81.     switch (flag) {
  82.     case REAL_OBJECT:
  83.         Read (id); // Ignore the class id we wrote
  84.         return obj.ReadFrom (*this);
  85.  
  86.     case OBJ_REF:
  87.         CL_Error::Warning ("CL_Stream::Read: reading object, found pointer");
  88.         return FALSE;
  89.  
  90.     default: // Invalid flag
  91.         CL_Error::Warning ("CL_Stream::Read: invalid flag: %d", flag);
  92.         return FALSE;
  93.     }
  94. }
  95.  
  96.  
  97.  
  98.  
  99. bool CL_Stream::Read (CL_ObjectPtr& p) const
  100. {
  101.     short flag;
  102.     CL_Offset  offset, tmp;
  103.     if (!Read (flag))
  104.         return FALSE;
  105.     switch (flag) {
  106.     case REAL_OBJECT:
  107.         p = _BuildObject ();
  108.         tmp = Offset ();
  109.         if (p && p->ReadFrom (*this)) {
  110.             (((MapStruct*) _maps)->_readMap).Add (tmp, (long) p);
  111.             return TRUE;
  112.         }
  113.         return FALSE;
  114.  
  115.     case OBJ_REF:
  116.         if (!Read (offset) || offset < 0) // Read the offset of the object
  117.             return FALSE;
  118.         p = (CL_ObjectPtr) (((MapStruct*) _maps)->_readMap) [offset];
  119.         return p ? TRUE : FALSE;
  120.  
  121.     case NULL_POINTER:
  122.         p = NULL;
  123.         return TRUE;
  124.         
  125.     default: // Invalid flag
  126.         CL_Error::Warning ("CL_Stream::Read: invalid flag: %d", flag);
  127.         return FALSE;
  128.     }
  129. }
  130.  
  131.  
  132.  
  133.  
  134. bool CL_Stream::Write (const CL_Object& obj)
  135. {
  136.     if (_remembering) {
  137.         CL_Offset offset = (((MapStruct*) _maps)->_writeMap) [(long) &obj]-1;
  138.         // --------------------------------------------------------------^^^-
  139.         // This -1, and the corresponding +1 indicated below, are used to
  140.         // ensure that the value associated with each key
  141.         // in the map is positive, since the map returns 0 (null value) if the
  142.         // key is not in it. Of course, we could use the map's IncludesKey
  143.         // method to avoid this adjustment, but that would mean the
  144.         // inefficiency of two map lookups.
  145.         if (offset >= 0) {
  146.             // The writeMap contained this object, so we just write a
  147.             // reference.
  148.             return Write (OBJ_REF) && Write (offset);
  149.         }
  150.         // Othewise, write the object, and remember it. The offset
  151.         // maintained in the map is the offset o at which the object lives, not
  152.         // the offset o-4 at which we wrote the class id.
  153.         return Write (REAL_OBJECT) && Write (obj.ClassId()) 
  154.             && (((MapStruct*) _maps)->_writeMap).Add ((long) &obj, Offset()+1)
  155.             && obj.WriteTo (*this);
  156.         // -------------------------------------------------------------^^^
  157.         // See comment above
  158.     }
  159.     // Not currently remembering addresses:
  160.     return Write (REAL_OBJECT) && Write (obj.ClassId()) && obj.WriteTo (*this);
  161. }
  162.  
  163.  
  164. bool CL_Stream::Write (CL_ObjectPtr p)
  165. {
  166.     return p ?  Write (*p) : Write (NULL_POINTER);
  167. }
  168.  
  169.     
  170.  
  171. void CL_Stream::Remember ()
  172. {
  173.     (((MapStruct*) _maps)->_writeMap).MakeEmpty ();
  174.     _remembering = TRUE;
  175. }
  176.  
  177. void CL_Stream::Forget ()
  178. {
  179.     (((MapStruct*) _maps)->_writeMap).MakeEmpty ();
  180.     _remembering = FALSE;
  181. }
  182.  
  183.  
  184. CL_String CL_Stream::ErrorString () const
  185. {
  186.     return "";
  187. }
  188.  
  189.  
  190. typedef CL_Object* (*Creator) ();
  191.  
  192.  
  193. CL_ObjectPtr CL_Stream::_BuildObject () const
  194. {
  195.     CL_ClassId id;
  196.     if (!Read (id))
  197.         return NULL;
  198.     Creator f = (Creator) (CL_Object::_ClassIdMap [id]);
  199.     if (!f)
  200.         return NULL;
  201.     CL_Object* p = (*f) ();
  202.     return p;
  203. }
  204.  
  205.  
  206.  
  207.