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

Last change on this file since 3722 was 3619, checked in by cmv, 16 years ago

add various #include<> for g++ 4.3 (jaunty 9.04), cmv 05/05/2009

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