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

  1.  
  2.  
  3. #ifndef _stream_h_ /* Tue Feb 22 11:29:17 1994 */
  4. #define _stream_h_
  5.  
  6.  
  7.  
  8.  
  9.  
  10. /*
  11.  *
  12.  *          Copyright (C) 1994, M. A. Sridhar
  13.  *  
  14.  *
  15.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  16.  *     to copy, modify or distribute this software  as you see fit,
  17.  *     and to use  it  for  any  purpose, provided   this copyright
  18.  *     notice and the following   disclaimer are included  with all
  19.  *     copies.
  20.  *
  21.  *                        DISCLAIMER
  22.  *
  23.  *     The author makes no warranties, either expressed or implied,
  24.  *     with respect  to  this  software, its  quality, performance,
  25.  *     merchantability, or fitness for any particular purpose. This
  26.  *     software is distributed  AS IS.  The  user of this  software
  27.  *     assumes all risks  as to its quality  and performance. In no
  28.  *     event shall the author be liable for any direct, indirect or
  29.  *     consequential damages, even if the  author has been  advised
  30.  *     as to the possibility of such damages.
  31.  *
  32.  */
  33.  
  34.  
  35.  
  36.  
  37. // This is a logically abstract class representing the notion of a
  38. // positionable binary data stream. It provides operators and methods for
  39. // data transfer between objects and the stream. All operators and methods
  40. // are expressed in terms of six {\it core\/} methods: {\tt Read (uchar*,
  41. // long}, which reads a given number of bytes from the stream; {\tt Write
  42. // (uchar*, long}, which writes a given number of bytes to the stream;
  43. // {\tt SeekTo (long)}, which positions the stream's cursor; {\tt
  44. // Size()}, which returns the stream's current size in bytes; {\tt
  45. // ChangeSize (long)}, which changes the stream's size; and {\tt Offset ()},
  46. // which returns the cursor position.
  47. //
  48. // When the {\tt Remember} method is called, the Stream begins to remember
  49. // addresses of all instances of objects derived
  50. // from {\tt CL_Object}  that have been written to it.
  51. // An attempt to  write an object that has already been written
  52. // results in writing a reference to the previously-written object. This
  53. // is so that cyclic data structures can be
  54. // written and read from the Stream without danger of infinite recursion.
  55. // When it is necessary to make the Stream forget the remembered object
  56. // addresses, its {\tt Forget} method must be called.
  57.  
  58.  
  59.  
  60. #ifdef __GNUC__
  61. #pragma interface
  62. #endif
  63.  
  64. #include "base/object.h"
  65.  
  66.  
  67.  
  68. typedef long CL_Offset;
  69.  
  70. class CL_EXPORT CL_Stream: public CL_Object {
  71.  
  72. public:
  73.  
  74.     CL_Stream ();
  75.     // Constructor.
  76.  
  77.     ~CL_Stream ();
  78.     // Destructor.
  79.  
  80.   
  81.     // ----------------- Read operations -------------------------
  82.  
  83.     virtual long Read (uchar* buffer, long num_bytes) const;
  84.     // Read from current position. Returns number of bytes read, 0 on eof, -1
  85.     // on error.
  86.     // This is a core method, and must be overridden by the
  87.     // derived class.
  88.  
  89.     inline long Read (CL_Offset offset, uchar* buffer, long
  90.                       num_bytes) const;
  91.     // Read num_bytes bytes into buffer, starting at the given offset.
  92.     // Returns number of bytes read, 0 on eof, -1 on error.
  93.  
  94.     inline bool Read (long& value) const;
  95.     // Read a long value. Return TRUE on success, FALSE on failure
  96.     // (i.e., end of file or i/o error).
  97.     
  98.     const CL_Stream& operator>> (long& value) const
  99.         {Read (value); return *this;};
  100.     
  101.     inline bool Read (CL_Offset offset, long& value) const;
  102.     // Read a long value from the given position. Return TRUE on
  103.     // success, FALSE on failure (i.e., end of file or i/o error).
  104.     
  105.  
  106.     inline bool Read (short& value) const;
  107.     // Read a short value. Return TRUE on success, FALSE on failure
  108.     
  109.     const CL_Stream& operator>> (short& value) const
  110.         {Read (value); return *this;};
  111.     
  112.     inline bool Read (char& value) const;
  113.     // Read a char value. Return TRUE on success, FALSE on failure
  114.     
  115.     const CL_Stream& operator>> (char& value) const
  116.         {Read (value); return *this;};
  117.     
  118.     inline bool Read (uchar& value) const;
  119.     // Read an unsigned char value. Return TRUE on success, FALSE on failure
  120.     
  121.     const CL_Stream& operator>> (uchar& value) const
  122.         {Read (value); return *this;};
  123.     
  124.     inline bool Read (CL_Offset offset, short& value) const;
  125.     // Read a short value from the given position. Return TRUE on
  126.     // success, FALSE on failure (i.e., end of file or i/o error).
  127.  
  128.  
  129.     virtual bool Read (CL_Object& obj) const;
  130.     // Generic reading: uses the virtual {\tt ReadFrom} method. The parameter's
  131.     // {\tt ReadFrom} is called only if the object has not already been
  132.     // read from the Stream; this is to prevent duplication.  The address
  133.     // of each read object is remembered by the Stream.
  134.  
  135.  
  136.     const CL_Stream& operator>> (CL_Object& value) const
  137.         {Read (value); return *this;};
  138.  
  139.     bool Read (CL_Offset offset, CL_Object& obj) const;
  140.  
  141.  
  142.     virtual bool Read (CL_ObjectPtr& p) const;
  143.     // Read the value in the stream, construct an object from it, and
  144.     // assign it to the parameter. If the stream contains the "null
  145.     // pointer" indicator, then p is assigned NULL.
  146.     
  147.     const CL_Stream& operator>> (CL_ObjectPtr value) const
  148.         {Read (value); return *this;};
  149.  
  150.     bool Read (CL_Offset offset, CL_ObjectPtr obj) const;
  151.  
  152.     
  153.     // ----------------- Write operations ------------------------
  154.  
  155.     virtual bool Write (uchar* buffer, long num_bytes);
  156.     // Write at current position. The default implementation returns FALSE
  157.     // unconditionally.
  158.     // This is a core method, and must be overridden by the
  159.     // derived class.
  160.  
  161.     inline bool Write (CL_Offset offset, uchar* buffer, long num_bytes);
  162.     // Seek to position "offset" from beginning of file; then
  163.     // write num_bytes bytes into buffer. Offset 0 is the beginning of the
  164.     // file.
  165.  
  166.  
  167.     inline bool Write (long value);
  168.     // Write a long value. Return TRUE on success, FALSE on failure
  169.     // (e.g., i/o error).
  170.     
  171.     CL_Stream& operator<< (long value)
  172.         {Write (value); return *this;};
  173.     
  174.     inline bool Write (CL_Offset offset, long value);
  175.     // Write a long value at the given position. Return TRUE on
  176.     // success, FALSE on failure (e.g., i/o error).
  177.     
  178.     inline bool Write (short value);
  179.     // Write a short value. Return TRUE on success, FALSE on failure
  180.     
  181.     CL_Stream& operator<< (short value)
  182.         {Write (value); return *this;};
  183.     
  184.     inline bool Write (CL_Offset offset, short value);
  185.     // Write a short value from the given position. Return TRUE on
  186.     // success, FALSE on failure (i.e., end of file or i/o error).
  187.  
  188.     inline bool Write (uchar value);
  189.     // Write an unsigned char value. Return TRUE on success, FALSE on
  190.     // failure.
  191.     
  192.     CL_Stream& operator<< (uchar value)
  193.         {Write (value); return *this;};
  194.     
  195.     inline bool Write (char value);
  196.     // Write a char value. Return TRUE on success, FALSE on failure.
  197.     
  198.     CL_Stream& operator<< (char value)
  199.         {Write (value); return *this;};
  200.  
  201.  
  202.     virtual bool Write (CL_ObjectPtr p);
  203.     // Write the object pointed to by p to the stream. If the parameter is
  204.     // NULL, write the "null pointer" indicator. Otherwise, use the object's
  205.     // WriteTo method.
  206.     
  207.     CL_Stream& operator<< (CL_ObjectPtr value)
  208.         {Write (value); return *this;};
  209.  
  210.  
  211.     
  212.     virtual bool Write (const CL_Object& obj);
  213.     // Generic writing: uses the WriteTo method. The parameter's
  214.     // {\tt WriteTo} is called only if the object has not already been
  215.     // written to the Stream; this is to prevent duplication. The address
  216.     // of each written object is remembered by the Stream.
  217.  
  218.  
  219.     CL_Stream& operator<< (const CL_Object& value)
  220.         {Write (value); return *this;};
  221.  
  222.     inline bool Write (CL_Offset offset, const CL_Object& obj);
  223.     
  224.     bool Append (uchar* buffer, long num_bytes);
  225.     // Write at the end of the file
  226.     
  227.     
  228.     // ------------- Positioning and sizing operations ----------
  229.     
  230.     virtual bool SeekTo (CL_Offset position) const;
  231.     // Change the current position to the given one. Returns TRUE on success.
  232.     // This is a core method, and must be overridden by the
  233.     // derived class. The default implementation returns FALSE
  234.     // unconditionally.
  235.  
  236.     virtual bool SeekRelative (long change) const;
  237.     
  238.     bool SeekToBegin() const;
  239.     // Change the current position to the beginning of the stream.
  240.  
  241.     virtual bool SeekToEnd () const;
  242.     // Change the current position to the end of the stream.
  243.  
  244.     virtual bool ChangeSize (long new_size);
  245.     // Change the size of the stream to the given size. Return TRUE if
  246.     // successful.
  247.     // This is a core method, and must be overridden by the
  248.     // derived class. The default implementation returns FALSE
  249.     // unconditionally.
  250.  
  251.     virtual long Size () const {return 0;};
  252.     // Return the current size of the stream.
  253.     // This is a core method, and must be overridden by the
  254.     // derived class. The default implementation returns 0
  255.     // unconditionally.
  256.     
  257.     virtual bool Eof () const {return Size() <= Offset();};
  258.     // Return TRUE if the stream's cursor is at the end of the stream.
  259.     
  260.     virtual long Offset () const {return 0;};
  261.     // Return the current position.
  262.     // This is a core method, and must be overridden by the
  263.     // derived class. The default implementation returns 0
  264.     // unconditionally.
  265.  
  266.  
  267.     virtual CL_String ErrorString () const;
  268.       // Return the error message string associated with the current error
  269.     // status, if any.
  270.  
  271.     // ------------------- History-related operations ------------
  272.  
  273.     virtual void Remember ();
  274.     // Begin remembering the addresses of objects written into this
  275.     // stream.
  276.     
  277.     virtual void Forget ();
  278.     // Forget the remembered addresses.
  279.  
  280.     bool IsRemembering () const {return _remembering;};
  281.     // Return the current state, whether this stream is currently
  282.     // remembering object addresses.
  283.     
  284.     // -------------- Basic methods  ----------------------
  285.  
  286.     const char* ClassName() const {return "CL_Stream";};
  287.     // Override the method inherited from {\tt CL_Object}.
  288.  
  289.     CL_ClassId ClassId() const { return _CL_Stream_CLASSID;};
  290.     // Override the method inherited from {\tt CL_Object}.
  291.  
  292.     // ------------------- End public protocol ------------------------ 
  293.  
  294. protected:
  295.  
  296.     virtual CL_ObjectPtr _BuildObject () const;
  297.     // Read a class id from this stream, construct an empty object of
  298.     // that type and return it. Return NULL on error (e.g., no such type).
  299.     
  300.     bool          _remembering;
  301.     void*         _maps;
  302. };
  303.  
  304.  
  305.  
  306. inline long CL_Stream::Read (uchar* , long ) const
  307. {
  308.     return 0;
  309.  
  310.  
  311. inline bool CL_Stream::Write (uchar* , long )
  312. {
  313.     return FALSE;
  314. }
  315.  
  316.  
  317. inline bool CL_Stream::SeekTo (CL_Offset ) const
  318. {
  319.     return FALSE;
  320. }
  321.  
  322.  
  323. inline long CL_Stream::Read (CL_Offset offset, uchar* buffer, long
  324.                            num_bytes) const
  325. {
  326.     return SeekTo (offset) ? Read (buffer, num_bytes) : -1;
  327. }
  328.  
  329. inline bool CL_Stream::Read (long& value) const
  330. {
  331.     return Read ((uchar*) &value, sizeof value) == sizeof value;
  332. }
  333.  
  334. inline bool CL_Stream::Read (CL_Offset offset, long& value) const
  335. {
  336.     return SeekTo (offset) && (Read ((uchar*) &value, sizeof value) ==
  337.                                sizeof value); 
  338. }
  339.  
  340. inline bool CL_Stream::Read (short& value) const
  341. {
  342.     return Read ((uchar*) &value, sizeof value) == sizeof value;
  343. }
  344.  
  345. inline bool CL_Stream::Read (CL_Offset offset, short& value) const
  346. {
  347.     return SeekTo (offset) && (Read (offset, (uchar*) &value, sizeof
  348.                                      value) == sizeof value);
  349. }
  350.  
  351. inline bool CL_Stream::Read (char& value) const
  352. {
  353.     return Read ((uchar*) &value, sizeof value) == sizeof value;
  354. }
  355.  
  356. inline bool CL_Stream::Read (uchar& value) const
  357. {
  358.     return Read ((uchar*) &value, sizeof value) == sizeof value;
  359. }
  360.  
  361. inline bool CL_Stream::Read (CL_Offset offset, CL_Object& o) const
  362. {
  363.     return (SeekTo (offset)) &&  Read (o);
  364. }
  365.  
  366.  
  367.  
  368. inline bool CL_Stream::Write (CL_Offset offset, uchar* buffer, long
  369.                             num_bytes)
  370. {
  371.     return SeekTo (offset) && Write (buffer, num_bytes);
  372. }
  373.  
  374. inline bool CL_Stream::Write (long value)
  375. {
  376.     return Write ((uchar*) &value, sizeof value);
  377. }
  378.  
  379. inline bool CL_Stream::Write (CL_Offset offset, long value)
  380. {
  381.     return SeekTo (offset) && Write ((uchar*) &value, sizeof value);
  382. }
  383.  
  384. inline bool CL_Stream::Write (short value)
  385. {
  386.     return Write ((uchar*) &value, sizeof value);
  387. }
  388.  
  389. inline bool CL_Stream::Write (char value)
  390. {
  391.     return Write ((uchar*) &value, sizeof value);
  392. }
  393.  
  394. inline bool CL_Stream::Write (uchar value)
  395. {
  396.     return Write ((uchar*) &value, sizeof value);
  397. }
  398.  
  399. inline bool CL_Stream::Write (CL_Offset offset, short value)
  400. {
  401.     return SeekTo (offset) && Write ((uchar*) &value, sizeof value);
  402. }
  403.  
  404.  
  405. inline bool CL_Stream::Write (CL_Offset offset, const CL_Object& o)
  406. {
  407.     return SeekTo (offset) && Write (o);
  408. }
  409.  
  410.  
  411.  
  412. inline bool CL_Stream::SeekToEnd () const 
  413. {
  414.     return SeekTo (Size());
  415. }
  416.  
  417. inline bool CL_Stream::Append (uchar* buffer, long num_bytes)
  418. {
  419.     return SeekToEnd() && Write (buffer, num_bytes);
  420. }
  421.  
  422.  
  423.  
  424.  
  425. inline bool CL_Stream::ChangeSize (long) 
  426. {
  427.     return FALSE;
  428. }
  429.  
  430.  
  431. inline bool CL_Stream::SeekRelative (long change) const
  432. {
  433.     return SeekTo (Offset() + change);
  434. }
  435.  
  436. inline bool CL_Stream::SeekToBegin() const
  437. {
  438.     return SeekTo (0L);
  439. }
  440.  
  441. #endif /* _stream_h_ */
  442.