home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / streams / stream / streams.txt < prev   
Encoding:
Text File  |  1991-10-30  |  7.1 KB  |  143 lines

  1. //========================================================================
  2. //  The following example routines have been provided by the Technical
  3. //  Support staff at Borland International.  They are provided as a
  4. //  courtesy and not as part of a Borland product, and as such, are
  5. //  provided without the assurance of technical support or any specific
  6. //  guarantees.
  7. //========================================================================
  8. Topic:      Streamable objects (persistance)
  9.  
  10. Associated reading:   Chapter 8, Ch. 13 p223-237, look at the source code 
  11. in TVDemo that deals with saving and restoring the desktop.  (TVDemo member 
  12. functions saveDesktop() & storeDesktop() in tvdemo1.cpp and loadDesktop() & 
  13. retrieveDesktop() in tvdemo3.cpp)
  14.  
  15. Discussion:   How can an object be created, saved and restored at a later 
  16.  time, but still have the properties that the previous object had?  
  17.  Furthermore, can this be done with runtime identification of what the 
  18.  object actually was?  This property of objects is called persistance.  
  19.  Class TStreamable is a required base class for any persistant object and 
  20.  TView is derived from both TObject and TStreamable.  Thus any view that is 
  21.  displayed on the screen can be streamed (with a little modification to the 
  22.  class such an object contains instances or pointers to other objects, they 
  23.  must be streamable as well.  For example, a TListBox contains a 
  24.  TCollection*.  If this had been a TNSCollection* (non-streamable 
  25.  collection) then a TListBox could not be safely streamed.  We will use a 
  26.  modified set of stream classes derived from the C++ streams to read/write 
  27.  data to auxiliary storage media.  The following is a list of steps needed 
  28.  to make an object streamable:
  29.  
  30. 1)  The object must have TStreamable in its hierarchy.  Anything derived 
  31. from TView already fits this.  If you are deriving a new object from 
  32. TObject and you want to be able to stream such items, then use multiple 
  33. inheritance to also derive it from TStreamable.
  34.  
  35. 2)  Override the virtual read/write for data related to class (if the class 
  36. is derived from something, then you will call the parents read/write 
  37. function first.  e.g. TView::write().)  These should be protected data 
  38. members.  Prototypes are:
  39.  
  40.         virtual void write( opstream& )
  41.         virtual void *read( ipstream& )        // returns 'this'
  42.  
  43. 3)  Include a private constructor which accepts one parameter of type 
  44. StreamableInit (this is a typedef for 'streamableInit').  Have the 
  45. constructor call the parent class constructor and pass it the parameter 
  46. streamableInit.  e.g.
  47.  
  48.         TClassName( StreamableInit ) : TView( StreamableInit ) { }
  49.  
  50. 4)  Have a public function that builds a 'template' for the object.  This 
  51. will be used by the stream manager to create an instance of an object whose 
  52. data it is currently reading.  The prototype is TStreamable *build() and 
  53. here is an example:
  54.  
  55.         TStreamable *TClassName::build()
  56.             { return new TClassName( streamableInit ); }
  57.  
  58. 5)  Have a public static const character pointer called name.  This should 
  59. be initialized to a unique character string, normally the class name, e.g.
  60.  
  61.         const char * const TClassName::name = "TClassName";
  62.  
  63. 6)  Have a public function called streamableName() that returns the above 
  64. string, name.  It's implemented like this:
  65.  
  66.         virtual const char *streamableName() const
  67.             { return name; }
  68.  
  69. 7)  You need to register the object with the stream manager.  This requires 
  70. creation of an object of type TStreamableClass and passing the name, 
  71. address of the build member function and a third parameter to it's 
  72. constructor.  The name of this instance is normally RClassName.  e.g.
  73.  
  74.         TStreamableClass RClassName(    TClassName::name,
  75.                                                 TClassName::build,
  76.                                                 __DELTA( TClassName ) ); 
  77.  
  78. Also, when you are using a class that descends from Turbo Vision objects, 
  79. you have to pull in their registration instances too.  This done with the 
  80. __link() macro.  You will have to use it for the TV class that you have 
  81. derived your object from.  It takes a single argument that is the class 
  82. name of the TV class involved, except the first letter is an 'R' instead of 
  83. a 'T'.  If you derived TMyWindow from TWindow, you would do this:
  84.  
  85.         __link( RWindow );
  86.  
  87. 8)  This is optional, but you can overload the >> and << operators for this 
  88. object with the following lines:
  89.  
  90.         inline ipstream& operator >> (ipstream& is, TClassName & cl)
  91.             { return is >> (TStreamable&) cl; }
  92.         inline ipstream& operator >> (ipstream& is, TClassName *& cl)
  93.             { return is >> (void *&) cl; }
  94.         inline opstream& operator << (opstream& os, TClassName & cl)
  95.             { return os << (TStreamable&) cl; }
  96.         inline opstream& operator << (opstream& os, TClassName * cl)
  97.             { return os << (TStreamable *) cl; }
  98.  
  99. In this example, we are going to make our desktop objects streamable and
  100. implement two menu items which will save and restore the desktop.  Saving 
  101. the contents simply requires using the forEach() member function to iterate 
  102. through the items in the desktop, writing each out to the stream as we go.  
  103. Restoring is a little different because you must first clear the current 
  104. desktop before reading in the new items.  (If you did not clear the current 
  105. desktop, then where would those objects go when the old desktop w as 
  106. restored?)  Once the desktop is cleared, you can read in the items and 
  107. insert them.
  108.  
  109. File name:    streams.cpp
  110.  
  111. Do:   Add two new menu items - Save and Restore Desktop to the program 
  112. provided.  Add stream support to the objects in the program that can go in 
  113. the desktop.  Because adding stream support is nearly an identical task for 
  114. any object, this project has a special program that only has a few different
  115. views available.  See the above discussion and the TV Demo source code for 
  116. examples of streaming a class.  (e.g. PUZZLE.CPP and PUZZLE.H.)  The 
  117. save/restore items are easy to implement - you don't have to rough the 
  118. items inserted in the desktop, simply use the << or >> operators to send 
  119. TProgram::deskTop out/in the stream.
  120.  
  121. Classes used:
  122.     i/ofpstream - These are the names of the stream objects you will be 
  123.     working with, rather than the normal C++ iostream library functions.
  124.  
  125.     TStreamable - Base class for all streamable objects.  Any class that is 
  126.     streamed MUST be descended from this class.  (Note: Anything derived 
  127.     from TView already meets this requirement.)
  128.  
  129.     TStreamableClass - An object of this type is created for the purposes 
  130.     of registering a new object with the streams.  This gives the stream 
  131.     manager the tools to build an object that is being read.
  132.  
  133. Macros:
  134.  
  135. __link( RTVClassName ) - Used to register the Turbo Vision object 
  136. RTVClassName.
  137.  
  138. __DELTA( TClassName ) - This calculates the difference in address value 
  139. between a TClassName* and the embedded TStreamable* within.  TClassName has 
  140. multiple base classes, TStreamable and TObject, so these addresses are not 
  141. necessarily the same.  The stream manager needs this delta value to be able 
  142. to properly cast a TStreamable* back to the object it is supposed to be.
  143.