/****************************************************************************
* datapipe.h :
*
* HEader file for data pipe class.
*
* Change Log :
* July-12 1997 Initial version, Liujian Qian
*
* $Id: gdatapipe.h,v 1.6 1999/02/03 06:45:00 qian Exp $
***************************************************************************/
#ifndef _DATA_PIPE_H_
#define _DATA_PIPE_H_
#include <string.h>
#include "gcxx.h"
/**
DataPipe maintains an extensible in-memory binary data stream.
This class can be used as a <b> dynamic array </b> or a pipeline
stream for serializing classes' persistent data members.
The central information about the pipe is the 'cursor', which
indicates the current position where subsequent methods such as
<b> append </b>, and <b> fetch </b> will start. Such methods
will reposition the cursor accordingly upon the completion of
the operation. Other important data members of DataPipe includes
the "size" of the data in the pipe and the "ptr" to the location
wehre the data is stored in memory.
Every ADT in GFC defines at least two methods to store/retrive persistent
member data into and out of a pipe. They are the <b> store </b>
method and the <b> load </b> method. Additionaly there are two
global operators "DataPipe<<" and "DataPipe>>" for each ADT which can
be used handy when pumping several ADT objects into the same pipe.
Some sample use:
<pre>
GPolygon poly1;
GRect rect1;
... do some thing on poly1 and rect1 ...
DataPipe p;
p << poly1 <<rect1;
db.create_record(p.ptr(), p.size()); //store into the database
DataPipe also accepts standard built-in types such as int, float,
char* etc. Here is another example:
DataPipe p1;
int x=100, y=200;
float dist = 1000;
char *name = "Pittsburgh";
p1 <<x << y << dist << name;
DataPipe p2 (p);
p2 >> x2 >> y2 >> dist2 >> name2;
...
</pre>
TODO
Make DataPipe be able to redirect to i/o streams.
*/
class DataPipe
{
friend class GSlab;
friend class GRasterIO;
int cur; //cursor
int _capacity;
int data_len; //actual length been used
bool attached; //1 if the udp is attached to an external ptr
char* udp;
enum {delta=512};
public:
/**
* seek directions
*/
enum seek_dir {BEGIN=0, END=1, CURRENT=2};
public:
/**
*/
DataPipe() : cur(0),_capacity(0),data_len(0),attached(0),udp(0){};
/**
*/
DataPipe(int len);
/**
*/
DataPipe(const DataPipe& a);
/**
*/
DataPipe(const char* d, int length);
/**
*/
virtual ~DataPipe();
/**
* asignment operator
*/
virtual DataPipe& operator= (const DataPipe& a);
public:
/**
* This method appends data to the pipe.
* append new data to the end of the existing data buffer
* and advance cursor. The buffer in the pipe get automatically
* expanded if length is greater than available space in pipe.
* @param data is the data to be add to the pipe
* length the size of the new data
*/
Result append(const char* data, int length);
/**
* insert a chunk of data at the beginning of the pipe.
* New data is always put in the position 0 of the internal buffer.
* Existing data gets shifted to the tail by "length".
*/
Result insert(const char* data, int length);
/**
* copy a chunk of data starting at cursor into 'dest';
* the cursor in the pipe is advanced accordingly
*/
Result fetch(char* dest, int length);
/**
* attach this pipe to a pointer
*/
Result attach(void* p, int space);
/**
* detach the previously attached pointer
*/
Result detach(void);
/**
* extend the capacity for the pipe to the 'new_capacity'. Old
* contents are preserved.
*/
Result extendTo(int new_capacity);
/**
* move the cursor to the specified position
*/
Result seek(int off, int dir=BEGIN);
/**
* return the position (beginning with 0) of the cursor
*/
int pos (void) {return cur; };
/**
* return the pointer at cursor
*/
inline char* cursor(void) const {
return (cur>=data_len &&
data_len>0)?
(char*)0 :
(char*)(udp+cur);
}
/**
* memset all data to zeros; keep the capacity intact;
* reset cursor to 0
*/
inline void recycle();
/**
* return the pointer to the beginning of the data
*/
inline char* ptr(void) const {return (char*)udp; }
/**
* type conversiion operator;
*/
operator char*() { return (char*)udp; }
/**
* const char* conversion
*/
operator const char*() {return (const char*)udp; }
/**
* return true if reached end of pipe (eop)
*/
inline bool eop(void) const {return cur>=data_len;} ;
/**
* return the data size
*/
inline int size(void) const {return data_len; }
/**
* return the capacity
*/
inline int capacity(void) {return _capacity;}
/**
* reutrn free space in the array
*/
inline int remainder(void) const {return _capacity-data_len;}
/**
* print the data pipe
*/
friend ostream& operator<<(ostream& s, const DataPipe& p);
private:
/**
* increase the capacity by incr_sz. Negative
* increment is ignored.
*/
Result extend(int incr_sz=delta);
void setDataLen (int l) {data_len = l; }
};
inline void
DataPipe::recycle()
{
if(udp)
memset(udp, 0, _capacity);
data_len = cur =0;
}
extern DataPipe& operator<< (DataPipe& s, const char& c);
extern DataPipe& operator<< (DataPipe& s, const unsigned char& c);
extern DataPipe& operator<< (DataPipe& s, const int& i);
extern DataPipe& operator<< (DataPipe& s, const short& t);
extern DataPipe& operator<< (DataPipe& s, const long& i);
extern DataPipe& operator<< (DataPipe& s, const unsigned int& i);
extern DataPipe& operator<< (DataPipe& s, const unsigned short& t);
extern DataPipe& operator<< (DataPipe& s, const unsigned long& i);
extern DataPipe& operator<< (DataPipe& s, const float& f);
extern DataPipe& operator<< (DataPipe& s, const double& d);
extern DataPipe& operator<< (DataPipe& s, const char* string);
#ifndef _WIN32
extern DataPipe& operator<< (DataPipe& s, const int64& i);
#endif
extern DataPipe& operator>> (DataPipe& s, char& c);
extern DataPipe& operator>> (DataPipe& s, unsigned char& c);
extern DataPipe& operator>> (DataPipe& s, int& i);
extern DataPipe& operator>> (DataPipe& s, short& t);
extern DataPipe& operator>> (DataPipe& s, long& i);
extern DataPipe& operator>> (DataPipe& s, unsigned int& i);
extern DataPipe& operator>> (DataPipe& s, unsigned short& t);
extern DataPipe& operator>> (DataPipe& s, unsigned long& i);
extern DataPipe& operator>> (DataPipe& s, float& f);
extern DataPipe& operator>> (DataPipe& s, double& d);
extern DataPipe& operator>> (DataPipe& s, char* string);
#ifndef _WIN32
extern DataPipe& operator>> (DataPipe& s, int64& i);
#endif
#endif
Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999