| 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
 | 
|---|