Tell emacs this is a -*-text-*- file...

pstream library - by Joshua Rowe

A persistent object stream library for C++.

Really, really cool!

Version 0.0.3

'nough said... let's get to the important stuff.


1.  BEWARE!!!

This is distributed under GPL.  Please follow its rules. 


2.  Building the library

Just edit the Makefile.  If you want to create ELF shared libs, set
SHARED=1.  Otherwise, set SHARED=0.  (It is 1 by default.)

INSTALLDIR should be the base directory of the installation;  the
library will be put int $INSTALLDIR/lib and the include files in
$INSTALLDIR/include.  Set it either to /usr or to /usr/local.

Do "make install" and you should be all set.  

3.  Using the library

Actually using the library is a little bit tougher.  We'll start with
the stream classes - pstream, ipstream, opstream, iopstream,
fdpstream, ifdpstream, ofdpstream, iofdpstream, fpstream, ifpstream,
ofpstream, iofpstream, pstreambuf, fdpstreambuf, fpstreambuf,
pstreamreg, pstreamed.  

Then we'll move on to creating your own streamable classes.  

3.1.  stream classes

All streams can be read to and written from using the extraction and
insertion operators >> and <<.  To use a stream, first create an
instance of the stream class you want to use.  The simply use the
insertion and extraction operators on them.  The operators can be
chained.  Most of the data types in GCC are supported.  An example:

int x = 5;
int y = 2;
char *c;
c = strdup("Hello there!");
ofpstream os("stream.out");
os << x << y << c;

Also, streamable class types are supported.  Classes derived from
pstreamable are streamable, as are pointers to these classes.  
We'll get into that later.  

3.1.1.  pstream

Simply a base class that implements some functionality important to
all stream classes.  

Also included are some functions that have a definite meaning for all
streams.  Descriptions for functions and data members follow:

pstream::buf
	A pointer to the class which handles the i/o for a stream.  It
is actually possible to create a stream with any source / destination
w/o creating a new stream type by providing a pointer to a custom
streambuf (which must be created anyway in order to create a new
source / destination).  

pstream::curid
	The current id used in the pstreamed mechanism.  

pstream::err
	The status of the last stream operation.  

pstream::flags
	The combination of flags in pstream::psFlags.

pstream::streamed
	This is a database of pointers to pstreamable's that have
already been streamed.  

pstream::psFlags
	A bunch of flags that control stream operation.
xxclose
	The buffer will be closed on calling pstream::close.
xxread
	The buffer will be opened for reading.
xxwrite
	The buffer will be opened for writing.
xxtrunc
	A file stream will be truncated.
xxexcl
	A file stream will be created exclusively.
xxcreat
	A file stream will be created.
xxappen
	A file steram will be opened for appending.
xxkill
	The buffer will be deleted when the estream is closed.

pstream::ptTypes
	These are the prefixes written to a stream when a pointer to a
pstreamable is written.
ptNULL
	The pointer has value NULL.
ptIndex
	The following data is an index into the pstream::streamed
database.
ptObject
	The following data is an object representation.

pstream::pstream(pstreambuf *abuf, int aflags)
	pstream constructor.  Uses the buffer abuf and sets flags to
aflags.  

pstream::~pstream()
	closes the current stream

pstream::addstreamed(pstreamable *obj)
	Adds the pair curid++, obj to the streamed database.

pstream::close()
	Deletes the streamed database.  Closes and kills the buffer
based on xxclose and xxkill.

pstream::error(int aerror)
	Sets err to aerror.

pstream::lookup(pvoid q)
	Returns the id associated with pointer q in the streamed
database.  

pstream::lookup(int aid)
	Returns the pstreamed object associated with id aid in the
streamed database.  

pstream::operator!()
	Returns err.


3.1.2.  opstream
	Provides the interface to a pstreambuf for an output stream.  

opstream::opstream(pstreambuf *abuf, int aflags)
	Passes abuf and aflags to pstream::pstream...

opstream::writebyte(char c)
	Writes the bytes c to the pstreambuf buf via writebytes.

opstream::writebytes(pvoid d, int l)
	Writes the data at d with length l to the pstreambuf buf.

opstream::writeint(int i)
	Writes the int i to the pstreambuf via writebytes.

opstream::writeobj(pstreamable *obj)
	Writes the object obj to the stream...
	If obj == NULL, write ptNULL.
	Else if the object has already been written already, ptIndex
is written and the object's index in the streamed database is
written.  
	Else write ptObject.  Write '['.  Write the string containing
the object's name (as returned by obj->streamableName).  Add the
object to the streamed database.  Call the objects write function.
Write ']'.  

opstream::writestring(char *c)
	Writes the length of the string c, then writes the string c.

operator<<(opstream &os, ...)
	Calls the appropriate write... function for that opstream.
Returns os, thus allowing for chainable operations.  

3.1.3.  ipstream
	Provides the interface to a pstreambuf for an output stream.  
	
ipstream::ipstream(pstreambuf *abuf, int aflags)
	Passes abuf and aflags to pstream::pstream...

ipstream::readbyte()
	Reads and returns a byte value from the stream.  

ipstream::readbytes(pvoid d, int l)
	Reads l bytes from the stream into the memory location d.

ipstream::readint
	Reads and returns an int value from the stream.

ipstream::readobj(pstreamreg *d, pstreamable *m)
	If m is zero, a new object type is created, built by the
builder specified in d.  A new pstreamed object is added to the
streamed database.  The object's read function is called.  A byte is
read (reading past the ']' written earlier).  We return the location
of the object in memory.  

ipstream::readstring()
	Reads in a string's length, allocates enough space for the
string using new, and reads the string into memory.  Returns the
address of the newly created string.  

operator>>(ipstream &is, ...)
	Calls the appropriate read functions.  

operator>>(ipstream &is, pvoid &x)
	Reads in a ptTypes value.  Sets x to 0 if the value read is
ptNULL.  Sets x to the pointer value of an already read object if the
ptTypes value is ptIndex.  If the ptTypes value is ptObject, it reads
in the object type, searches for the object type by calling the
system-wide registration mechaism's search function, and calls
readobj.  


3.1.4.  pstreamed
	Stores id and pointer pairs for already read and written
objects to a stream.  

pstreamed::id
	Stores the id member of the pair.

pstreamed::next
	Stores the location of the next pstreamed object in the
database.  

pstreamed::p
	Stores the pointer value associated with the pair.  


3.1.5.  pstreamable

pstreamable::pstreamable(pstreamableInit)
	Dummy constructor.  This just provides a unique method used in
creating an object without having to call its initialization stuff.  

pstreamable::streamableName()
	Returns the name of the object.  This is redefined in derived
classes, and should always return the class name of the object, so as
to prevent confusion.  

pstreamable::read(ipstream &is)
	Reads the object from the stream.  Must be redefined in
derived classes.  

pstreamable::write(opstream &os)
	Writes the object to the stream.  Must be redefined in derived
classes.  


3.1.6.  pstreamreg
	These classes hold a program-wide database of classes that can
be written and read from streams.  It stores names, build functions,
and a special delta value used in converting objects pointers to and
from pvoid and pstreamable.  

pstreamreg::name
	A string holding the name of the object type.  

pstreamreg::builder
	A pointer to a function used to create the object.  

pstreamreg::delta
	A special delta value used in pointer conversions.  

pstreamreg::findclass(char *aname)
	Searches the system-wide pstreamreg database pstreamreged for
the pstreamreg object holding a name value identical to aname.  


3.1.6.  pstreambuf
	Self explanatory, as is most of the rest of the stuff...

3.1.7.  fdpstreambuf
	Performs pstreambuf operations on a file descriptor.  

3.1.8.  fpstreambuf
	Creates a file and uses the returned file descriptor for use
in fdpstreambuf operations.  

3.1.9.  ...fdpstream
	Creates streams that work with a file descriptor.  A
fdpstreambuf is created and associated with the provided file
descriptor.  

3.1.10.  ...fpstream
	Create streams that work with a file.  A fpstreambuf is
created and associated with the provided file name.  


3.2.  Creating your own streamable classes.  

It's really easy.  Derive your class from pstreamable.  Redefine the
read and write members to read and write data (see the test.cc program
for an example).  Redefine the streamableName function to return the
name of the class.  Create insertion an extraction operators for the
class - simply copy the ones in the example.  Create a pstreamreg
object for that class.  

When deriving a class indirectly from pstreamable, be sure to call the
parent's read and write functions.  Also, be sure that data is written
in a predictible manner, and can be read back in the same order it was
written in.  

See test.cc for a complete example of deriving a class from
pstreamable both directly and indirectly.  


3.3.  Building programs

Be sure to include the file "pios.hh" for basic stream manipulations
(including deriving classes).  Also, include the file "fpios.hh" to
use any streams based on file-descriptors or files.  

Like the program with libpios like this:

	gcc -L ./ -o test test.o -lpios


4.  Me
	I am Joshua Rowe.  Hear me roar.  Have fun with this little
toy.  I like it.  See my regd program for an example of a program that
uses this library.

5.  Bugs
	Yes, you can report bugs to me - if you can find me.  Anyone
willing to put additional work into this program is welcome to - just
remember the GPL!  I don't plan on doing much to this library simply
because it works now for what I do with it.  Nothing fancy, just a few
weekends of work.  So if something doesn't work quite right, I'm not
surprised.  But if you don't like it, change it.  You get the idea.
Just be sure to keep my name associated with whatever changes you
make.

	I would like to make sure that all the versions of the
database are standardized.  So, if you do make changes, make sure that
they are made on the latest version.  I'll willingly maintain version
consistency, but don't particularly care to do much else with it.  So
if you want to make sure this library stays useful, send of your
modified versions with descriptions of what's changed to me.  


6.  To do...

	I'd like to make sure it follows some standards across
platforms - like converting things to network byte order, etc., so
that different platforms can communicate using this stream library
across tcp/ip.  I wish...



