home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CSTREAM.ZIP / CSTREAM.DOC < prev    next >
Text File  |  1991-05-28  |  8KB  |  260 lines

  1.  
  2.  
  3.      Dear C++ programmer,
  4.  
  5.  
  6.      Thank  you for downloading csteam.  The StreamableClass 
  7.      class provides a base class for a  polymorphic  cluster 
  8.      of  streamable  classes!   In  other  words,  any class 
  9.      derived from the StreamableClass can  be  stored  on  a 
  10.      stream  and  subsequently loaded from the stream later.  
  11.      All such classes can be stored in any order and/or  mix 
  12.      on the same stream.
  13.  
  14.      The  inspiration  for  my  StreamableClass  comes  from 
  15.      Borland's TurboVision for Turbo Pascal, and there is no 
  16.      telling where they got it!  A TurboVision for BC++  has 
  17.      been  hinted  at  by  Borland but cstream allows you to 
  18.      stream classes without the whole TurboVision tool,  and 
  19.      to do it NOW!  Not to mention it's FreeWare.
  20.  
  21.  
  22.  
  23.      Getting Started
  24.      ===============
  25.  
  26.      Copy   cstream.hpp   to   your   header  directory  and 
  27.      cstream.cpp  along  with  csdemo.cpp  to  your   source 
  28.      directory.  Compile cstream.cpp and csdemo.cpp and link 
  29.      (a  project  file  is  included, i.e. csdemo.prj).  Run 
  30.      this demo and study its source.
  31.  
  32.  
  33.      In  order  to  make  a  class  streamable,  derive   it 
  34.      privately from StreamableClass.
  35.  
  36.  
  37.     class Employee : StreamableClass {
  38.         ...
  39.     public:
  40.         StreamableClassID(2);
  41.         
  42.         ...
  43.         
  44.         Employee();
  45.         ~Employee();
  46.     };
  47.  
  48.  
  49.      The  StreamableClassID macro is used to assign a unique 
  50.      id by which the class can be identified on the  stream. 
  51.      This   macro  also  declares  several  required  member 
  52.      functions of which you must define store() and  load().  
  53.      Below   is  the  macro  definition  as  it  appears  in 
  54.      cstream.hpp.
  55.  
  56.  
  57.     #define StreamableClassID(id)  \
  58.         enum { CLASS_ID = id };  \
  59.         StreamableClass::ID;          \
  60.         operator StreamC() { return (StreamC)this; }  \
  61.         virtual void store(ostream& os);             \
  62.         static StreamC load(istream& is, StreamC C)
  63.  
  64.  
  65.      Your store function should write out to "os"  the  data 
  66.      members  of your class, specifically the data needed in 
  67.      a call to a constructor for your class  and  any  other 
  68.      data  required to reconstruct your class to its present 
  69.      state. You'll see what I  mean  when  you  get  to  the 
  70.      description  for  load().   Don't worry about the id or 
  71.      any  fields  in  StreamableClass  -  this  is   handled 
  72.      automatically.
  73.  
  74.  
  75.     void Employee::store(ostream& os)
  76.     {
  77.         os << name << endf << address << endf
  78.             << cityStateZip << endf;
  79.     }
  80.  
  81.  
  82.  
  83.      Your  load  function  should read in the data stored in 
  84.      the extact order it was written out.
  85.  
  86.  
  87.     StreamC Employee::load(istream& is, StreamC C)
  88.     {
  89.         char *name, *address, *cityStateZip;
  90.  
  91.         if (C)
  92.             return C;
  93.         is.getline(nameBuf,MAX_STR_BUF,
  94.             StreamableClass::FieldTermChar);
  95.         is.getline(addressBuf,MAX_STR_BUF,
  96.             StreamableClass::FieldTermChar);
  97.         is.getline(cityStateZipBuf,MAX_STR_BUF
  98.             ,StreamableClass::FieldTermChar);
  99.         return new Employee(nameBuf,addressBuf,
  100.             cityStateZipBuf);
  101.     }
  102.  
  103.  
  104.      The load() function then calls your class'  constructor 
  105.      with  the  new  operator  to  create the class.  If any 
  106.      other information is  required  modify  your  class  to 
  107.      conform  to its prestorage state, that information will 
  108.      obviously have  to  be  read  in  and  the  appropriate 
  109.      modification  made.   Make  sure  your store() function 
  110.      stores this information.
  111.  
  112.      The trick  to  streamable  classes  is  in  the  load() 
  113.      function.  It is a static member of StreamableClass and 
  114.      thus has no implicit "this" parameter.  The address  of 
  115.      a  static function can be taken where as the address of 
  116.      a constructor cannot be! This is why load() is declared 
  117.      as such.  Note also  that  load  returns  "StreamC",  a 
  118.      pointer  to a StreamableClass base.  All  we  know when 
  119.      loading   a   StreamableClass   is   that   it   is   a 
  120.      StreamableClass.    You   must  call  the  ID()  member 
  121.      function, which returns the unique id  you  defined  in 
  122.      the StreamableClassID() macro, to determine its class.
  123.  
  124.  
  125.      If   your   class   is   not   directly   derived  from 
  126.      StreamableClass,   it   still   needs   to   use    the 
  127.      StreamableClassID()   macro.    Your  store()  function 
  128.      should call its immediate base class  store()  function 
  129.      first  before  storing its own data members. The load() 
  130.      function is alittle different.  It  still  should  call 
  131.      its  constructor  and  then  it can call its base class 
  132.      load()  function  to  get  any  additional  information 
  133.      required.  This  is  why  I  have  the test "if (C)" in 
  134.      Employee::load()  above.   You  need  to   think   your 
  135.      hierarchical design out thoroughly.  What is the access 
  136.      to your base class' data members?  Only data that can't 
  137.      be  accessed  directly, through constructors, or member 
  138.      functions, should be processed  by  the  base's  load() 
  139.      inside "if (C) ..."!
  140.  
  141.  
  142.      The  design  of streamable classes in C++ requires that 
  143.      we call a constructor  -  how  else  can  we  insure  a 
  144.      portable  way  of  initializing  virtual function table 
  145.      addresses?
  146.  
  147.  
  148.  
  149.      You should be wondering at this point how  the  correct 
  150.      static load() function will be called.  We need to back 
  151.      up   first   and   see  how  to  initialize  the  whole 
  152.      class-stream system. This is done by a global  call  to 
  153.      the macro StreamableClasses().
  154.  
  155.  
  156.     StreamableClasses(20);
  157.  
  158.     main()
  159.     {
  160.  
  161.         RegisterClass(StreamableClass);
  162.         RegisterClass(Employee);
  163.  
  164.         ...
  165.  
  166.         StreamableClass *S1, *S2, *S3;
  167.  
  168.         ifstream iS("emp$prod.cls");
  169.  
  170.         iS >> S1 >> S2 >> S3;
  171.  
  172.         //S1->ID()
  173.  
  174.     }
  175.  
  176.  
  177.      The  call here initializes the system to hold a maximum 
  178.      of 20 records for different streamable classes  in  our 
  179.      application.  You should set your count appropriately.
  180.  
  181.      The  classes  to  be streamed must be registered before 
  182.      attempting to stream them with  a  call  to  the  macro 
  183.      RegisterClass().    Besure   to   always  register  the 
  184.      StreamableClass for classes that may  for  some  reason 
  185.      not  provide  a  load()  function.  The RegisterClass() 
  186.      macro registers your class' ID and load function.
  187.  
  188.      When you go to read back  in  classes  from  a  stream, 
  189.      define  some pointers to StreamableClass and then fetch 
  190.      the classes from the  stream  to  these  pointers.   To 
  191.      determine  the  actual  class  fetched,  call  the ID() 
  192.      member function.
  193.  
  194.  
  195.  
  196.      Registration 
  197.      ============
  198.  
  199.      If you find cstream useful and  are  using it  in  your 
  200.      applications,  tell  your  friends.   You don't need to 
  201.      register cstream -- it's freeware!  All I ask  is  that 
  202.      you  leave  my  copyright  notice  intact!   How  about 
  203.      dropping me a line -- I like to here your comments  and 
  204.      suggestions.
  205.  
  206.  
  207.  
  208.      Other   Freeware  Goodies  available  for  Borland  C++ 
  209.      =======================================================
  210.  
  211.  
  212.      pckey    PC keyboard class w/auto enhanced 
  213.      gconio      Graphics mode conio class
  214.      cmouse     Mouse Driver class w/ intr handler
  215.      cmdln    Command line parser class
  216.      
  217.  
  218.  
  219.      And Shareware 
  220.      =============
  221.  
  222.  
  223.      FlexList II ANSI && K&R C
  224.      FlexList II C++
  225.  
  226.     * Ready-to-run C/C++ linked lists.
  227.     * Hybrid structure: stack,queue,list,array.
  228.     * Stores Heterogeneous/homogeneous data
  229.     * Eliminates the need for parameterized list
  230.         templates such as are proposed for
  231.         C++ in the future.
  232.  
  233.  
  234.      Loose Data Binder C++
  235.  
  236.     * Combination FlexList/TCollection
  237.     
  238.  
  239.     
  240.      Soon to be Released
  241.      ===================
  242.      
  243.      PolyMesh II C++
  244.      
  245.         * Networks of Polymorphic clusters
  246.     
  247.  
  248.  
  249.      Thanks again!
  250.  
  251.  
  252.      John W. Small
  253.      CIS: 73757,2233
  254.  
  255.      PSW / Power SoftWare
  256.      P.O. Box 10072
  257.      McLean,  VA  22102 8072
  258.      USA (703) 759-3838
  259.  
  260.