| 1 | // This may look like C code, but it is really -*- C++ -*- | 
|---|
| 2 |  | 
|---|
| 3 | #ifndef PPFBINSTREAM_H_SEEN | 
|---|
| 4 | #define PPFBINSTREAM_H_SEEN | 
|---|
| 5 |  | 
|---|
| 6 | // PPF (Portable Persistence Format) Input/Output streams | 
|---|
| 7 | // | 
|---|
| 8 | // E. Aubourg     CEA DAPNIA/SPP  1999 | 
|---|
| 9 | // R. Ansari      LAL IN2P3/CNRS  2000-2003 | 
|---|
| 10 |  | 
|---|
| 11 |  | 
|---|
| 12 | #include "machdefs.h" | 
|---|
| 13 | #include "rawstream.h" | 
|---|
| 14 |  | 
|---|
| 15 | #include <time.h> | 
|---|
| 16 |  | 
|---|
| 17 | #include <complex> | 
|---|
| 18 | #include <string> | 
|---|
| 19 | #include <map> | 
|---|
| 20 | #include <vector> | 
|---|
| 21 |  | 
|---|
| 22 |  | 
|---|
| 23 |  | 
|---|
| 24 | namespace SOPHYA { | 
|---|
| 25 |  | 
|---|
| 26 | class PPFBinaryIOStream { | 
|---|
| 27 | public: | 
|---|
| 28 |  | 
|---|
| 29 | enum  PPFByteOrdering  {PPS_NATIVE = -1, PPS_LITTLE_ENDIAN = 0, PPS_BIG_ENDIAN = 1}; | 
|---|
| 30 |  | 
|---|
| 31 | // Value of item identification tags in PPF binary streams | 
|---|
| 32 | enum  PPFItemTag { | 
|---|
| 33 | PPS_NULL = 0,             // this is a null object | 
|---|
| 34 | PPS_STRING = 1,           // string, length (4b) + data | 
|---|
| 35 | PPS_OBJECT = 2,           // classId, data... | 
|---|
| 36 | PPS_REFERENCE = 3,        // objectId | 
|---|
| 37 | PPS_NAMETAG_TABLE = 4,    // Name tag table (Written at the end of file/stream) | 
|---|
| 38 | PPS_EOF = 5,              // Just before tag infomation, offset to PPS_TAG | 
|---|
| 39 | PPS_ENDOBJECT = 6,        // marks the end of a given object information | 
|---|
| 40 | PPS_NAMETAG_MARK = 7,     // To have a name tag, position marker in a file | 
|---|
| 41 | PPS_POSTAG_MARK = 8,      // Position tag mark + 8 bytes (=stream position) | 
|---|
| 42 | PPS_POSTAG_TABLE = 9,     // Position tag table + 8 bytes (=stream position) | 
|---|
| 43 | PPS_SIMPLE = 16,          // 16 + number of bytes, up to 8 bytes | 
|---|
| 44 | PPS_SIMPLE_ARRAY4 = 32,   // 32 + number of bytes, up to 8 bytes, then 4 bytes of length | 
|---|
| 45 | PPS_SIMPLE_ARRAY8 = 48    // 48 + number of bytes, up to 8 bytes, then 8 bytes of length | 
|---|
| 46 | }; | 
|---|
| 47 |  | 
|---|
| 48 | // The following values are used with PPS_SIMPLE and PPS_SIMPLE_ARRAY (Using OR) | 
|---|
| 49 | enum   PPFItemTagDataType { | 
|---|
| 50 | PPS_DATATYPE_CHAR = 0,        // 0  : DataType=character | 
|---|
| 51 | PPS_DATATYPE_FLOAT = 64,      // 64 : DataType=float | 
|---|
| 52 | PPS_DATATYPE_COMPLEX = 65,    // 65 : DataType=complex | 
|---|
| 53 | PPS_DATATYPE_INTEGER = 128,   // 128 :DataType=integer | 
|---|
| 54 | PPS_DATATYPE_UNSIGNED = 192   // 192 :DataType=Unsigned integer | 
|---|
| 55 | }; | 
|---|
| 56 |  | 
|---|
| 57 | PPFBinaryIOStream(); | 
|---|
| 58 | virtual ~PPFBinaryIOStream(); | 
|---|
| 59 |  | 
|---|
| 60 | inline int    Version() {return version;}  // PIn/OutPersist version number | 
|---|
| 61 | inline time_t CreationDate() { return creationdate; } | 
|---|
| 62 | string        CreationDateStr(); | 
|---|
| 63 | string        InfoString(); | 
|---|
| 64 |  | 
|---|
| 65 | inline int_8  NbPosTags() {return _nbpostag; } | 
|---|
| 66 | inline int_8  NbNameTags() {return tags.size(); } | 
|---|
| 67 | inline int_8  NbObjects() {return _nbobjs; } | 
|---|
| 68 | inline int_8  NbTopLevelObjects() {return _nbtlobjs; } | 
|---|
| 69 | inline int_8  NbReferences() {return _nbrefs; } | 
|---|
| 70 | inline int_4  MaxNestedObjsLevel() {return _maxnestlevel; } | 
|---|
| 71 |  | 
|---|
| 72 | string GetTagName(int itag);  // 0..NbTags-1 | 
|---|
| 73 | vector<string> const &  GetNameTags(); | 
|---|
| 74 |  | 
|---|
| 75 | protected: | 
|---|
| 76 | // La liste des NameTag ds le flot | 
|---|
| 77 | map<string, int_8> tags; | 
|---|
| 78 | int version;     // PPersist(In/Out) version | 
|---|
| 79 | time_t creationdate;   // Date de creation du fichier | 
|---|
| 80 |  | 
|---|
| 81 | // Variables pour garder le compte des objets et des tags | 
|---|
| 82 | // Le nombre d'objets a l'ecriture est mis a jour par la classe | 
|---|
| 83 | // derivee POutPersist | 
|---|
| 84 | int_8 _nbpostag;     // Nb de tag de positionnement | 
|---|
| 85 | int_8 _nbobjs;       // Nb total d'objets | 
|---|
| 86 | int_8 _nbtlobjs;     // Nb d'objets de niveau 1 | 
|---|
| 87 | int_8 _nbrefs;       // Nb de references PPS_REFERENCE | 
|---|
| 88 | int_4 _maxnestlevel; // Niveau maximum d'objets emboites | 
|---|
| 89 | }; | 
|---|
| 90 |  | 
|---|
| 91 |  | 
|---|
| 92 | //! Input PPF (Portable Persist Format) streams | 
|---|
| 93 | class PPFBinaryInputStream : public PPFBinaryIOStream { | 
|---|
| 94 | public: | 
|---|
| 95 | PPFBinaryInputStream(RawInOutStream * is, bool ad, bool scan=false); | 
|---|
| 96 | PPFBinaryInputStream(string const& flnm, bool scan=true); | 
|---|
| 97 | virtual  ~PPFBinaryInputStream(); | 
|---|
| 98 |  | 
|---|
| 99 | inline string FileName() { return s->getFileName(); }   // Retourne le nom de fichier | 
|---|
| 100 |  | 
|---|
| 101 | // Gestion des tags | 
|---|
| 102 | bool   GotoPositionTag(int_8 pos); | 
|---|
| 103 | bool   GotoNameTag(string const& name); | 
|---|
| 104 | bool   GotoNameTagNum(int itag);  // 0..NbTags-1 | 
|---|
| 105 |  | 
|---|
| 106 | // Saut jusqu'au prochain objet | 
|---|
| 107 | bool   SkipToNextObject(); | 
|---|
| 108 | // Saut d'un item de base (tag+donnees correspondantes), le suivant ds le flot | 
|---|
| 109 | bool   SkipNextItem(); | 
|---|
| 110 | // Lecture du tag de type next item + infos correspondantes | 
|---|
| 111 | // Le stream est re-positionne avant le tag | 
|---|
| 112 | char   NextItemTag(short & datasz, size_t & sz); | 
|---|
| 113 |  | 
|---|
| 114 | // Lecture donnees de base et tableaux de donnees de base | 
|---|
| 115 | // Basic data type (and corresponding arrays) reading | 
|---|
| 116 | void   GetByte (char& c); | 
|---|
| 117 | void   GetBytes(void* ptr, size_t bytes); | 
|---|
| 118 | void   GetR4   (r_4&); | 
|---|
| 119 | void   GetR4s  (r_4*, size_t); | 
|---|
| 120 | void   GetR8   (r_8&); | 
|---|
| 121 | void   GetR8s  (r_8*, size_t); | 
|---|
| 122 | void   GetI1   (int_1&); | 
|---|
| 123 | void   GetI1s  (int_1*, size_t); | 
|---|
| 124 | void   GetU1   (uint_1&); | 
|---|
| 125 | void   GetU1s  (uint_1*, size_t); | 
|---|
| 126 | void   GetI2   (int_2&); | 
|---|
| 127 | void   GetI2s  (int_2*, size_t); | 
|---|
| 128 | void   GetU2   (uint_2&); | 
|---|
| 129 | void   GetU2s  (uint_2*, size_t); | 
|---|
| 130 | void   GetI4   (int_4&); | 
|---|
| 131 | void   GetI4s  (int_4*, size_t); | 
|---|
| 132 | void   GetU4   (uint_4&); | 
|---|
| 133 | void   GetU4s  (uint_4*, size_t); | 
|---|
| 134 | void   GetI8   (int_8&); | 
|---|
| 135 | void   GetI8s  (int_8*, size_t); | 
|---|
| 136 | void   GetU8   (uint_8&); | 
|---|
| 137 | void   GetU8s  (uint_8*, size_t); | 
|---|
| 138 | void   GetLine (char* ptr, size_t len); | 
|---|
| 139 | void   GetStr  (string&); | 
|---|
| 140 | void   GetZ4   (complex<r_4> &); | 
|---|
| 141 | void   GetZ4s  (complex<r_4> *, size_t); | 
|---|
| 142 | void   GetZ8   (complex<r_8> &); | 
|---|
| 143 | void   GetZ8s  (complex<r_8> *, size_t); | 
|---|
| 144 |  | 
|---|
| 145 | inline void   Get(char&   c) {GetByte(c);} | 
|---|
| 146 | inline void   Get(r_4&    x) {GetR4(x);} | 
|---|
| 147 | inline void   Get(r_8&    x) {GetR8(x);} | 
|---|
| 148 | inline void   Get(uint_1& x) {GetU1(x);} | 
|---|
| 149 | inline void   Get(int_1&  x) {GetI1(x);} | 
|---|
| 150 | inline void   Get(uint_2& x) {GetU2(x);} | 
|---|
| 151 | inline void   Get(int_2&  x) {GetI2(x);} | 
|---|
| 152 | inline void   Get(uint_4& x) {GetU4(x);} | 
|---|
| 153 | inline void   Get(int_4&  x) {GetI4(x);} | 
|---|
| 154 | inline void   Get(uint_8& x) {GetU8(x);} | 
|---|
| 155 | inline void   Get(int_8&  x) {GetI8(x);} | 
|---|
| 156 | inline void   Get(complex<r_4> & x) {GetZ4(x);} | 
|---|
| 157 | inline void   Get(complex<r_8> & x) {GetZ8(x);} | 
|---|
| 158 |  | 
|---|
| 159 | inline void   Get(r_4*    x, size_t n) {GetR4s(x,n);} | 
|---|
| 160 | inline void   Get(r_8*    x, size_t n) {GetR8s(x,n);} | 
|---|
| 161 | inline void   Get(uint_1* x, size_t n) {GetU1s(x,n);} | 
|---|
| 162 | inline void   Get(int_1*  x, size_t n) {GetI1s(x,n);} | 
|---|
| 163 | inline void   Get(uint_2* x, size_t n) {GetU2s(x,n);} | 
|---|
| 164 | inline void   Get(int_2*  x, size_t n) {GetI2s(x,n);} | 
|---|
| 165 | inline void   Get(uint_4* x, size_t n) {GetU4s(x,n);} | 
|---|
| 166 | inline void   Get(int_4*  x, size_t n) {GetI4s(x,n);} | 
|---|
| 167 | inline void   Get(uint_8* x, size_t n) {GetU8s(x,n);} | 
|---|
| 168 | inline void   Get(int_8*  x, size_t n) {GetI8s(x,n);} | 
|---|
| 169 | inline void   Get(string& x) {GetStr(x);} | 
|---|
| 170 | inline void   Get(complex<r_4> * x, size_t n) { GetZ4s(x, n); } | 
|---|
| 171 | inline void   Get(complex<r_8> * x, size_t n) { GetZ8s(x, n); } | 
|---|
| 172 |  | 
|---|
| 173 | // Reading a list (table) of position tags | 
|---|
| 174 | void    GetPosTagTable(int_8*, size_t); | 
|---|
| 175 | void    GetPosTagTable(vector<int_8>&); | 
|---|
| 176 |  | 
|---|
| 177 | void   AnalyseTags(int lev=0);   // List (all or some) tags ... | 
|---|
| 178 |  | 
|---|
| 179 | protected: | 
|---|
| 180 | void   Init(bool scan); | 
|---|
| 181 | void   ReadNameTagTableV2(); | 
|---|
| 182 | void   ReadNameTagTable(); | 
|---|
| 183 |  | 
|---|
| 184 | void   SkipItem(bool fgrdi=true, unsigned char itag=0); | 
|---|
| 185 |  | 
|---|
| 186 | void   CheckTag   (short datasz, short datatype); | 
|---|
| 187 | void   CheckArrayTag(short datasz, size_t sz, short datatype); | 
|---|
| 188 | void   GetTypeTag (unsigned char& c); | 
|---|
| 189 | void   GetRawByte (char& c); | 
|---|
| 190 | void   GetRawUByte (unsigned char& c); | 
|---|
| 191 | void   GetRawBytes(void* ptr, size_t bytes); | 
|---|
| 192 | void   GetRawI2   (int_2&); | 
|---|
| 193 | void   GetRawI4   (int_4&); | 
|---|
| 194 | void   GetRawI8   (int_8&); | 
|---|
| 195 | void   GetRawU8   (uint_8&); | 
|---|
| 196 |  | 
|---|
| 197 | RawInOutStream* s; | 
|---|
| 198 | bool _ads; // delete/close the stream at the end | 
|---|
| 199 |  | 
|---|
| 200 | bool bigEndian; | 
|---|
| 201 | // Si on a fait une lecture non sequentielle  -> seqread = false | 
|---|
| 202 | bool seqread; | 
|---|
| 203 | }; | 
|---|
| 204 |  | 
|---|
| 205 | //! Output stream for PPersit objects. | 
|---|
| 206 | class PPFBinaryOutputStream : public PPFBinaryIOStream { | 
|---|
| 207 | public: | 
|---|
| 208 | PPFBinaryOutputStream(RawInOutStream* os, bool ad, int endianness = PPS_NATIVE); | 
|---|
| 209 | PPFBinaryOutputStream(string const& flnm, int endianness = PPS_NATIVE); | 
|---|
| 210 | virtual ~PPFBinaryOutputStream(); | 
|---|
| 211 |  | 
|---|
| 212 | inline string FileName() { return s->getFileName(); }   // Retourne le nom de fichier | 
|---|
| 213 |  | 
|---|
| 214 | // Ecriture de tags | 
|---|
| 215 | int_8 WritePositionTag(); | 
|---|
| 216 | void  WriteNameTag(string const& name); | 
|---|
| 217 | inline void WriteTag(string const& name) { WriteNameTag(name); } | 
|---|
| 218 |  | 
|---|
| 219 | void PutByte (char c); | 
|---|
| 220 | void PutBytes(void const* ptr, size_t bytes); | 
|---|
| 221 | void PutR4   (r_4); | 
|---|
| 222 | void PutR4s  (r_4 const*, size_t); | 
|---|
| 223 | void PutR8   (r_8); | 
|---|
| 224 | void PutR8s  (r_8 const*, size_t); | 
|---|
| 225 | void PutI1   (int_1); | 
|---|
| 226 | void PutI1s  (int_1 const*, size_t); | 
|---|
| 227 | void PutU1   (uint_1); | 
|---|
| 228 | void PutU1s  (uint_1 const*, size_t); | 
|---|
| 229 | void PutI2   (int_2); | 
|---|
| 230 | void PutI2s  (int_2 const*, size_t); | 
|---|
| 231 | void PutU2   (uint_2); | 
|---|
| 232 | void PutU2s  (uint_2 const*, size_t); | 
|---|
| 233 | void PutI4   (int_4); | 
|---|
| 234 | void PutI4s  (int_4 const*, size_t); | 
|---|
| 235 | void PutU4   (uint_4); | 
|---|
| 236 | void PutU4s  (uint_4 const*, size_t); | 
|---|
| 237 | void PutI8   (int_8); | 
|---|
| 238 | void PutI8s  (int_8 const*, size_t); | 
|---|
| 239 | void PutU8   (uint_8); | 
|---|
| 240 | void PutU8s  (uint_8 const*, size_t); | 
|---|
| 241 | void PutLine (char const* ptr, size_t len=0); // deprecated ? | 
|---|
| 242 | void PutStr  (string const&); | 
|---|
| 243 | void PutZ4   (complex<r_4>); | 
|---|
| 244 | void PutZ4s  (complex<r_4> const*, size_t); | 
|---|
| 245 | void PutZ8   (complex<r_8>); | 
|---|
| 246 | void PutZ8s  (complex<r_8> const*, size_t); | 
|---|
| 247 |  | 
|---|
| 248 |  | 
|---|
| 249 | void   Put(char   c) {PutByte(c);} | 
|---|
| 250 | void   Put(r_4    x) {PutR4(x);} | 
|---|
| 251 | void   Put(r_8    x) {PutR8(x);} | 
|---|
| 252 | void   Put(complex<r_4>   x) {PutZ4(x);} | 
|---|
| 253 | void   Put(complex<r_8>   x) {PutZ8(x);} | 
|---|
| 254 | void   Put(uint_1 x) {PutU1(x);} | 
|---|
| 255 | void   Put(int_1  x) {PutI1(x);} | 
|---|
| 256 | void   Put(uint_2 x) {PutU2(x);} | 
|---|
| 257 | void   Put(int_2  x) {PutI2(x);} | 
|---|
| 258 | void   Put(uint_4 x) {PutU4(x);} | 
|---|
| 259 | void   Put(int_4  x) {PutI4(x);} | 
|---|
| 260 | void   Put(uint_8 x) {PutU8(x);} | 
|---|
| 261 | void   Put(int_8  x) {PutI8(x);} | 
|---|
| 262 | void   Put(r_4 const*    x, size_t n) {PutR4s(x,n);} | 
|---|
| 263 | void   Put(r_8 const*    x, size_t n) {PutR8s(x,n);} | 
|---|
| 264 | void   Put(complex<r_4> const*    x, size_t n) {PutZ4s(x,n);} | 
|---|
| 265 | void   Put(complex<r_8> const*    x, size_t n) {PutZ8s(x,n);} | 
|---|
| 266 | void   Put(uint_1 const* x, size_t n) {PutU1s(x,n);} | 
|---|
| 267 | void   Put(int_1 const*  x, size_t n) {PutI1s(x,n);} | 
|---|
| 268 | void   Put(uint_2 const* x, size_t n) {PutU2s(x,n);} | 
|---|
| 269 | void   Put(int_2 const*  x, size_t n) {PutI2s(x,n);} | 
|---|
| 270 | void   Put(uint_4 const* x, size_t n) {PutU4s(x,n);} | 
|---|
| 271 | void   Put(int_4 const*  x, size_t n) {PutI4s(x,n);} | 
|---|
| 272 | void   Put(uint_8 const* x, size_t n) {PutU8s(x,n);} | 
|---|
| 273 | void   Put(int_8 const*  x, size_t n) {PutI8s(x,n);} | 
|---|
| 274 | void   Put(string const& s) {PutStr(s);} | 
|---|
| 275 |  | 
|---|
| 276 | // Writing a list of position tag table | 
|---|
| 277 | void   PutPosTagTable(int_8 const *, size_t); | 
|---|
| 278 | void   PutPosTagTable(vector<int_8> const&); | 
|---|
| 279 |  | 
|---|
| 280 |  | 
|---|
| 281 | protected: | 
|---|
| 282 | void     Init(int endianness); | 
|---|
| 283 | void     WriteNameTagTable(); | 
|---|
| 284 | void     WriteNameTagTableV2(); | 
|---|
| 285 |  | 
|---|
| 286 | void     PutArrayTag(short datasz, size_t sz, short datatype); | 
|---|
| 287 | void     PutRawByte (char); | 
|---|
| 288 | void     PutRawUByte (unsigned char); | 
|---|
| 289 | void     PutRawI2   (int_2); | 
|---|
| 290 | void     PutRawI4   (int_4); | 
|---|
| 291 | void     PutRawI8   (int_8); | 
|---|
| 292 | void     PutRawU8   (uint_8); | 
|---|
| 293 | void     PutRawBytes(void const* ptr, size_t bytes); | 
|---|
| 294 |  | 
|---|
| 295 | // Attributs, variables | 
|---|
| 296 | RawInOutStream* s; | 
|---|
| 297 | bool _ads; // delete/close the stream at the end | 
|---|
| 298 |  | 
|---|
| 299 | bool bigEndian; | 
|---|
| 300 | }; | 
|---|
| 301 |  | 
|---|
| 302 |  | 
|---|
| 303 |  | 
|---|
| 304 | } // namespace | 
|---|
| 305 |  | 
|---|
| 306 | #endif | 
|---|