zBucket
=============================================================================

    The zBucket class provides array-like syntax for typed file access.
    It is very useful for large binary files with records of the same
    type. The class can handle any file size supported by the file system,
    with up to 2 million records per file. The array syntax used is
    context-sensitive and allows both reads and updates (the class will
    detect which one to use from the context).

    To maximize performance, the class uses an internal buffer to cache
    elements when reading and writing. The size of this buffer is user-
    definable.

    Files can be used in read-only mode which significantly improves
    performance; however, out-of-bounds array indices will result in an
    error (with update mode, they result in extending the file).

    The class uses a templatized implementation to facilitate strong
    typing and compile-time error checking.


	ZBUCKET::ZBUCKET
	-------------------------------------------------------------------------

	    Summary    Constructs a zBucket object

	    Syntax     zBucket(const char *name, size_t nelems, Boolean update);

	    Remarks    This is the only constructor that can be used by the
	               caller. It ties the zBucket object to the file with
	               'name', and creates an internal buffer of 'nelems' number
	               of elements. A good size here would usually be around 64.
	               The 'update' parameter specifies whether the class can
	               update the file (i.e. allow assignment to the array
	               elements). If this parameter is True, the file 'name' need
	               not previously exist, it would be created as necessary.
	               If this parameter is False, the file must exist or the
	               constructor will fail. In case of failure, the error()
	               method will be called. You can check the status after
	               attempting to construct the object with the operator!()
	               or operator void*() member functions.

	    Example    zBucket<int> array("MYFILE.DAT", 256, False);
	               if( array ) { // ok, process here }

	    See also   zBucket::operator!, zBucket::operator void*


	ZBUCKET::~ZBUCKET
	-------------------------------------------------------------------------

	    Summary    Destroys the bucket object and flushes the file

	    Syntax     virtual ~zBucket();

	    Remarks    The destructor performs all the necessary cleanup for
	               the object, including closing the file and flushing any
	               changes as necessary.



	ZBUCKET::OPERATOR VOID*
	-------------------------------------------------------------------------

	    Summary    Test the error condition of the object

	    Syntax     operator void*() const;

	    Remarks    You can use this operator to test the status of the object
	               in a very intuitive way (within an if construct). In case
	               of an error, this operator returns 0, non-zero otherwise.

	    Return     0 if there's an error in the object,
	               Non-zero, if there is no error

	    Example    zBucket<int> bucket("DUMMY.DAT", 20, False);
	               if( bucket )	 // <-- this is where it gets used
	               { // we're ok
	               }


	ZBUCKET::OPERATOR !
	-------------------------------------------------------------------------

	    Summary    Return the status of the object

	    Syntax     Boolean operator!() const;

	    Remarks    The NOT operator returns the status of the object so that
	               if constructs can be used in the usual way.

	    Return     True on error, False if the object checks out

	    Example    zBucket<int> bucket("DUMMY.DAT", 35, True);
	               if( !bucket ) // <-- this is where it gets called
	               { // error processing
	               }


	ZBUCKET::NELEMS
	-------------------------------------------------------------------------

	    Summary    Returns the number of records in the file

	    Syntax     long nelems() const;

	    Remarks    This function returns the total number of records in the
	               file. This number can be modified by writing beyond the
	               upper bound of the array if the 'update' parameter in the
	               constructor is True. Usually, this method can be useful
	               to check for out-of-bounds conditions before attempting to
	               reference an element in the array.

	    Return     The number of records in the file

	    Example    for( long i = 0; ; )
	               { // this cycles through the file, with wrap-around
	                   cout << bucket[i];
	                   i = (i + 1) % bucket.nelems();
	               }


	ZBUCKET::OPERATOR []
	-------------------------------------------------------------------------

	    Summary    Retrieve or modify a record

	    Syntax     operator[](long index);

	    Remarks    This is the heart of the class. The subscript operator
	               allows the caller to retrieve or modify individual array
	               records using the familiar syntax. The operator is context
	               sensitive so you do not need any special functions to
	               signal that an update has taken place. Note that attempts
	               to modify records in read-only arrays (see constructor)
	               will result in calling the error() method. The 'index'
	               ranges from 0 to nelems() - 1 (as for all arrays). Note
	               that it can exceed the upper bound if the object is
	               writable. In this case, the file will be extended with
	               the necessary number of records to accomodate the index
	               specified. The gap will be filled with zeroes. Illegal
	               'index' values will cause the error() method to be called.

	    Return     Element, when object used as lvalue
	               Nothing, when object used as rvalue

	    Example    zBucket<int> bucket("DUMMY.FIL", 23, True);
	               if( bucket )
	               { // works even if the file does not exist!
	                   bucket[10] = 25;     // updates the file
	                   cout << bucket[10];  // prints 25
	               }


	ZBUCKET::ERROR
	-------------------------------------------------------------------------

	    Summary    Called internally on error

	    Syntax     virtual void error(int code);

	    Remarks    This function is called internally by the various methods
	               when an error condition is encountered. The default
	               implementation aborts the program with exit code of
	               255 - 'code'. You can override this function in a derived
	               class to provide for mor sophisticated error-handling. The
	               possible values for 'code' are:

                               protected enum error_types
                               {
                                   ERROR_FILE = 100,
                                   ERROR_MEMORY,
                                   ERROR_UNDERFLOW,
                                   ERROR_OVERFLOW,
                                   ERROR_INVREQ,
                               };

	               ERROR_FILE is used when the specified file could not be
	               opened or created, depending on the access mode specified
	               by the constructor. ERROR_MEMORY is used when there is
	               not enough memory to initialize the internal buffers and
	               maps. These runtime errors should be treated as fatal.
	               ERROR_UNDERFLOW and ERROR_OVERFLOW are used when illegal
	               array subscript is used (i.e. < 0 or >= nelems() when
	               the object is read-only). Finally, ERROR_INVREQ is used
	               when an assignment is attempted with a read-only object.

	    Return     Nothing

	    Example    n/a

