diff options
Diffstat (limited to 'src/SockIOreader.hh')
-rw-r--r-- | src/SockIOreader.hh | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/SockIOreader.hh b/src/SockIOreader.hh new file mode 100644 index 0000000..19f16bf --- /dev/null +++ b/src/SockIOreader.hh @@ -0,0 +1,141 @@ +#ifndef __SOCKIOREADER_HH_ +#define __SOCKIOREADER_HH_ + +#include "Arch.h" +#include "IO.hh" +#include "IEEEIO.hh" +#include "RawTCP.H" +#include "PortMux.H" + +/*========================================================================= +class: SockIOreader +description: Implements IEEEIO IO interface described in + http://bach.ncsa.uiuc.edu/IEEEIO over a socket connection. + The interface is read-only. This is the client and the SockIOwriter + is a server which sends data out to the SockIOreader from the + application. All data is cached in an IEEEIO file on the client + end (this side) for rapid local access by the client application. + +Problems: The background IO methods are kludgy at best. Currently it + depends on SigIO in order to determine when some new data is availible + on the socket. However, it is very difficult to demultiplex that + signal when you have more than one instance of SockIOreader active. + + Need a garaunteed method to determine if a client has dropped it connection. + A dropped connection can cause a lockup if it occurs during a blocking read. + This needs to have a SigALRM in order to recover from such errors. +===========================================================================*/ +//void IOsigHandler(int sig); // prototype + +class SockIOreader : public IObase { + + // The following data structures come straight out of IEEEIO and + // are necessary for interpreting the data coming in through the + // socket connection. Other than that, you can completely ignore them + // or refer directly to the docs in IEEEIO.hh if you really feel the + // need to understand what is happening here. + enum RecordType {DataRecord=1,AnnotationRecord,AttributeRecord}; + +#ifdef __hpux +// silly HPUX compiler doesn't allow FileHdr access to btorder... +public: +#endif + + // Structure for determining the native byte-order of data stored in the file + union btorder { + char c[4]; // write as int, read as int + int i; + }; + + // File header describes how many data records are in the file and what the + // version of the IEEEIO wrote this data. + struct FileHdr { + // do magic twice so we can figure out which byte-order + // the current machine is in addition (without hardcoding) in + // addition to which byte order the file is in + btorder magic; + btorder byteorder; + Long ndatasets; + short majorversion; + short minorversion; + }; + + // At the head of each data or attribute record. Identifies the type of + // record and how large it is so that it can be skipped if it doesn't contain + // relevant data. + struct RecordHdr { + int recordtype; + Long recordsize; + int sequenceID; + }; + + // This immediately follows a RecordHeader if the record contains raw data. + // this stores the number of dimensions and the datatype of the record + struct DataRecordHdr { + Long datasize; + int numbertype; + int rank; + }; + + // The immediately follows the RecordHeader if the record contains a + // NetCDF attribute. It stores the datatype, name and datasize of the + // attribute vector. + struct AttributeRecordHdr { + Long datasize; + int numbertype; + int namesize; // attributes are named + }; + + char scratchfilename[256]; // name of scratchfile in which to store the IEEEIO data + IEEEIO *scratchfile; // IEEEIO file descriptor for the scratch file + FastTCPserver ServerPort; // Server port from which connections from SockIOwriters are accept()'ed + RawTCPport *connected_client; // Only one client can be attached at a time. + //**** State information for IEEEIO management + RecordHdr current_rec; + DataRecordHdr current_data_rec; + AttributeRecordHdr current_att_rec; + //**** master_mux is the serverport (accept calls) and mux is the connected ports (new data) + PortMux master_mux,mux; + int n_complete_ds,current_ds,last_ds; // number of completely received datasets + current&last + int pending; // Flag if a new dataset transfer is currently in progress in the background. + + // Make this functionality inacessible since this class is read-only. + virtual int write(IObase::DataType typeID,int rank,CONST int *dims,void *data){return 0;} + virtual int writeAnnotation(CONST char *annotation){return 0;} + virtual int writeAttribute(CONST char *name,IObase::DataType typeID,Long length,void *data){return 0;} + virtual int reserveChunk(IObase::DataType typeID,int rank,CONST int *dims){return 0;} + virtual int reserveStream(IObase::DataType typeID,int rank,CONST int *dims){return 0;} + virtual int writeChunk(CONST int *chunkdims,CONST int *chunkorigin,void *data){return 0;} + virtual int writeStream(void *data,int length){return 0;} +protected: + int blockingRead(void *buffer,int size); // kludge + //static void halt(){} + //static int sendInProgress(){return 0;} +public: + void sigHandler(int sig); + friend void IOsigHandler(int *handler); // give the sighandler internal access to sigHandler(); + //------------------------core stuff..................... + SockIOreader(CONST char *scratchfilenm,int port); + SockIOreader(CONST char *scratchfilenm,int port,int tcpwindowsize); + virtual ~SockIOreader(); + // should check server status too + virtual int isValid(); + // could use overloading to differentiate type here... (but I'm going simple) + virtual int readInfo(IObase::DataType &typeID,int &rank,int *dims,int maxdims=3); + virtual int read(void *data); + virtual int seek(int dataset_index); + virtual int nDatasets(); + virtual int readAnnotationInfo(int number,int &length); + virtual int readAnnotation(int number,char *annotation,int maxsize=128); + virtual int nAnnotations(); + virtual int readAttributeInfo(int number,char *name,IObase::DataType &typeID,Long &nelem,int maxnamelen=128); + virtual int readAttributeInfo(CONST char *name,IObase::DataType &typeID,Long &nelem); + virtual int readAttribute(int number,void *data); + virtual int nAttributes(); + //-----------------Chunking Utilities.................. + //---Not implemented quite yet on server side, but you can read in chunks on client. + virtual int readChunk(CONST int *chunkdims,CONST int *chunkorigin,void *data); + virtual int readStream(void *data,int length){return 0;} +}; + +#endif |