source: Sophya/trunk/SophyaLib/BaseTools/ppfbinstream.cc@ 3277

Last change on this file since 3277 was 2805, checked in by ansari, 20 years ago

MAJ commentaires pour documentation doxygen - Reza 9 Juin 2005

File size: 44.2 KB
RevLine 
[2615]1#include "sopnamsp.h"
[2475]2#include "machdefs.h"
3#include <stdio.h>
4#include <sys/types.h>
5#include <time.h>
6#include "ppfbinstream.h"
7#include "pexceptions.h"
8#include <iostream>
9
10
[2482]11// strptime n'est pas defini sous Linux avec g++ avant gcc 3.x - Reza Mars 2000
12#if defined(OS_LINUX) && defined(__GNUG__) && (__GNUC__ < 3)
[2475]13extern "C" {
14char *strptime(const char *buf, const char *format, struct tm *tm);
15}
16#endif
17
18#define MAXTAGLEN_V2 255
19
20
21static inline void bswap8(void* p)
22{
23 uint_8 tmp = *(uint_8*)p;
24 *(uint_8*)p = ((tmp >> (7*8)) & 0x000000FF) |
25 ((tmp >> (5*8)) & 0x0000FF00) |
26 ((tmp >> (3*8)) & 0x00FF0000) |
27 ((tmp >> (1*8)) & 0xFF000000) |
28 ((tmp & 0xFF000000) << (1*8)) |
29 ((tmp & 0x00FF0000) << (3*8)) |
30 ((tmp & 0x0000FF00) << (5*8)) |
31 ((tmp & 0x000000FF) << (7*8));
32}
33
34static inline void bswap4(void* p)
35{
36 uint_4 tmp = *(uint_4*)p;
37 *(uint_4*)p = ((tmp >> 24) & 0x000000FF) |
38 ((tmp >> 8) & 0x0000FF00) |
39 ((tmp & 0x0000FF00) << 8) |
40 ((tmp & 0x000000FF) << 24);
41}
42
43static inline void bswap2(void* p)
44{
45 uint_2 tmp = *(uint_2*)p;
46 *(uint_2*)p = ((tmp >> 8) & 0x00FF) |
47 ((tmp & 0x00FF) << 8);
48}
49
[2477]50//-------------------------------------------------------------------------
51//---------------------- Classe PPFBinaryIOStream ------------------------
52//-------------------------------------------------------------------------
[2475]53
[2805]54/*!
55 \class SOPHYA::PPFBinaryIOStream
56 \ingroup BaseTools
57 Base class for SOPHYA PPF input / output stream
58*/
[2477]59
[2805]60
[2477]61PPFBinaryIOStream::PPFBinaryIOStream()
62{
63 version = 0; // PPersist(In/Out) version
64 // creationdate = time(NULL); // Date de creation du fichier
65 _nbpostag = 0; // Nb de tag de positionnement
66 _nbobjs = 0; // Nb total d'objets
67 _nbtlobjs = 0; // Nb d'objets de niveau 1
[2482]68 _nbrefs = 0; // Nb de reference d'objets
69 _maxnestlevel = 0; // Niveau maximum d'objets emboites
[2477]70}
71
72PPFBinaryIOStream::~PPFBinaryIOStream()
73{
74}
75
[2805]76//! Return the creation date/time of the associated stream as a string
[2477]77string
78PPFBinaryIOStream::CreationDateStr()
79{
80 time_t cdt = CreationDate();
81 string cdate = ctime(&cdt);
82 return(cdate);
83}
84
[2805]85//! Return a string with information about the stream (creation-date, version ...)
[2477]86string
87PPFBinaryIOStream::InfoString()
88{
89 string rs;
90 char buff[256];
91 sprintf(buff,"PPFStream Version= %d CreationDate= ", Version());
92 rs += buff;
93 rs += CreationDateStr();
[2482]94 sprintf(buff,"\n NbObjs= %ld NbTopLevObjs= %ld NbRefs= %ld MaxNest= %d ",
95 (long)NbObjects(), (long)NbTopLevelObjects(),
96 (long)NbReferences(), MaxNestedObjsLevel());
[2477]97 rs += buff;
98 sprintf(buff,"\n NbPosTag= %ld NbNameTag= %ld ", (long)NbPosTags(),
99 (long)NbNameTags());
100 rs += buff;
101 return rs;
102}
103
104
[2805]105//! Return the name tag number \b itag
[2477]106string
107PPFBinaryIOStream::GetTagName(int itag)
108{
109 if (itag<0 || itag >= (int)tags.size()) return "";
110 map<string, int_8>::iterator i = tags.begin();
111 for (int j=0; j<itag; j++) i++;
112 return((*i).first);
113}
114
115
[2805]116//! Return a reference to a vector<string> containing all name-tags associated with the stream
[2477]117static vector<string> * ret_tag_names = NULL;
118vector<string> const &
119PPFBinaryIOStream::GetNameTags()
120{
121if (ret_tag_names) delete ret_tag_names;
122ret_tag_names = new vector<string> ;
123map<string, int_8>::iterator i;
124for(i=tags.begin(); i!=tags.end(); i++) ret_tag_names->push_back((*i).first);
125return(*ret_tag_names);
126}
127
128//-------------------------------------------------------------------------
129//-------------------- Classe PPFBinaryInputStream -----------------------
130//-------------------------------------------------------------------------
131
[2805]132/*!
133 \class SOPHYA::PPFBinaryInputStream
134 \ingroup BaseTools
135 PPF Input stream implementing read operations
136*/
137
138/*! Constructor from a RawInOutStream pointer
139 \param is : pointer to RawInOutStream
140 \param ad : if true, the RawInOutStream \b is is deleted by the destructor
141 \param scan : if true, try to read the name-tags table from the end of the input stream
142*/
[2476]143PPFBinaryInputStream::PPFBinaryInputStream(RawInOutStream * is, bool ad, bool scan)
[2475]144{
[2476]145 s = is;
146 _ads = ad;
147 Init(scan);
[2475]148}
149
[2805]150/*! Constructor
151 \param flnm : input file name
152 \param scan : if true, try to read the name-tags table from the end of the input stream
153*/
[2475]154PPFBinaryInputStream::PPFBinaryInputStream(string const& flnm, bool scan)
155//
156// Constructeur. Ouvre le fichier.
157//--
158{
159 s = new RawInFileStream(flnm.c_str());
[2476]160 _ads = true;
161 Init(scan);
162}
[2475]163
[2476]164PPFBinaryInputStream::~PPFBinaryInputStream()
165{
166 if (_ads && (s!=NULL) ) delete s;
167}
168
169void
170PPFBinaryInputStream::Init(bool scan)
171{
[2475]172 // Read and check header
173
174 char rbuf[36];
175 GetRawBytes(rbuf, 32);
176 if (strncmp(rbuf,"SOS-SOPHYA-PPersistFile", 23) != 0) {
177 throw FileFormatExc("PPFBinaryInputStream::PPFBinaryInputStream bad header");
178 }
179 rbuf[32] = '\0';
180 version = atoi(rbuf+25);
181 if (version < 2) {
[2476]182 cerr << "PPFBinaryInputStream::PPFBinaryInputStream(" << FileName() << ") Version(=" << version
[2475]183 << ") < 2 not supported !" << endl;
184 throw FileFormatExc("PPFBinaryInputStream::PPFBinaryInputStream() - Unsupported (Old) Version");
185 }
186 // read endianness
187 GetRawBytes(rbuf, 32);
188 if (strncmp(rbuf,"BIG-ENDIAN",10) == 0)
189 bigEndian = true;
190 else if (strncmp(rbuf,"LITTLE-ENDIAN",13) == 0)
191 bigEndian = false;
192 else {
193 throw FileFormatExc("PPFBinaryInputStream::PPFBinaryInputStream bad header - endianness");
194 }
195
196 // read creation date
197 GetRawBytes(rbuf, 32);
198 rbuf[32] = '\0';
199 struct tm tm;
200 strptime(rbuf,"%d/%m/%Y %H:%M:%S GMT",&tm);
201 /* #else
202 sscanf(rbuf,"%2d/%2d/%4d %2d:%2d:%2d GMT",&tm.tm_mday,&tm.tm_mon,&tm.tm_year,
203 &tm.tm_hour,&tm.tm_min,&tm.tm_sec);
[2482]204 tm.tm_mon --; tm.tm_year -= 1900;
205 #endif */
[2475]206
207 creationdate = mktime(&tm);
208 seqread = true; // To flag non sequential reads
[2476]209 if (scan && s->isSeekable()) {
210 if (Version() >= 3) ReadNameTagTable();
211 else ReadNameTagTableV2();
212 }
[2475]213}
214
215
216void
[2476]217PPFBinaryInputStream::ReadNameTagTable()
[2475]218{
[2476]219 unsigned char ppstype;
220 int_8 debut;
221 debut = s->tellg();
222
223 s->seekg(-(sizeof(int_8)+1), ios::end);
[2477]224 // Lecture position NameTagTable et tag EOF
225 int_8 pos;
226 GetRawI8(pos);
[2481]227 GetRawUByte(ppstype);
[2476]228 if (ppstype != PPS_EOF)
229 throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTable() Corrupted file, no EOF tag at end of file");
230
231 // On se positionne au debut du NameTagTable
232 s->seekg(pos);
[2481]233 GetRawUByte(ppstype);
[2476]234 if (ppstype != PPS_NAMETAG_TABLE)
235 throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTable() Corrupted file PPS_NAMETAG_TABLE not found");
[2477]236 // Lecture nb de PosTag et nb d'objets dans le flot
[2482]237 int_8 stats[8] = {0,0,0,0,0,0,0,0};
238 GetI8s(stats, 8);
239 _nbpostag = stats[0];
240 _nbobjs = stats[1];
241 _nbtlobjs = stats[2];
242 _nbrefs = stats[3];
243 _maxnestlevel = stats[4];
244
[2476]245 uint_8 ttsz,it;
[2477]246 // Lecture nombre de NameTag
[2482]247 GetRawU8(ttsz);
[2477]248 if (ttsz > 0) {
249 for(it=0; it<ttsz; it++) {
250 int_8 tpos;
251 string tname;
[2482]252 GetRawI8(tpos);
[2477]253 GetStr(tname);
254 tags[tname] = tpos;
255 }
[2476]256 }
257 // On revient au debut du float, juste apres l'entete
258 s->seekg(debut);
259}
260
261void
262PPFBinaryInputStream::ReadNameTagTableV2()
263{
[2475]264 // On cherche la liste des tags, a la fin du fichier
265
266 unsigned char ppstype;
267 int_8 debut;
268 debut = s->tellg();
269
270 s->seekg(-(sizeof(int_8)+1), ios::end);
271
[2481]272 GetRawUByte(ppstype);
[2475]273 if (ppstype != PPS_EOF)
[2476]274 throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTableV2() Corrupted file, no eof entry at end of file");
[2475]275
276 int_8 pos;
277 GetRawI8(pos);
278 if (pos < 0) { // no tags
279 s->seekg(debut);
280 return;
281 }
282
283 char buffer[MAXTAGLEN_V2+1];
284 s->seekg(pos);
285 while (true) {
[2481]286 GetRawUByte(ppstype);
[2475]287 if (ppstype == PPS_EOF) break;
288
289 if (ppstype != PPS_NAMETAG_TABLE)
[2476]290 throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTableV2() Corrupted file, bad tag entry");
[2475]291
292 GetRawI8(pos);
293 int_4 len;
294 GetRawI4(len);
295 if (len > MAXTAGLEN_V2)
[2476]296 throw FileFormatExc("PPFBinaryInputStream::ReadNameTagTableV2() Corrupted file, tag name too long");
[2475]297 GetRawBytes(buffer, len);
298 buffer[len] = '\0';
299
300 tags[buffer] = pos;
301 }
302 s->seekg(debut);
303}
304
305
306bool
307PPFBinaryInputStream::GotoPositionTag(int_8 pos)
308{
309 s->seekg(pos);
[2481]310 unsigned char ppstag;
311 GetRawUByte(ppstag);
312 if (ppstag != PPS_POSTAG_MARK)
313 throw FileFormatExc("PPFBinaryInputStream::GotoPositionTag() - PPS_POSTAG_MARK not found!");
[2475]314 int_8 tpos;
315 GetRawI8(tpos);
316 if (tpos != pos)
317 throw FileFormatExc("PPFBinaryInputStream::GotoPositionTag() - Wrong tag position!");
318 return true;
319}
320
321bool
322PPFBinaryInputStream::GotoNameTag(string const& name)
323{
324 map<string, int_8>::iterator i = tags.find(name);
325 if (i == tags.end())
326 return false;
327 // throw NotFoundExc("PPFBinaryInputStream::GotoNameTag tag not found");
328 s->seekg((*i).second);
329 seqread = false;
330 // objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
331 return(true);
332}
333
334
335bool
336PPFBinaryInputStream::GotoNameTagNum(int itag)
337{
338 if (itag<0 || itag >= (int)tags.size()) return false;
339 map<string, int_8>::iterator i = tags.begin();
340 for (int j=0; j<itag; j++) i++;
341 s->seekg((*i).second);
342 seqread = false;
343 // objList.clear(); $CHECK$ EA 171199 Ne pas faire ? Reza 03/2000 ?
344 return(true);
345}
346
347
348bool
349PPFBinaryInputStream::SkipToNextObject()
350{
[2477]351 if (! s->isSeekable()) return false;
352 unsigned char ppstag=0;
353 // int kss;
354 while ((ppstag != PPS_OBJECT) && (ppstag != PPS_REFERENCE) && (ppstag != PPS_EOF)) {
355 // kss++;
356 GetRawUByte(ppstag);
357 // cout << " DBG--SkipToNextObject(" << kss << ")" << (int)ppstag << ","
358 // << (int)PPS_OBJECT << " fpos=" << s->tellg() << endl;
359 if ((ppstag != PPS_OBJECT) && (ppstag != PPS_REFERENCE) && (ppstag != PPS_EOF))
360 SkipItem(false, ppstag);
361 }
362 s->seekg(-1, ios::cur);
363 if (ppstag == PPS_OBJECT) return true;
364 else return false;
365
[2475]366}
367
368bool
[2476]369PPFBinaryInputStream::SkipNextItem()
[2475]370{
[2477]371 if (! s->isSeekable()) return false;
372 SkipItem();
[2475]373 return true;
374}
375
[2476]376char
[2485]377PPFBinaryInputStream::NextItemTag(short & datasz, size_t & asz)
[2476]378{
[2477]379 int_8 cpos;
380 cpos = s->tellg();
381
382 unsigned char ppstag=0;
383 unsigned char ppst1,ppst2,ppst3,ppst30;
384 GetRawUByte(ppstag);
385 ppst1 = ppstag&0x0f; // bits 0123
386 ppst2 = ppstag&0x30; // bits 45
387 ppst3 = ppstag&0xc0; // bits 67
388 ppst30 = ppstag&0xc1; // bits 0 67
389
[2476]390 datasz = 0;
[2477]391 asz = 0;
392
393 int_4 i4;
394 uint_8 ui8;
395
396 if ((ppst2 == 0) && (ppst3 == 0) ) {
397 switch (ppst1) {
398 case PPS_STRING :
399 GetRawI4(i4);
400 datasz = 1;
401 asz = i4;
402 break;
403
404 case PPS_NULL :
405 case PPS_OBJECT :
406 case PPS_REFERENCE :
407 case PPS_NAMETAG_MARK :
408 case PPS_POSTAG_MARK :
409 case PPS_ENDOBJECT :
410 case PPS_POSTAG_TABLE :
411 case PPS_NAMETAG_TABLE :
412 case PPS_EOF :
413 datasz = 0;
414 asz = 0;
415 break;
416
417 default :
418 throw FileFormatExc("PPFBinaryInputStream::NextItemTag() - Unexpected tag value !");
419 break;
420 }
421 }
422 else {
423 int_4 dsize = ppst1;
424 if (ppst30 == PPS_DATATYPE_COMPLEX) {
425 dsize--;
426 }
427 switch (ppst2) {
428 case PPS_SIMPLE :
429 datasz = dsize;
430 asz = 1;
431 break;
432
433 case PPS_SIMPLE_ARRAY4 :
434 GetRawI4(i4);
435 datasz = dsize;
436 asz = i4;
437 break;
438
439 case PPS_SIMPLE_ARRAY8 :
440 GetRawU8(ui8);
441 datasz = dsize;
[2481]442 asz = ui8;
[2477]443 break;
444 }
445 }
446
447 s->seekg(cpos,ios::beg);
448 return(ppstag);
[2476]449}
450
451void
[2477]452PPFBinaryInputStream::SkipItem(bool fgrdt, unsigned char itag)
[2476]453{
[2477]454 unsigned char ppstag=0;
455 unsigned char ppst1,ppst2,ppst3,ppst30;
456 uint_8 ui8;
457 int_4 i4;
458 int_8 i8;
459
460 if (fgrdt) GetRawUByte(ppstag);
461 else ppstag = itag;
462
463 ppst1 = ppstag&0x0f; // bits 0123
464 ppst2 = ppstag&0x30; // bits 45
465 ppst3 = ppstag&0xc0; // bits 67
466 ppst30 = ppstag&0xc1; // bits 0 67
467 if ((ppst2 == 0) && (ppst3 == 0) ) {
468 switch (ppst1) {
469 case PPS_NULL :
470 case PPS_NAMETAG_MARK :
471 break;
472
473 case PPS_STRING :
474 GetRawI4(i4);
475 s->seekg(i4,ios::cur);
476 break;
477
478 case PPS_OBJECT :
479 GetRawU8(ui8);
480 GetRawU8(ui8);
481 break;
482
483 case PPS_REFERENCE :
484 GetRawU8(ui8);
485 GetRawI8(i8);
486 break;
487
488 case PPS_POSTAG_MARK :
489 GetRawI8(i8);
490 break;
491
492 case PPS_ENDOBJECT :
493 GetRawU8(ui8);
494 break;
495
496 case PPS_POSTAG_TABLE :
497 GetRawI4(i4);
498 // for(int kkt=0; kkt<i4; kkt++) GetRawI8(i8);
499 s->seekg((int_8)i4*8,ios::cur);
500 break;
501
502 case PPS_NAMETAG_TABLE :
503 if (Version() < 3) {
504 GetRawI8(i8);
505 GetRawI4(i4);
506 s->seekg(i4,ios::cur);
507 }
508 else {
509 GetI8(i8); // nb pos tag
510 GetI8(i8); // nb d'objets
511 GetI8(i8); // nb objets toplevel
512 GetU8(ui8); // nb de nametag
513 for(int kt=0; kt<ui8; kt++) {
514 GetRawI4(i4);
515 s->seekg(i4,ios::cur);
516 }
517 GetI8(i8); // position debut NameTagTable
518 }
519 break;
520
521
522 case PPS_EOF :
523 if (Version() < 3) GetRawI8(i8);
524 break;
525
526 default :
527 cerr << "PPFBinaryInputStream::SkipItem() ERROR : Unexpected tag value "
528 << hex << ppstag << " At position" << s->tellg() << dec << endl;
529 throw FileFormatExc("PPFBinaryInputStream::SkipItem() - Unexpected tag value !");
530 }
531 }
532 else {
533 string dtype = "???? x";
534 int_4 dsize = ppst1;
535 int_8 dsizeskip = dsize;
536 if (ppst30 == PPS_DATATYPE_COMPLEX) {
537 dsize--;
538 dsizeskip = 2*dsize;
539 }
540
541 switch (ppst2) {
542 case PPS_SIMPLE :
543 s->seekg(dsizeskip, ios::cur);
544 break;
545
546 case PPS_SIMPLE_ARRAY4 :
547 GetRawI4(i4);
548 s->seekg(dsizeskip*(int_8)i4, ios::cur);
549 break;
550
551 case PPS_SIMPLE_ARRAY8 :
552 GetRawU8(ui8);
553 s->seekg(dsizeskip*ui8, ios::cur);
554 break;
555 }
556 }
557return;
[2476]558}
559
[2475]560//++
561// void PPFBinaryInputStream::GetByte(char& c)
562// void PPFBinaryInputStream::GetBytes(void* ptr, size_t bytes)
563// void PPFBinaryInputStream::GetR4 (r_4& result)
564// void PPFBinaryInputStream::GetR4s (r_4* tab, size_t n)
565// void PPFBinaryInputStream::GetR8 (r_8& result)
566// void PPFBinaryInputStream::GetR8s (r_8* tab, size_t n)
567// void PPFBinaryInputStream::GetI2 (int_2& result)
568// void PPFBinaryInputStream::GetI2s (int_2* tab, size_t n)
569// void PPFBinaryInputStream::GetU2 (uint_2& result)
570// void PPFBinaryInputStream::GetU2s (uint_2* tab, size_t n)
571// void PPFBinaryInputStream::GetI4 (int_4& result)
572// void PPFBinaryInputStream::GetI4s (int_4* tab, size_t n)
573// void PPFBinaryInputStream::GetU4 (uint_4& result)
574// void PPFBinaryInputStream::GetU4s (uint_4* tab, size_t n)
575// void PPFBinaryInputStream::GetI8 (int_8& result)
576// void PPFBinaryInputStream::GetI8s (int_8* tab, size_t n)
577// void PPFBinaryInputStream::GetU8 (uint_8& result)
578// void PPFBinaryInputStream::GetU8s (uint_8* tab, size_t n)
579// Lecture de données portables depuis le fichier PPersist. Pour chaque type
580// de données, on peut lire une valeur, ou un tableau de valeurs.
581// void PPFBinaryInputStream::GetLine(char* ptr, size_t len)
582// Lecture d'une ligne de texte depuis le fichier PPersist.
583//--
584
585
586void
587PPFBinaryInputStream::GetTypeTag(unsigned char& c)
588{
589 int_8 tpos;
590 c = PPS_NAMETAG_MARK;
591 while ( (c == PPS_NAMETAG_MARK) || (c == PPS_POSTAG_MARK) ) {
592 GetRawUByte(c);
593 if (c == PPS_POSTAG_MARK) GetRawI8(tpos);
594 }
595 // while (c == PPS_NAMETAG_MARK) { Il ne faut plus faire ca !
596 // objList.clear(); $CHECK$ Reza 03/2000
597 // GetRawByte(c);
598 // }
599}
600
601
602void
603PPFBinaryInputStream::GetRawByte(char& c)
604{
605 GetRawBytes(&c, 1);
606}
607
608void
609PPFBinaryInputStream::GetRawUByte(unsigned char& c)
610{
611 GetRawBytes(&c, 1);
612}
613
614void
615PPFBinaryInputStream::GetRawBytes(void* ptr, size_t bytes)
616{
617 s->read((char*)ptr, bytes);
618}
619
620void
621PPFBinaryInputStream::GetRawI2 (int_2& result)
622{
623 GetRawBytes(&result, sizeof(int_2));
624 if (bigEndian != IS_BIG_ENDIAN)
625 bswap2(&result);
626}
627
628void
629PPFBinaryInputStream::GetRawI4 (int_4& result)
630{
631 GetRawBytes(&result, sizeof(int_4));
632 if (bigEndian != IS_BIG_ENDIAN)
633 bswap4(&result);
634}
635
636void
637PPFBinaryInputStream::GetRawI8 (int_8& result)
638{
639 GetRawBytes(&result, sizeof(int_8));
640 if (bigEndian != IS_BIG_ENDIAN)
641 bswap8(&result);
642}
643
644void
645PPFBinaryInputStream::GetRawU8 (uint_8& result)
646{
647 GetRawBytes(&result, sizeof(uint_8));
648 if (bigEndian != IS_BIG_ENDIAN)
649 bswap8(&result);
650}
651
652void
653PPFBinaryInputStream::CheckTag(short datasz, short datatype)
654// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
655{
656 unsigned char ppstype;
657 GetTypeTag(ppstype);
658 if (ppstype != PPS_SIMPLE + datasz + datatype)
659 throw FileFormatExc("PPFBinaryInputStream::CheckTag bad type in ppersist file");
660}
661
662void
663PPFBinaryInputStream::CheckArrayTag(short datasz, size_t sz, short datatype)
664// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
665{
666 unsigned char ppstype;
667 GetTypeTag(ppstype);
668 size_t filesz;
669 if (sz <= 0x7fffffff) {
670 if (ppstype != PPS_SIMPLE_ARRAY4 + datasz + datatype)
671 throw FileFormatExc("PPFBinaryInputStream::CheckArrayTag bad type in ppersist file");
672 int_4 ff;
673 GetRawI4(ff); filesz=ff;
674 } else {
675 if (ppstype != PPS_SIMPLE_ARRAY8 + datasz + datatype)
676 throw FileFormatExc("PPFBinaryInputStream::CheckArrayTag bad type in ppersist file");
677 uint_8 ff;
678 GetRawU8(ff); filesz=ff;
679 }
680 if (filesz != sz)
681 throw FileFormatExc("PPFBinaryInputStream::CheckArrayTag bad array size in ppersist file");
682}
683
684void
685PPFBinaryInputStream::GetByte(char& c)
686{
687 CheckTag(1,PPS_DATATYPE_CHAR);
688 GetRawBytes(&c, 1);
689}
690
691
692void
693PPFBinaryInputStream::GetBytes(void* ptr, size_t bytes)
694{
695 CheckArrayTag(1, bytes, PPS_DATATYPE_CHAR);
696 GetRawBytes(ptr, bytes);
697}
698void
699PPFBinaryInputStream::GetR4 (r_4& result)
700{
701 CheckTag(4,PPS_DATATYPE_FLOAT);
702 GetRawBytes(&result, sizeof(r_4));
703 if (bigEndian != IS_BIG_ENDIAN)
704 bswap4(&result);
705}
706
707
708void
709PPFBinaryInputStream::GetR4s (r_4* tab, size_t n)
710{
711 CheckArrayTag(4,n,PPS_DATATYPE_FLOAT);
712 GetRawBytes(tab, n*sizeof(r_4));
713 if (bigEndian == IS_BIG_ENDIAN) return;
714
715 for (unsigned int i=0; i<n; i++)
716 bswap4(tab+i);
717
718 return;
719}
720
721void
722PPFBinaryInputStream::GetR8 (r_8& result)
723{
724 CheckTag(8,PPS_DATATYPE_FLOAT);
725 GetRawBytes(&result, sizeof(r_8));
726 if (bigEndian != IS_BIG_ENDIAN)
727 bswap8(&result);
728}
729
730void
731PPFBinaryInputStream::GetR8s (r_8* tab, size_t n)
732{
733 CheckArrayTag(8,n,PPS_DATATYPE_FLOAT);
734 GetRawBytes(tab, n*sizeof(r_8));
735 if (bigEndian == IS_BIG_ENDIAN) return;
736
737 for (unsigned int i=0; i<n; i++)
738 bswap8(tab+i);
739
740 return;
741}
742
743void
744PPFBinaryInputStream::GetI1 (int_1& result)
745{
746 CheckTag(1,PPS_DATATYPE_INTEGER);
747 GetRawBytes(&result, sizeof(int_1));
748}
749
750void
751PPFBinaryInputStream::GetI1s (int_1* tab, size_t n)
752{
753 CheckArrayTag(1,n,PPS_DATATYPE_INTEGER);
754 GetRawBytes(tab, n*sizeof(int_1));
755}
756
757void
758PPFBinaryInputStream::GetU1 (uint_1& result)
759{
760 CheckTag(1,PPS_DATATYPE_UNSIGNED);
761 GetRawBytes(&result, sizeof(uint_1));
762}
763
764void
765PPFBinaryInputStream::GetU1s (uint_1* tab, size_t n)
766{
767 CheckArrayTag(1,n,PPS_DATATYPE_UNSIGNED);
768 GetRawBytes(tab, n*sizeof(uint_1));
769}
770
771void
772PPFBinaryInputStream::GetI2 (int_2& result)
773{
774 CheckTag(2,PPS_DATATYPE_INTEGER);
775 GetRawBytes(&result, sizeof(int_2));
776 if (bigEndian != IS_BIG_ENDIAN)
777 bswap2(&result);
778}
779
780void
781PPFBinaryInputStream::GetI2s (int_2* tab, size_t n)
782{
783 CheckArrayTag(2,n,PPS_DATATYPE_INTEGER);
784 GetRawBytes(tab, n*sizeof(int_2));
785 if (bigEndian == IS_BIG_ENDIAN) return;
786
787 for (unsigned int i=0; i<n; i++)
788 bswap2(tab+i);
789
790 return;
791}
792
793void
794PPFBinaryInputStream::GetU2 (uint_2& result)
795{
796 CheckTag(2,PPS_DATATYPE_UNSIGNED);
797 GetRawBytes(&result, sizeof(uint_2));
798 if (bigEndian != IS_BIG_ENDIAN)
799 bswap2(&result);
800}
801
802void
803PPFBinaryInputStream::GetU2s (uint_2* tab, size_t n)
804{
805 CheckArrayTag(2,n,PPS_DATATYPE_UNSIGNED);
806 GetRawBytes(tab, n*sizeof(uint_2));
807 if (bigEndian == IS_BIG_ENDIAN) return;
808
809 for (unsigned int i=0; i<n; i++)
810 bswap2(tab+i);
811
812 return;
813}
814
815void
816PPFBinaryInputStream::GetI4 (int_4& result)
817{
818 CheckTag(4,PPS_DATATYPE_INTEGER);
819 GetRawBytes(&result, sizeof(int_4));
820 if (bigEndian != IS_BIG_ENDIAN)
821 bswap4(&result);
822}
823
824void
825PPFBinaryInputStream::GetI4s (int_4* tab, size_t n)
826{
827 CheckArrayTag(4,n,PPS_DATATYPE_INTEGER);
828 GetRawBytes(tab, n*sizeof(int_4));
829 if (bigEndian == IS_BIG_ENDIAN) return;
830
831 for (unsigned int i=0; i<n; i++)
832 bswap4(tab+i);
833
834 return;
835}
836
837void
838PPFBinaryInputStream::GetU4 (uint_4& result)
839{
840 CheckTag(4,PPS_DATATYPE_UNSIGNED);
841 GetRawBytes(&result, sizeof(uint_4));
842 if (bigEndian != IS_BIG_ENDIAN)
843 bswap4(&result);
844}
845
846void
847PPFBinaryInputStream::GetU4s (uint_4* tab, size_t n)
848{
849 CheckArrayTag(4,n,PPS_DATATYPE_UNSIGNED);
850 GetRawBytes(tab, n*sizeof(uint_4));
851 if (bigEndian == IS_BIG_ENDIAN) return;
852
853 for (unsigned int i=0; i<n; i++)
854 bswap4(tab+i);
855
856 return;
857}
858
859
860void
861PPFBinaryInputStream::GetI8 (int_8& result)
862{
863 CheckTag(8,PPS_DATATYPE_INTEGER);
864 GetRawBytes(&result, sizeof(int_8));
865 if (bigEndian != IS_BIG_ENDIAN)
866 bswap8(&result);
867}
868
869void
870PPFBinaryInputStream::GetI8s (int_8* tab, size_t n)
871{
872 CheckArrayTag(8,n,PPS_DATATYPE_INTEGER);
873 GetRawBytes(tab, n*sizeof(int_8));
874 if (bigEndian == IS_BIG_ENDIAN) return;
875
876 for (unsigned int i=0; i<n; i++)
877 bswap8(tab+i);
878
879 return;
880}
881
882void
883PPFBinaryInputStream::GetU8 (uint_8& result)
884{
885 CheckTag(8,PPS_DATATYPE_UNSIGNED);
886 GetRawBytes(&result, sizeof(uint_8));
887 if (bigEndian != IS_BIG_ENDIAN)
888 bswap8(&result);
889}
890
891void
892PPFBinaryInputStream::GetU8s (uint_8* tab, size_t n)
893{
894 CheckArrayTag(8,n,PPS_DATATYPE_UNSIGNED);
895 GetRawBytes(tab, n*sizeof(uint_8));
896 if (bigEndian == IS_BIG_ENDIAN) return;
897
898 for (unsigned int i=0; i<n; i++)
899 bswap8(tab+i);
900
901 return;
902}
903
904
905void
906PPFBinaryInputStream::GetLine(char* ptr, size_t len)
907{
908 string str;
909 GetStr(str);
910 strncpy(ptr, str.c_str(), len);
911 ptr[len] = '\0';
912}
913
914void
915PPFBinaryInputStream::GetStr(string& str)
916{
917 unsigned char ppstype;
918 GetTypeTag(ppstype);
919 if (ppstype != PPS_STRING)
920 throw FileFormatExc("PPFBinaryInputStream::GetStr bad type in ppersist file");
921 int_4 len;
922 GetRawI4(len);
923 char * buff = new char[len+1];
924 GetRawBytes(buff, len);
925 buff[len] = '\0';
926 str = buff;
927 delete[] buff;
928}
929
930void
931PPFBinaryInputStream::GetZ4 (complex<r_4>& result)
932{
933 CheckTag(4,PPS_DATATYPE_COMPLEX);
934 r_4 reim[2];
935 GetRawBytes(reim, 2*sizeof(r_4));
936 if (bigEndian != IS_BIG_ENDIAN) {
937 bswap4(reim);
938 bswap4(reim+1);
939 }
940 result = complex<r_4>(reim[0], reim[1]);
941}
942
943void
944PPFBinaryInputStream::GetZ4s (complex<r_4>* tab, size_t n)
945{
946 CheckArrayTag(4,n,PPS_DATATYPE_COMPLEX);
947 GetRawBytes(tab, n*2*sizeof(r_4));
948 if (bigEndian == IS_BIG_ENDIAN) return;
949
950 r_4 * p = (r_4 *)tab;
951 for (unsigned int i=0; i<n; i++) {
952 bswap4(p); p++;
953 bswap4(p); p++;
954 }
955 return;
956}
957
958void
959PPFBinaryInputStream::GetZ8 (complex<r_8>& result)
960{
961 CheckTag(8,PPS_DATATYPE_COMPLEX);
962 r_8 reim[2];
963 GetRawBytes(reim, 2*sizeof(r_8));
964 if (bigEndian != IS_BIG_ENDIAN) {
965 bswap8(reim);
966 bswap8(reim+1);
967 }
968 result = complex<r_8>(reim[0], reim[1]);
969}
970
971void
972PPFBinaryInputStream::GetZ8s (complex<r_8>* tab, size_t n)
973{
974 CheckArrayTag(8,n,PPS_DATATYPE_COMPLEX);
975 GetRawBytes(tab, n*2*sizeof(r_8));
976 if (bigEndian == IS_BIG_ENDIAN) return;
977
978 r_8 * p = (r_8 *)tab;
979 for (unsigned int i=0; i<n; i++) {
980 bswap8(p); p++;
981 bswap8(p); p++;
982 }
983 return;
984}
985
986
987void
988PPFBinaryInputStream::GetPosTagTable(int_8* ptab, size_t sz)
989{
990 unsigned char ppstype;
991 GetTypeTag(ppstype);
992 if (ppstype != PPS_POSTAG_TABLE)
993 throw FileFormatExc("PPFBinaryInputStream::GetPosTagTable bad type in ppersist stream");
994 int_4 tsz;
995 GetRawI4(tsz);
996 if (tsz != sz)
997 throw FileFormatExc("PPFBinaryInputStream::GetPosTagTable Size mismatch ");
998 for(int kk=0; kk<tsz; kk++)
999 GetRawI8(ptab[kk]);
1000 return;
1001}
1002
1003void
1004PPFBinaryInputStream::GetPosTagTable(vector<int_8>& ptab)
1005{
1006 unsigned char ppstype;
1007 GetTypeTag(ppstype);
1008 if (ppstype != PPS_POSTAG_TABLE)
1009 throw FileFormatExc("PPFBinaryInputStream::GetPosTagTable bad type in ppersist stream");
1010 ptab.clear();
1011 int_4 tsz;
1012 GetRawI4(tsz);
1013 int_8 tpos;
1014 for(int kk=0; kk<tsz; kk++) {
1015 GetRawI8(tpos);
1016 ptab.push_back(tpos);
1017 }
1018 return;
1019}
1020
[2805]1021/*! Scans the streams and prints in text format to standard output (cout) the PPF
1022 stream content.
1023 \param lev : print level (level of details) = 0,1,2,3
1024*/
[2475]1025void
1026PPFBinaryInputStream::AnalyseTags(int lev)
1027{
1028 unsigned char ppstag=0;
1029 unsigned char ppst1,ppst2,ppst3,ppst30;
1030 int_8 cpos,fsize;
1031 uint_8 ui8,cid,oid;
1032 int_4 i4;
1033 int_8 i8;
1034 char * buff;
1035 string str;
[2660]1036 // Pour indenter lors de l'impression
1037 #define _MXINDENT_ 10
1038 char * indents[_MXINDENT_+1] = {""," ", " ", " ", " ", " ",
1039 " ", " ", " ",
1040 " ", " "};
1041 int idxindent = 0;
1042 int idxind = 0;
[2475]1043 cout << "\n ---------------------------------------------------------- " << endl;
1044 cout << " PPFBinaryInputStream::AnalyseTags(Level= " << lev << ")" << endl;
1045
1046
1047 cpos = s->tellg();
1048 s->seekg(0,ios::end);
1049 fsize = s->tellg();
1050 s->seekg(cpos,ios::beg);
1051
[2477]1052 cout << " FileName= " << FileName() << endl;
[2475]1053 cout << " Version= " << Version() << " FileSize= " << fsize
1054 << " Creation Date= " << CreationDateStr() << endl;
[2477]1055 cout << " NbPosTag=" << NbPosTags() << " NbNameTag=" << tags.size()
1056 << " NbObjs=" << NbObjects() << " NbTopLevObjs=" << NbTopLevelObjects()
[2482]1057 << " NbRefs=" << NbReferences() << " MaxNest=" << MaxNestedObjsLevel()
[2477]1058 << endl << endl;
1059
[2475]1060 uint_8 totntags = 0;
1061 bool eofok = false;
1062
1063 while ( (ppstag != PPS_EOF) && (cpos < fsize) ) {
1064 cpos = s->tellg();
1065 GetRawUByte(ppstag);
1066 totntags++;
1067
1068 ppst1 = ppstag&0x0f; // bits 0123
1069 ppst2 = ppstag&0x30; // bits 45
1070 ppst3 = ppstag&0xc0; // bits 67
1071 ppst30 = ppstag&0xc1; // bits 0 67
1072 if ((ppst2 == 0) && (ppst3 == 0) ) {
1073 switch (ppst1) {
1074
1075 case PPS_NULL :
[2660]1076 if (lev > 1) cout << indents[idxindent]
1077 << "<PPS_NULL> tag at position " << hex << cpos << dec << endl;
[2475]1078 break;
1079
1080 case PPS_STRING :
1081 GetRawI4(i4);
[2660]1082 if (lev > 1) cout << indents[idxindent]
1083 << "<PPS_STRING> tag at position " << hex << cpos << dec
[2475]1084 << " Length=" << i4 << endl;
1085 s->seekg(i4,ios::cur);
1086 break;
1087
1088 case PPS_OBJECT :
1089 GetRawU8(cid);
1090 GetRawU8(oid);
[2660]1091 cout << indents[idxindent]
1092 << "<PPS_OBJECT> tag at position " << hex << cpos << " ClassId= " << cid
[2475]1093 << " ObjectId= " << oid << dec << endl;
[2660]1094 idxind++;
1095 idxindent = (idxind <= _MXINDENT_) ? idxind : _MXINDENT_;
[2475]1096 break;
1097
1098 case PPS_REFERENCE :
1099 GetRawU8(oid);
1100 GetRawI8(i8);
[2660]1101 cout << indents[idxindent]
1102 << "<PPS_REFERENCE> tag at position " << hex << cpos << " ObjectId= "
[2475]1103 << oid << " OrigPos=" << i8 << dec << endl;
1104 break;
1105
1106 case PPS_NAMETAG_MARK :
[2660]1107 cout << indents[idxindent]
1108 << "<PPS_NAMETAG_MARK> tag at position " << hex << cpos << dec << endl;
[2475]1109 break;
1110
1111 case PPS_POSTAG_MARK :
1112 GetRawI8(i8);
[2660]1113 cout << indents[idxindent]
1114 << "<PPS_POSTAG_MARK> tag at position " << hex << cpos
[2475]1115 << " TPos=" << i8 << dec << endl;
1116 break;
1117
1118 case PPS_ENDOBJECT :
1119 GetRawU8(oid);
[2664]1120 idxind--;
1121 idxindent = (idxind >= 0) ? idxind : 0;
[2660]1122 cout << indents[idxindent]
1123 << "<PPS_ENDOBJECT> tag at position " << hex << cpos << " ObjectId= "
[2475]1124 << oid << dec << endl;
1125 break;
1126
1127 case PPS_POSTAG_TABLE :
1128 GetRawI4(i4);
1129 for(int kkt=0; kkt<i4; kkt++) GetRawI8(i8);
[2660]1130 cout << indents[idxindent]
1131 << "<PPS_POSTAG_TABLE> tag at position " << hex << cpos << dec << endl;
[2475]1132 break;
1133
1134 case PPS_NAMETAG_TABLE :
[2477]1135 if (Version() < 3) {
1136 GetRawI8(i8);
1137 GetRawI4(i4);
1138 buff = new char[i4+1];
1139 GetRawBytes(buff, i4);
1140 buff[i4] = '\0'; str = buff;
1141 delete[] buff;
[2660]1142 cout << indents[idxindent]
1143 << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec
[2477]1144 << " Name= " << str << endl;
1145 }
1146 else {
[2660]1147 cout << indents[idxindent]
1148 << "<PPS_NAMETAG_TABLE> tag at position " << hex << cpos << dec << endl;
[2482]1149 int_8 stats[8];
1150 GetI8s(stats,8);
1151 GetRawU8(ui8); // nb de nametag
[2477]1152 for(int kt=0; kt<ui8; kt++) {
1153 string tname;
[2482]1154 GetRawI8(i8);
[2477]1155 GetStr(tname);
1156 if (lev > 0)
1157 cout << "<PPS_NAMETAG_ENTRY> NameTag=" << tname
1158 << " NameTagMark Position=" << hex << i8 << dec << endl;
1159 }
1160 GetRawI8(i8); // position debut NameTagTable
1161 }
[2475]1162 break;
1163
1164 case PPS_EOF :
[2477]1165 if (Version() < 3) GetRawI8(i8);
[2660]1166 cout << indents[idxindent]
1167 << "<PPS_EOF> tag at position " << hex << cpos
[2475]1168 << " TagPos=" << i8 << dec << endl;
1169 eofok = true;
1170 break;
1171
1172 default :
1173 cerr << " ERROR : Unexpected tag value " << hex << ppstag
1174 << " At position" << cpos << dec << endl;
1175 throw FileFormatExc("PPFBinaryInputStream::AnalyseTags() - Unexpected tag value !");
1176 }
1177 }
1178 else {
1179 string dtype = "???? x";
1180 if (ppst30 == PPS_DATATYPE_COMPLEX) dtype = "COMPLEX x";
1181 else if (ppst3 == PPS_DATATYPE_CHAR) dtype = "CHAR x";
1182 else if (ppst3 == PPS_DATATYPE_FLOAT) dtype = "FLOAT x";
1183 else if (ppst3 == PPS_DATATYPE_INTEGER) dtype = "INTEGER x";
1184 else if (ppst3 == PPS_DATATYPE_UNSIGNED) dtype = "UNSIGNED x";
1185 int_4 dsize = ppst1;
[2477]1186 int_8 dsizeskip = dsize;
[2475]1187 if (ppst30 == PPS_DATATYPE_COMPLEX) {
1188 dsize--;
1189 dsizeskip = 2*dsize;
1190 }
1191 char sb[16];
1192 sprintf(sb, "%d", dsize);
1193 dtype += sb;
1194
1195 switch (ppst2) {
1196
1197 case PPS_SIMPLE :
[2660]1198 if (lev > 2) cout << indents[idxindent]
1199 << "<PPS_SIMPLE> tag at position " << hex << cpos << dec
[2475]1200 << " DataType=" << dtype << endl;
1201 s->seekg(dsizeskip, ios::cur);
1202 break;
1203
1204 case PPS_SIMPLE_ARRAY4 :
1205 GetRawI4(i4);
[2660]1206 if (lev > 0) cout << indents[idxindent]
1207 << "<PPS_SIMPLE_ARRAY4> tag at position " << hex << cpos << dec
[2475]1208 << " DataType=" << dtype << " NElts= " << i4 << endl;
[2477]1209 s->seekg(dsizeskip*(int_8)i4, ios::cur);
[2475]1210 break;
1211
1212 case PPS_SIMPLE_ARRAY8 :
1213 GetRawU8(ui8);
[2660]1214 if (lev > 0) cout << indents[idxindent]
1215 << "<PPS_SIMPLE_ARRAY8> tag at position " << hex << cpos << dec
[2475]1216 << " DataType=" << dtype << " NElts= " << ui8 << endl;
[2477]1217 s->seekg(dsizeskip*ui8, ios::cur);
[2475]1218 break;
1219 }
1220 }
1221 }
1222 if (!eofok)
1223 throw FileFormatExc("PPFBinaryInputStream::AnalyseTags() - Not found <PPS_EOF> tag ");
1224
1225 cout << " PPFBinaryInputStream::AnalyseTags() - End - Total Number of Tags= " << totntags << endl;
1226 cout << " ---------------------------------------------------------- \n" << endl;
1227 return;
1228}
1229
1230
[2477]1231//-------------------------------------------------------------------------
1232//------------------- Classe PPFBinaryOutputStream -----------------------
1233//-------------------------------------------------------------------------
1234
1235
[2475]1236//++
1237// Class POutPersist
1238// Lib Outils++
1239// include ppersist.h
1240//
1241// Fichier d'objets persistants, en écriture.
1242//--
1243
1244
1245//++
1246// POutPersist(string const& flnm, int endianness = PPersist::PPS_NATIVE)
1247//
1248// Crée un nouveau fichier ppersist. Par défaut, il est petit=boutien
1249// sur machines petit-boutiennes, et gros-boutien sur machines
1250// gros-boutiennes. On peut explicitement spécifier PPersist::PPS_LITTLE_ENDIAN
1251// ou PPersist::PPS_BIG_ENDIAN.
1252//--
1253
[2805]1254/*!
1255 \class SOPHYA::PPFBinaryInputStream
1256 \ingroup BaseTools
1257 PPF output stream implementing write operations. The byte-ordering (endianess)
1258 of the output stream can be selected at creation. By default, the native endianness
1259 of the machine is used.
1260*/
1261
1262/*! Constructor from a RawInOutStream pointer
1263 \param os : pointer to RawInOutStream
1264 \param ad : if true, the RawInOutStream \b os is deleted by the destructor
1265 \param endianness : Endianness selector PPS_NATIVE PPS_LITTLE_ENDIAN PPS_BIG_ENDIAN
1266*/
[2476]1267PPFBinaryOutputStream::PPFBinaryOutputStream(RawInOutStream* os, bool ad, int endianness)
[2475]1268{
[2476]1269 s = os;
1270 _ads = ad;
1271 Init(endianness);
[2475]1272}
1273
[2805]1274/*! Constructor
1275 \param flnm : output file name
1276 \param endianness : Endianness selector PPS_NATIVE PPS_LITTLE_ENDIAN PPS_BIG_ENDIAN
1277*/
[2475]1278PPFBinaryOutputStream::PPFBinaryOutputStream(string const& flnm, int endianness)
1279{
[2476]1280 // Output stream creation
1281 s = new RawOutFileStream(flnm.c_str());
1282 _ads = true;
1283 Init(endianness);
1284}
1285
1286PPFBinaryOutputStream::~PPFBinaryOutputStream()
1287{
1288 WriteNameTagTable();
1289 if (_ads && (s != NULL)) delete s; // Close the stream
1290}
1291
1292void
1293PPFBinaryOutputStream::Init(int endianness)
1294{
[2475]1295 if (endianness == -1)
1296 bigEndian = IS_BIG_ENDIAN;
1297 else
1298 bigEndian = endianness;
1299
1300 version = 3;
1301 // Header
1302 PutRawBytes("SOS-SOPHYA-PPersistFile V3 ",32);
1303 PutRawBytes(bigEndian
1304 ? "BIG-ENDIAN "
1305 : "LITTLE-ENDIAN ",32);
1306
1307// ---- GMT creation date of the file
1308 time_t tm = time(NULL);
[2477]1309 creationdate = tm;
[2475]1310 char datestring[33];
1311 int l=strftime(datestring,32,"%d/%m/%Y %H:%M:%S GMT",gmtime(&tm));
1312 for(int i=l; i<32; i++) datestring[i] = ' ';
1313 datestring[32] = '\0';
1314 PutRawBytes(datestring, 32);
1315}
1316
[2476]1317void
1318PPFBinaryOutputStream::WriteNameTagTable()
1319{
[2477]1320 int_8 tagPos;
1321 tagPos = s->tellp();
1322 PutRawUByte(PPS_NAMETAG_TABLE); // NameTagTable tag
1323 // Ecriture nb de PosTag et nb d'objets dans le flot
[2482]1324 int_8 stats[8] = {0,0,0,0,0,0,0,0};
1325 stats[0] = _nbpostag;
1326 stats[1] = _nbobjs;
1327 stats[2] = _nbtlobjs;
1328 stats[3] = _nbrefs;
1329 stats[4] = _maxnestlevel;
1330 PutI8s(stats, 8);
[2477]1331 // Ecriture nb de tag et les tags
[2482]1332 PutRawU8((uint_8)tags.size()); // Number of tags
[2477]1333 if (tags.size() > 0) {
[2476]1334 for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
1335 int_8 pos = (*i).second;
[2482]1336 PutRawI8(pos);
[2476]1337 PutStr((*i).first);
1338 }
1339 }
[2477]1340 PutRawI8(tagPos);
1341 PutRawUByte(PPS_EOF);
1342 return;
[2476]1343}
1344
1345void
1346PPFBinaryOutputStream::WriteNameTagTableV2()
[2475]1347{
1348 if (tags.size() == 0) {
1349 PutRawUByte(PPS_EOF);
1350 PutRawI8(-1);
1351 } else {
1352 int_8 tagPos;
1353 tagPos = s->tellp();
1354 for (map<string,int_8>::iterator i = tags.begin(); i != tags.end(); i++) {
1355 string name = (*i).first;
1356 int_8 pos = (*i).second;
1357 PutRawUByte(PPS_NAMETAG_TABLE); // This is a tag
1358 PutRawI8(pos); // position of previous tag
1359 PutRawI4(name.length()); // length of the name
1360 PutRawBytes(name.c_str(), name.length()); // name, without final "0".
1361 }
1362 PutRawUByte(PPS_EOF);
1363 PutRawI8(tagPos);
1364 }
1365
1366}
1367
[2476]1368
[2475]1369int_8
1370PPFBinaryOutputStream::WritePositionTag()
1371{
1372 int_8 tagpos;
1373 tagpos = s->tellp();
1374 PutRawByte(PPS_POSTAG_MARK);
[2481]1375 PutRawI8(tagpos);
[2477]1376 _nbpostag++; // Compteur de nombre de tags
[2475]1377 return(tagpos);
1378}
1379
1380void
1381PPFBinaryOutputStream::WriteNameTag(string const& name)
1382{
1383 // if (name.length() > MAXTAGLEN_V2)
1384 // throw ParmError("PPFBinaryOutputStream::WriteNameTag tag name too long");
1385
1386 if (tags.find(name) != tags.end())
1387 throw DuplicateIdExc("PPFBinaryOutputStream::WriteNameTag duplicate tag name");
1388
1389 // Get current file position
1390 int_8 tagPos;
1391 tagPos = s->tellp();
1392
1393 tags[name] = tagPos;
1394 PutRawUByte(PPS_NAMETAG_MARK); // This is a tag
1395 // objList.clear(); // $CHECK$ EA 171199 - Ne pas faire ? Reza 03/2000
1396}
1397
1398//++
1399// void PPFBinaryOutputStream::PutByte(char& c)
1400// void PPFBinaryOutputStream::PutBytes(void const* ptr, size_t bytes)
1401// void PPFBinaryOutputStream::PutR4 (r_4 result)
1402// void PPFBinaryOutputStream::PutR4s (r_4 const* tab, size_t n)
1403// void PPFBinaryOutputStream::PutR8 (r_8 result)
1404// void PPFBinaryOutputStream::PutR8s (r_8 const* tab, size_t n)
1405// void PPFBinaryOutputStream::PutI2 (int_2 result)
1406// void PPFBinaryOutputStream::PutI2s (int_2 const* tab, size_t n)
1407// void PPFBinaryOutputStream::PutU2 (uint_2 result)
1408// void PPFBinaryOutputStream::PutU2s (uint_2 const* tab, size_t n)
1409// void PPFBinaryOutputStream::PutI4 (int_4 result)
1410// void PPFBinaryOutputStream::PutI4s (int_4 const* tab, size_t n)
1411// void PPFBinaryOutputStream::PutU4 (uint_4 result)
1412// void PPFBinaryOutputStream::PutU4s (uint_4 const* tab, size_t n)
1413// void PPFBinaryOutputStream::PutI8 (int_8 result)
1414// void PPFBinaryOutputStream::PutI8s (int_8 const* tab, size_t n)
1415// void PPFBinaryOutputStream::PutU8 (uint_8 result)
1416// void PPFBinaryOutputStream::PutU8s (uint_8 const* tab, size_t n)
1417// void PPFBinaryOutputStream::PutStr (string const&)
1418// Ecriture de données portables.. Pour chaque type
1419// de données, on peut écrire une valeur, ou un tableau de valeurs.
1420// void PPFBinaryOutputStream::PutLine(char const* ptr, size_t len)
1421// Ecriture d'une ligne de texte dans le fichier PPersist.
1422//--
1423
1424
1425
1426
1427void
1428PPFBinaryOutputStream::PutRawBytes(void const* ptr, size_t bytes)
1429{
1430 s->write((char const*)ptr, bytes);
1431}
1432
1433void
1434PPFBinaryOutputStream::PutRawByte(char c)
1435{
1436 PutRawBytes(&c, 1);
1437}
1438
1439void
1440PPFBinaryOutputStream::PutRawUByte(unsigned char c)
1441{
1442 PutRawBytes(&c, 1);
1443}
1444
1445void
1446PPFBinaryOutputStream::PutRawI2 (int_2 val)
1447{
1448 if (bigEndian != IS_BIG_ENDIAN)
1449 bswap2(&val);
1450
1451 PutRawBytes(&val, sizeof(int_2));
1452}
1453
1454void
1455PPFBinaryOutputStream::PutRawI4 (int_4 val)
1456{
1457 if (bigEndian != IS_BIG_ENDIAN)
1458 bswap4(&val);
1459
1460 PutRawBytes(&val, sizeof(int_4));
1461}
1462
1463void
1464PPFBinaryOutputStream::PutRawI8 (int_8 val)
1465{
1466 if (bigEndian != IS_BIG_ENDIAN)
1467 bswap8(&val);
1468
1469 PutRawBytes(&val, sizeof(int_8));
1470}
1471
1472void
1473PPFBinaryOutputStream::PutRawU8 (uint_8 val)
1474{
1475 if (bigEndian != IS_BIG_ENDIAN)
1476 bswap8(&val);
1477
1478 PutRawBytes(&val, sizeof(uint_8));
1479}
1480
1481void
1482PPFBinaryOutputStream::PutArrayTag(short datasz, size_t sz, short datatype)
1483// datatype = PPS_DATATYPE_CHAR or PPS_DATATYPE_FLOAT or PPS_DATATYPE_INTEGER or PPS_DATATYPE_UNSIGNED
1484{
1485 if (sz <= 0x7fffffff) {
1486 PutRawUByte(PPS_SIMPLE_ARRAY4 + datasz + datatype);
1487 PutRawI4(sz);
1488 } else {
1489 PutRawUByte(PPS_SIMPLE_ARRAY8 + datasz + datatype);
1490 PutRawU8(sz);
1491 }
1492}
1493
1494void
1495PPFBinaryOutputStream::PutByte(char c)
1496{
1497 PutRawByte(PPS_SIMPLE + 1 + PPS_DATATYPE_CHAR);
1498 PutRawBytes(&c, 1);
1499}
1500
1501
1502
1503void
1504PPFBinaryOutputStream::PutBytes(void const* ptr, size_t bytes)
1505{
1506 PutArrayTag(1, bytes, PPS_DATATYPE_CHAR);
1507 PutRawBytes(ptr, bytes);
1508}
1509
1510void
1511PPFBinaryOutputStream::PutR4 (r_4 val)
1512{
1513 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_FLOAT);
1514
1515 if (bigEndian != IS_BIG_ENDIAN)
1516 bswap4(&val);
1517
1518 PutRawBytes(&val, sizeof(r_4));
1519}
1520
1521void
1522PPFBinaryOutputStream::PutR4s (r_4 const* tab, size_t n)
1523{
1524 PutArrayTag(4, n, PPS_DATATYPE_FLOAT);
1525
1526 if (bigEndian == IS_BIG_ENDIAN) {
1527 PutRawBytes(tab, n*sizeof(r_4));
1528 } else {
1529 for (unsigned int i=0; i<n; i++) {
1530 r_4 val = tab[i];
1531 bswap4(&val);
1532 PutRawBytes(&val, sizeof(r_4));
1533 }
1534 }
1535}
1536
1537void
1538PPFBinaryOutputStream::PutR8 (r_8 val)
1539{
1540 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_FLOAT);
1541
1542 if (bigEndian != IS_BIG_ENDIAN)
1543 bswap8(&val);
1544
1545 PutRawBytes(&val, sizeof(r_8));
1546}
1547
1548void
1549PPFBinaryOutputStream::PutR8s (r_8 const* tab, size_t n)
1550{
1551 PutArrayTag(8, n, PPS_DATATYPE_FLOAT);
1552
1553 if (bigEndian == IS_BIG_ENDIAN) {
1554 PutRawBytes(tab, n*sizeof(r_8));
1555 } else {
1556 for (unsigned int i=0; i<n; i++) {
1557 r_8 val = tab[i];
1558 bswap8(&val);
1559 PutRawBytes(&val, sizeof(r_8));
1560 }
1561 }
1562}
1563
1564void
1565PPFBinaryOutputStream::PutI1 (int_1 val)
1566{
1567 PutRawUByte(PPS_SIMPLE + 1 + PPS_DATATYPE_INTEGER);
1568 PutRawBytes(&val, sizeof(int_1));
1569}
1570
1571void
1572PPFBinaryOutputStream::PutI1s (int_1 const* tab, size_t n)
1573{
1574 PutArrayTag(1, n, PPS_DATATYPE_INTEGER);
1575 PutRawBytes(tab, n*sizeof(int_1));
1576}
1577
1578void
1579PPFBinaryOutputStream::PutU1 (uint_1 val)
1580{
1581 PutRawUByte(PPS_SIMPLE + 1 + PPS_DATATYPE_UNSIGNED);
1582 PutRawBytes(&val, sizeof(uint_1));
1583}
1584
1585void
1586PPFBinaryOutputStream::PutU1s (uint_1 const* tab, size_t n)
1587{
1588 PutArrayTag(1, n, PPS_DATATYPE_UNSIGNED);
1589 PutRawBytes(tab, n*sizeof(uint_1));
1590}
1591
1592void
1593PPFBinaryOutputStream::PutI2 (int_2 val)
1594{
1595 PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_INTEGER);
1596
1597 if (bigEndian != IS_BIG_ENDIAN)
1598 bswap2(&val);
1599
1600 PutRawBytes(&val, sizeof(int_2));
1601}
1602
1603void
1604PPFBinaryOutputStream::PutI2s (int_2 const* tab, size_t n)
1605{
1606 PutArrayTag(2, n, PPS_DATATYPE_INTEGER);
1607
1608 if (bigEndian == IS_BIG_ENDIAN) {
1609 PutRawBytes(tab, n*sizeof(int_2));
1610 } else {
1611 for (unsigned int i=0; i<n; i++) {
1612 int_2 val = tab[i];
1613 bswap2(&val);
1614 PutRawBytes(&val, sizeof(int_2));
1615 }
1616 }
1617}
1618
1619void
1620PPFBinaryOutputStream::PutU2 (uint_2 val)
1621{
1622 PutRawUByte(PPS_SIMPLE + 2 + PPS_DATATYPE_UNSIGNED);
1623
1624 if (bigEndian != IS_BIG_ENDIAN)
1625 bswap2(&val);
1626
1627 PutRawBytes(&val, sizeof(uint_2));
1628}
1629
1630void
1631PPFBinaryOutputStream::PutU2s (uint_2 const* tab, size_t n)
1632{
1633 PutArrayTag(2, n, PPS_DATATYPE_UNSIGNED);
1634
1635 if (bigEndian == IS_BIG_ENDIAN) {
1636 PutRawBytes(tab, n*sizeof(uint_2));
1637 } else {
1638 for (unsigned int i=0; i<n; i++) {
1639 uint_2 val = tab[i];
1640 bswap2(&val);
1641 PutRawBytes(&val, sizeof(uint_2));
1642 }
1643 }
1644}
1645
1646void
1647PPFBinaryOutputStream::PutI4 (int_4 val)
1648{
1649 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_INTEGER);
1650
1651 if (bigEndian != IS_BIG_ENDIAN)
1652 bswap4(&val);
1653
1654 PutRawBytes(&val, sizeof(int_4));
1655}
1656
1657void
1658PPFBinaryOutputStream::PutI4s (int_4 const* tab, size_t n)
1659{
1660 PutArrayTag(4, n, PPS_DATATYPE_INTEGER);
1661
1662 if (bigEndian == IS_BIG_ENDIAN) {
1663 PutRawBytes(tab, n*sizeof(int_4));
1664 } else {
1665 for (unsigned int i=0; i<n; i++) {
1666 int_4 val = tab[i];
1667 bswap4(&val);
1668 PutRawBytes(&val, sizeof(int_4));
1669 }
1670 }
1671}
1672
1673void
1674PPFBinaryOutputStream::PutU4 (uint_4 val)
1675{
1676 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_UNSIGNED);
1677
1678 if (bigEndian != IS_BIG_ENDIAN)
1679 bswap4(&val);
1680
1681 PutRawBytes(&val, sizeof(uint_4));
1682}
1683
1684void
1685PPFBinaryOutputStream::PutU4s (uint_4 const* tab, size_t n)
1686{
1687 PutArrayTag(4, n, PPS_DATATYPE_UNSIGNED);
1688
1689 if (bigEndian == IS_BIG_ENDIAN) {
1690 PutRawBytes(tab, n*sizeof(uint_4));
1691 } else {
1692 for (unsigned int i=0; i<n; i++) {
1693 uint_4 val = tab[i];
1694 bswap4(&val);
1695 PutRawBytes(&val, sizeof(uint_4));
1696 }
1697 }
1698}
1699
1700void
1701PPFBinaryOutputStream::PutI8 (int_8 val)
1702{
1703 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_INTEGER);
1704
1705 if (bigEndian != IS_BIG_ENDIAN)
1706 bswap8(&val);
1707
1708 PutRawBytes(&val, sizeof(int_8));
1709}
1710
1711void
1712PPFBinaryOutputStream::PutI8s (int_8 const* tab, size_t n)
1713{
1714 PutArrayTag(8, n, PPS_DATATYPE_INTEGER);
1715
1716 if (bigEndian == IS_BIG_ENDIAN) {
1717 PutRawBytes(tab, n*sizeof(int_8));
1718 } else {
1719 for (unsigned int i=0; i<n; i++) {
1720 int_8 val = tab[i];
1721 bswap8(&val);
1722 PutRawBytes(&val, sizeof(int_8));
1723 }
1724 }
1725}
1726
1727void
1728PPFBinaryOutputStream::PutU8 (uint_8 val)
1729{
1730 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_UNSIGNED);
1731
1732 if (bigEndian != IS_BIG_ENDIAN)
1733 bswap8(&val);
1734
1735 PutRawBytes(&val, sizeof(uint_8));
1736}
1737
1738void
1739PPFBinaryOutputStream::PutU8s (uint_8 const* tab, size_t n)
1740{
1741 PutArrayTag(8, n, PPS_DATATYPE_UNSIGNED);
1742
1743 if (bigEndian == IS_BIG_ENDIAN) {
1744 PutRawBytes(tab, n*sizeof(uint_8));
1745 } else {
1746 for (unsigned int i=0; i<n; i++) {
1747 uint_8 val = tab[i];
1748 bswap8(&val);
1749 PutRawBytes(&val, sizeof(uint_8));
1750 }
1751 }
1752}
1753
1754void
1755PPFBinaryOutputStream::PutStr(string const& str)
1756{
1757 PutRawUByte(PPS_STRING);
1758 PutRawI4(str.length());
1759 PutRawBytes(str.c_str(), str.length());
1760}
1761
1762void
1763PPFBinaryOutputStream::PutLine(char const* ptr, size_t len)
1764{
1765 string str = ptr;
1766 PutStr(str);
1767}
1768
1769
1770void
1771PPFBinaryOutputStream::PutZ4 (complex<r_4> val)
1772{
1773 PutRawUByte(PPS_SIMPLE + 4 + PPS_DATATYPE_COMPLEX);
1774 r_4 reim[2];
1775 reim[0] = val.real();
1776 reim[1] = val.imag();
1777 if (bigEndian != IS_BIG_ENDIAN) {
1778 bswap4(reim);
1779 bswap4(reim+1);
1780 }
1781 PutRawBytes(reim, 2*sizeof(r_4));
1782}
1783
1784void
1785PPFBinaryOutputStream::PutZ4s (complex<r_4> const* tab, size_t n)
1786{
1787 PutArrayTag(4, n, PPS_DATATYPE_COMPLEX);
1788
1789 if (bigEndian == IS_BIG_ENDIAN) {
1790 PutRawBytes(tab, n*2*sizeof(r_4));
1791 } else {
1792 for (unsigned int i=0; i<n; i++) {
1793 r_4 reim[2];
1794 reim[0] = tab[i].real();
1795 reim[1] = tab[i].imag();
1796 bswap4(reim);
1797 bswap4(reim+1);
1798 PutRawBytes(reim, 2*sizeof(r_4));
1799 }
1800 }
1801}
1802
1803void
1804PPFBinaryOutputStream::PutZ8 (complex<r_8> val)
1805{
1806 PutRawUByte(PPS_SIMPLE + 8 + PPS_DATATYPE_COMPLEX);
1807 r_8 reim[2];
1808 reim[0] = val.real();
1809 reim[1] = val.imag();
1810 if (bigEndian != IS_BIG_ENDIAN) {
1811 bswap8(reim);
1812 bswap8(reim+1);
1813 }
1814 PutRawBytes(reim, 2*sizeof(r_8));
1815}
1816
1817void
1818PPFBinaryOutputStream::PutZ8s (complex<r_8> const* tab, size_t n)
1819{
1820 PutArrayTag(8, n, PPS_DATATYPE_COMPLEX);
1821
1822 if (bigEndian == IS_BIG_ENDIAN) {
1823 PutRawBytes(tab, n*2*sizeof(r_8));
1824 } else {
1825 for (unsigned int i=0; i<n; i++) {
1826 r_8 reim[2];
1827 reim[0] = tab[i].real();
1828 reim[1] = tab[i].imag();
1829 bswap8(reim);
1830 bswap8(reim+1);
1831 PutRawBytes(reim, 2*sizeof(r_8));
1832 }
1833 }
1834}
1835
1836void
1837PPFBinaryOutputStream::PutPosTagTable(int_8 const * ptab, size_t sz)
1838{
1839 PutRawUByte(PPS_POSTAG_TABLE);
1840 int_4 tsz = sz;
1841 PutRawI4(tsz);
1842 for(int kk=0; kk<tsz; kk++)
1843 PutRawI8(ptab[kk]);
1844 return;
1845}
1846
1847void
1848PPFBinaryOutputStream::PutPosTagTable(vector<int_8> const& ptab)
1849{
1850 PutRawUByte(PPS_POSTAG_TABLE);
1851 int_4 tsz = ptab.size();
1852 PutRawI4(tsz);
1853 for(int kk=0; kk<tsz; kk++)
1854 PutRawI8(ptab[kk]);
1855 return;
1856}
1857
Note: See TracBrowser for help on using the repository browser.