aboutsummaryrefslogtreecommitdiff
path: root/src/SockIOreader.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/SockIOreader.hh')
-rw-r--r--src/SockIOreader.hh141
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