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

Last change on this file since 2477 was 2477, checked in by ansari, 22 years ago

Suite et presque fin de l'extension des fonctionalites de la persistence PPF - fonctionalite pour le swap en particulier - Reza 7 Dec 2003

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