45784601e0181d3922f32a21a518c02c19626757
[occt.git] / src / FSD / FSD_BinaryFile.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <FSD_BinaryFile.hxx>
17 #include <OSD.hxx>
18 #include <OSD_OpenFile.hxx>
19 #include <Storage_BaseDriver.hxx>
20 #include <Storage_StreamExtCharParityError.hxx>
21 #include <Storage_StreamFormatError.hxx>
22 #include <Storage_StreamTypeMismatchError.hxx>
23 #include <Storage_StreamWriteError.hxx>
24 #include <TCollection_AsciiString.hxx>
25 #include <TCollection_ExtendedString.hxx>
26 #include <Standard_Assert.hxx>
27
28 const Standard_CString MAGICNUMBER = "BINFILE";
29
30 //=======================================================================
31 //function : FSD_BinaryFile
32 //purpose  : 
33 //=======================================================================
34
35 FSD_BinaryFile::FSD_BinaryFile() :
36 myStream(0L)
37 {
38   myHeader.testindian  = -1;
39   myHeader.binfo       = -1;
40   myHeader.einfo       = -1;
41   myHeader.bcomment    = -1;
42   myHeader.ecomment    = -1;
43   myHeader.btype       = -1;
44   myHeader.etype       = -1;
45   myHeader.broot       = -1;
46   myHeader.eroot       = -1;
47   myHeader.bref        = -1;
48   myHeader.eref        = -1;
49   myHeader.bdata       = -1;
50   myHeader.edata       = -1;
51 }
52
53 //=======================================================================
54 //function : IsGoodFileType
55 //purpose  : INFO SECTION
56 //           write
57 //=======================================================================
58
59 Storage_Error FSD_BinaryFile::IsGoodFileType(const TCollection_AsciiString& aName)
60 {
61   FSD_BinaryFile      f;
62   Storage_Error s;
63
64   s = f.Open(aName,Storage_VSRead);
65
66   if (s == Storage_VSOk) {
67     TCollection_AsciiString l;
68     Standard_Size        len = strlen(FSD_BinaryFile::MagicNumber());
69
70     f.ReadChar(l,len);
71
72     f.Close();
73
74     if (strncmp(FSD_BinaryFile::MagicNumber(),l.ToCString(),len) != 0) {
75       s = Storage_VSFormatError;
76     }
77   }
78
79   return s;
80 }
81
82 //=======================================================================
83 //function : Open
84 //purpose  : 
85 //=======================================================================
86
87 Storage_Error FSD_BinaryFile::Open(const TCollection_AsciiString& aName,const Storage_OpenMode aMode)
88 {
89   Storage_Error result = Storage_VSOk;
90
91   SetName(aName);
92
93   if (OpenMode() == Storage_VSNone) {
94     if (aMode == Storage_VSRead) {
95       myStream = OSD_OpenFile(aName.ToCString(),"rb");
96     }
97     else if (aMode == Storage_VSWrite) {
98       myStream = OSD_OpenFile(aName.ToCString(),"wb");
99     }
100     else if (aMode == Storage_VSReadWrite) {
101       myStream = OSD_OpenFile(aName.ToCString(),"w+b");
102     }
103     
104     if (myStream == 0L) {
105       result = Storage_VSOpenError;
106     }
107     else {
108       SetOpenMode(aMode);
109     }
110   }
111   else {
112     result = Storage_VSAlreadyOpen;
113   }
114
115   return result;
116 }
117
118 //=======================================================================
119 //function : IsEnd
120 //purpose  : 
121 //=======================================================================
122
123 Standard_Boolean FSD_BinaryFile::IsEnd()
124 {
125   return (feof(myStream) != 0);
126 }
127
128 //=======================================================================
129 //function : Close
130 //purpose  : 
131 //=======================================================================
132
133 Storage_Error FSD_BinaryFile::Close()
134 {
135   Storage_Error result = Storage_VSOk;
136
137   if (OpenMode() != Storage_VSNone) {
138     fclose(myStream);
139     SetOpenMode(Storage_VSNone);
140   }
141   else {
142     result = Storage_VSNotOpen;
143   }
144
145   return result;
146 }
147
148 //=======================================================================
149 //function : MagicNumber
150 //purpose  : ------------------ PROTECTED
151 //=======================================================================
152
153 Standard_CString FSD_BinaryFile::MagicNumber()
154 {
155   return MAGICNUMBER;
156 }
157
158 //=======================================================================
159 //function : ReadChar
160 //purpose  : read <rsize> character from the current position.
161 //=======================================================================
162
163 void FSD_BinaryFile::ReadChar(TCollection_AsciiString& buffer, const Standard_Size rsize)
164 {
165   char             c;
166   Standard_Size ccount = 0;
167
168   buffer.Clear();
169
170   while (!IsEnd() && (ccount < rsize)) {
171     ccount += fread(&c, sizeof(char),1, myStream);
172     buffer += c;
173   }
174 }
175
176 //=======================================================================
177 //function : SkipObject
178 //purpose  : 
179 //=======================================================================
180
181 void FSD_BinaryFile::SkipObject()
182 {
183
184 }
185
186 //=======================================================================
187 //function : PutReference
188 //purpose  : ---------------------- PUBLIC : PUT
189 //=======================================================================
190
191 Storage_BaseDriver& FSD_BinaryFile::PutReference(const Standard_Integer aValue)
192 {
193 #if OCCT_BINARY_FILE_DO_INVERSE
194   Standard_Integer t = InverseInt (aValue);
195   
196   if (!fwrite(&t,sizeof(Standard_Integer),1,myStream)) Storage_StreamWriteError::Raise();
197 #else
198   if (!fwrite(&aValue,sizeof(Standard_Integer),1,myStream)) Storage_StreamWriteError::Raise();
199 #endif
200   return *this;
201 }
202
203 //=======================================================================
204 //function : PutCharacter
205 //purpose  : 
206 //=======================================================================
207
208 Storage_BaseDriver& FSD_BinaryFile::PutCharacter(const Standard_Character aValue)
209 {
210   if (!fwrite(&aValue,sizeof(Standard_Character),1,myStream)) Storage_StreamWriteError::Raise();
211   return *this;
212 }
213
214 //=======================================================================
215 //function : PutExtCharacter
216 //purpose  : 
217 //=======================================================================
218
219 Storage_BaseDriver& FSD_BinaryFile::PutExtCharacter(const Standard_ExtCharacter aValue)
220 {
221 #if OCCT_BINARY_FILE_DO_INVERSE
222   Standard_ExtCharacter t = InverseExtChar (aValue);
223
224   if (!fwrite(&t,sizeof(Standard_ExtCharacter),1,myStream)) Storage_StreamWriteError::Raise();
225 #else
226   if (!fwrite(&aValue,sizeof(Standard_ExtCharacter),1,myStream)) Storage_StreamWriteError::Raise();
227 #endif
228   return *this;
229 }
230
231 //=======================================================================
232 //function : PutInteger
233 //purpose  : 
234 //=======================================================================
235
236 Storage_BaseDriver& FSD_BinaryFile::PutInteger(const Standard_Integer aValue)
237 {
238 #if OCCT_BINARY_FILE_DO_INVERSE
239   Standard_Integer t = InverseInt (aValue);
240   
241   if (!fwrite(&t,sizeof(Standard_Integer),1,myStream)) Storage_StreamWriteError::Raise();
242 #else
243   if (!fwrite(&aValue,sizeof(Standard_Integer),1,myStream)) Storage_StreamWriteError::Raise();
244 #endif
245
246   return *this;
247 }
248
249 //=======================================================================
250 //function : PutBoolean
251 //purpose  : 
252 //=======================================================================
253
254 Storage_BaseDriver& FSD_BinaryFile::PutBoolean(const Standard_Boolean aValue)
255 {
256 #if OCCT_BINARY_FILE_DO_INVERSE
257   Standard_Integer t = InverseInt ((Standard_Integer) aValue);
258   
259   if (!fwrite(&t,sizeof(Standard_Integer),1,myStream)) Storage_StreamWriteError::Raise();
260 #else
261   if (!fwrite(&aValue,sizeof(Standard_Boolean),1,myStream)) Storage_StreamWriteError::Raise();
262 #endif
263   return *this;
264 }
265
266 //=======================================================================
267 //function : PutReal
268 //purpose  : 
269 //=======================================================================
270
271 Storage_BaseDriver& FSD_BinaryFile::PutReal(const Standard_Real aValue)
272 {
273 #if OCCT_BINARY_FILE_DO_INVERSE
274   Standard_Real t = InverseReal (aValue);
275   
276   if (!fwrite(&t,sizeof(Standard_Real),1,myStream)) Storage_StreamWriteError::Raise();
277 #else
278   if (!fwrite(&aValue,sizeof(Standard_Real),1,myStream)) Storage_StreamWriteError::Raise();
279 #endif
280   return *this;
281 }
282
283 //=======================================================================
284 //function : PutShortReal
285 //purpose  : 
286 //=======================================================================
287
288 Storage_BaseDriver& FSD_BinaryFile::PutShortReal(const Standard_ShortReal aValue)
289 {
290 #if OCCT_BINARY_FILE_DO_INVERSE
291   Standard_ShortReal t = InverseShortReal (aValue);
292
293   if (!fwrite(&t,sizeof(Standard_ShortReal),1,myStream)) Storage_StreamWriteError::Raise();
294 #else
295   if (!fwrite(&aValue,sizeof(Standard_ShortReal),1,myStream)) Storage_StreamWriteError::Raise();
296 #endif
297   return *this;
298 }
299
300 //=======================================================================
301 //function : GetReference
302 //purpose  : ----------------- PUBLIC : GET
303 //=======================================================================
304
305 Storage_BaseDriver& FSD_BinaryFile::GetReference(Standard_Integer& aValue)
306 {
307   if (!fread(&aValue,sizeof(Standard_Integer),1,myStream))
308     Storage_StreamTypeMismatchError::Raise();
309 #if OCCT_BINARY_FILE_DO_INVERSE
310   aValue = InverseInt (aValue);
311 #endif
312   return *this;
313 }
314
315 //=======================================================================
316 //function : GetCharacter
317 //purpose  : 
318 //=======================================================================
319
320 Storage_BaseDriver& FSD_BinaryFile::GetCharacter(Standard_Character& aValue)
321 {
322   if (!fread(&aValue,sizeof(Standard_Character),1,myStream))
323     Storage_StreamTypeMismatchError::Raise();
324   return *this;
325 }
326
327 //=======================================================================
328 //function : GetExtCharacter
329 //purpose  : 
330 //=======================================================================
331
332 Storage_BaseDriver& FSD_BinaryFile::GetExtCharacter(Standard_ExtCharacter& aValue)
333 {
334   if (!fread(&aValue,sizeof(Standard_ExtCharacter),1,myStream))
335     Storage_StreamTypeMismatchError::Raise();
336 #if OCCT_BINARY_FILE_DO_INVERSE
337   aValue = InverseExtChar (aValue);
338 #endif
339   return *this;
340 }
341
342 //=======================================================================
343 //function : GetInteger
344 //purpose  : 
345 //=======================================================================
346
347 Storage_BaseDriver& FSD_BinaryFile::GetInteger(Standard_Integer& aValue)
348 {
349   if (!fread(&aValue,sizeof(Standard_Integer),1,myStream))
350     Storage_StreamTypeMismatchError::Raise();
351 #if OCCT_BINARY_FILE_DO_INVERSE
352   aValue = InverseInt (aValue);
353 #endif
354   return *this;
355 }
356
357 //=======================================================================
358 //function : GetBoolean
359 //purpose  : 
360 //=======================================================================
361
362 Storage_BaseDriver& FSD_BinaryFile::GetBoolean(Standard_Boolean& aValue)
363 {
364   if (!fread(&aValue,sizeof(Standard_Boolean),1,myStream))
365     Storage_StreamTypeMismatchError::Raise();
366 #if OCCT_BINARY_FILE_DO_INVERSE
367   aValue = InverseInt ((Standard_Integer) aValue);
368 #endif
369   return *this;
370 }
371
372 //=======================================================================
373 //function : GetReal
374 //purpose  : 
375 //=======================================================================
376
377 Storage_BaseDriver& FSD_BinaryFile::GetReal(Standard_Real& aValue)
378 {
379   if (!fread(&aValue,sizeof(Standard_Real),1,myStream))
380     Storage_StreamTypeMismatchError::Raise();
381 #if OCCT_BINARY_FILE_DO_INVERSE
382   aValue = InverseReal (aValue);
383 #endif
384   return *this;
385 }
386
387 //=======================================================================
388 //function : GetShortReal
389 //purpose  : 
390 //=======================================================================
391
392 Storage_BaseDriver& FSD_BinaryFile::GetShortReal(Standard_ShortReal& aValue)
393 {
394   if (!fread(&aValue,sizeof(Standard_ShortReal),1,myStream))
395     Storage_StreamTypeMismatchError::Raise();
396 #if OCCT_BINARY_FILE_DO_INVERSE
397   aValue = InverseShortReal (aValue);
398 #endif
399   return *this;
400 }
401
402 //=======================================================================
403 //function : Destroy
404 //purpose  : 
405 //=======================================================================
406
407 void FSD_BinaryFile::Destroy()
408 {
409   if (OpenMode() != Storage_VSNone) {
410     Close();
411   }
412 }
413
414 //=======================================================================
415 //function : BeginWriteInfoSection
416 //purpose  : -------------------------- INFO : WRITE
417 //=======================================================================
418
419 Storage_Error FSD_BinaryFile::BeginWriteInfoSection() 
420 {
421   union {
422     char ti2[4];
423     Standard_Integer aResult;
424   } aWrapUnion;
425
426   aWrapUnion.ti2[0] = 1;
427   aWrapUnion.ti2[1] = 2;
428   aWrapUnion.ti2[2] = 3;
429   aWrapUnion.ti2[3] = 4;
430
431   myHeader.testindian = aWrapUnion.aResult;
432
433   if (!fwrite(FSD_BinaryFile::MagicNumber(),
434               strlen(FSD_BinaryFile::MagicNumber()),
435               1,
436               myStream))
437     Storage_StreamWriteError::Raise();
438   
439   myHeader.binfo = ftell(myStream);
440   WriteHeader();
441
442   return Storage_VSOk;
443 }
444
445 //=======================================================================
446 //function : WriteInfo
447 //purpose  : 
448 //=======================================================================
449
450 void FSD_BinaryFile::WriteInfo(const Standard_Integer nbObj,
451                          const TCollection_AsciiString& dbVersion,
452                          const TCollection_AsciiString& date,
453                          const TCollection_AsciiString& schemaName,
454                          const TCollection_AsciiString& schemaVersion,
455                          const TCollection_ExtendedString& appName,
456                          const TCollection_AsciiString& appVersion,
457                          const TCollection_ExtendedString& dataType,
458                          const TColStd_SequenceOfAsciiString& userInfo) 
459 {
460   Standard_Integer i;
461
462   PutInteger(nbObj);
463   WriteString(dbVersion);
464   WriteString(date);
465   WriteString(schemaName);
466   WriteString(schemaVersion);
467   WriteExtendedString(appName);
468   WriteString(appVersion);
469   WriteExtendedString(dataType);
470   i = userInfo.Length();
471
472   PutInteger(i);
473   for (i = 1; i <= userInfo.Length(); i++) {
474     WriteString(userInfo.Value(i));
475   }
476 }
477
478 //=======================================================================
479 //function : EndWriteInfoSection
480 //purpose  : read
481 //=======================================================================
482
483 Storage_Error FSD_BinaryFile::EndWriteInfoSection() 
484 {
485   myHeader.einfo = ftell(myStream);
486
487   return Storage_VSOk;
488 }
489
490 //=======================================================================
491 //function : BeginReadInfoSection
492 //purpose  : 
493 //=======================================================================
494
495 Storage_Error FSD_BinaryFile::BeginReadInfoSection() 
496 {
497   Storage_Error s = Storage_VSOk;
498   TCollection_AsciiString l;
499   Standard_Size        len = strlen(FSD_BinaryFile::MagicNumber());
500
501   ReadChar(l,len);
502
503   if (strncmp(FSD_BinaryFile::MagicNumber(),l.ToCString(),len) != 0) {
504     s = Storage_VSFormatError;
505   }
506   else {
507     ReadHeader();
508   }
509
510   return s;
511 }
512
513 //=======================================================================
514 //function : ReadInfo
515 //purpose  : ------------------- INFO : READ
516 //=======================================================================
517
518 void FSD_BinaryFile::ReadInfo(Standard_Integer& nbObj,
519                         TCollection_AsciiString& dbVersion,
520                         TCollection_AsciiString& date,
521                         TCollection_AsciiString& schemaName,
522                         TCollection_AsciiString& schemaVersion,
523                         TCollection_ExtendedString& appName,
524                         TCollection_AsciiString& appVersion,
525                         TCollection_ExtendedString& dataType,
526                         TColStd_SequenceOfAsciiString& userInfo) 
527 {
528   GetInteger(nbObj);
529   ReadString(dbVersion);
530   ReadString(date);
531   ReadString(schemaName);
532   ReadString(schemaVersion);
533   ReadExtendedString(appName);
534   ReadString(appVersion);
535   ReadExtendedString(dataType);
536
537   Standard_Integer i,len = 0;
538
539   GetInteger(len);
540   TCollection_AsciiString line;
541
542   for (i = 1; i <= len && !IsEnd(); i++) {
543     ReadString(line);
544     userInfo.Append(line);
545   }
546 }
547
548 //=======================================================================
549 //function : EndReadInfoSection
550 //purpose  : COMMENTS SECTION
551 //           write
552 //=======================================================================
553
554 Storage_Error FSD_BinaryFile::EndReadInfoSection() 
555 {
556   if (!fseek(myStream,myHeader.einfo,SEEK_SET)) return Storage_VSOk;
557   else return Storage_VSSectionNotFound;
558 }
559
560 //=======================================================================
561 //function : BeginWriteCommentSection
562 //purpose  : ---------------- COMMENTS : WRITE
563 //=======================================================================
564
565 Storage_Error FSD_BinaryFile::BeginWriteCommentSection() 
566 {
567   myHeader.bcomment = ftell(myStream);
568   return Storage_VSOk;
569 }
570
571 //=======================================================================
572 //function : WriteComment
573 //purpose  : 
574 //=======================================================================
575
576 void FSD_BinaryFile::WriteComment(const TColStd_SequenceOfExtendedString& aCom)
577 {
578  Standard_Integer i,aSize;
579
580  aSize = aCom.Length();
581  PutInteger(aSize);
582  for (i = 1; i <= aSize; i++) {
583    WriteExtendedString(aCom.Value(i));
584  }
585 }
586
587 //=======================================================================
588 //function : EndWriteCommentSection
589 //purpose  : read
590 //=======================================================================
591
592 Storage_Error FSD_BinaryFile::EndWriteCommentSection() 
593 {
594   myHeader.ecomment = ftell(myStream);
595
596   return Storage_VSOk;
597 }
598
599 //=======================================================================
600 //function : BeginReadCommentSection
601 //purpose  : ---------------- COMMENTS : READ
602 //=======================================================================
603
604 Storage_Error FSD_BinaryFile::BeginReadCommentSection() 
605 {
606   if (!fseek(myStream,myHeader.bcomment,SEEK_SET)) return Storage_VSOk;
607   else return Storage_VSSectionNotFound;
608 }
609
610 //=======================================================================
611 //function : ReadComment
612 //purpose  : 
613 //=======================================================================
614
615 void FSD_BinaryFile::ReadComment(TColStd_SequenceOfExtendedString& aCom)
616 {
617   TCollection_ExtendedString line;
618   Standard_Integer           len,i;
619
620   GetInteger(len);
621   for (i = 1; i <= len && !IsEnd(); i++) {
622     ReadExtendedString(line);
623     aCom.Append(line);
624   }
625 }
626
627 //=======================================================================
628 //function : EndReadCommentSection
629 //purpose  : 
630 //=======================================================================
631
632 Storage_Error FSD_BinaryFile::EndReadCommentSection() 
633 {
634   if (!fseek(myStream,myHeader.ecomment,SEEK_SET)) return Storage_VSOk;
635   else return Storage_VSSectionNotFound;
636 }
637
638 //=======================================================================
639 //function : BeginWriteTypeSection
640 //purpose  : --------------- TYPE : WRITE
641 //=======================================================================
642
643 Storage_Error FSD_BinaryFile::BeginWriteTypeSection() 
644 {
645   myHeader.btype = ftell(myStream);
646
647   return Storage_VSOk;
648 }
649
650 //=======================================================================
651 //function : SetTypeSectionSize
652 //purpose  : 
653 //=======================================================================
654
655 void FSD_BinaryFile::SetTypeSectionSize(const Standard_Integer aSize) 
656 {
657   PutInteger(aSize);
658 }
659
660 //=======================================================================
661 //function : WriteTypeInformations
662 //purpose  : 
663 //=======================================================================
664
665 void FSD_BinaryFile::WriteTypeInformations(const Standard_Integer typeNum,
666                                       const TCollection_AsciiString& typeName) 
667 {
668   PutInteger(typeNum);
669   WriteString(typeName);
670 }
671
672 //=======================================================================
673 //function : EndWriteTypeSection
674 //purpose  : read
675 //=======================================================================
676
677 Storage_Error FSD_BinaryFile::EndWriteTypeSection() 
678 {
679   myHeader.etype = ftell(myStream);
680
681   return Storage_VSOk;
682 }
683
684 //=======================================================================
685 //function : BeginReadTypeSection
686 //purpose  : ------------------- TYPE : READ
687 //=======================================================================
688
689 Storage_Error FSD_BinaryFile::BeginReadTypeSection() 
690 {
691  if (!fseek(myStream,myHeader.btype,SEEK_SET)) return Storage_VSOk;
692   else return Storage_VSSectionNotFound;
693 }
694
695 //=======================================================================
696 //function : TypeSectionSize
697 //purpose  : 
698 //=======================================================================
699
700 Standard_Integer FSD_BinaryFile::TypeSectionSize() 
701 {
702   Standard_Integer i;
703
704   GetInteger(i);
705   return i;
706 }
707
708 //=======================================================================
709 //function : ReadTypeInformations
710 //purpose  : 
711 //=======================================================================
712
713 void FSD_BinaryFile::ReadTypeInformations(Standard_Integer& typeNum,TCollection_AsciiString& typeName) 
714 {
715   GetInteger(typeNum);
716   ReadString(typeName);
717 }
718
719 //=======================================================================
720 //function : EndReadTypeSection
721 //purpose  : ROOT SECTION
722 //           write
723 //=======================================================================
724
725 Storage_Error FSD_BinaryFile::EndReadTypeSection() 
726 {
727  if (!fseek(myStream,myHeader.etype,SEEK_SET)) return Storage_VSOk;
728   else return Storage_VSSectionNotFound;
729 }
730
731 //=======================================================================
732 //function : BeginWriteRootSection
733 //purpose  : -------------------- ROOT : WRITE
734 //=======================================================================
735
736 Storage_Error FSD_BinaryFile::BeginWriteRootSection() 
737 {
738   myHeader.broot = ftell(myStream);
739
740   return Storage_VSOk;
741 }
742
743 //=======================================================================
744 //function : SetRootSectionSize
745 //purpose  : 
746 //=======================================================================
747
748 void FSD_BinaryFile::SetRootSectionSize(const Standard_Integer aSize) 
749 {
750   PutInteger(aSize);
751 }
752
753 //=======================================================================
754 //function : WriteRoot
755 //purpose  : 
756 //=======================================================================
757
758 void FSD_BinaryFile::WriteRoot(const TCollection_AsciiString& rootName, const Standard_Integer aRef, const TCollection_AsciiString& rootType) 
759 {
760   PutReference(aRef);
761   WriteString(rootName);
762   WriteString(rootType);
763 }
764
765 //=======================================================================
766 //function : EndWriteRootSection
767 //purpose  : read
768 //=======================================================================
769
770 Storage_Error FSD_BinaryFile::EndWriteRootSection() 
771 {
772   myHeader.eroot = ftell(myStream);
773
774   return Storage_VSOk;
775 }
776
777 //=======================================================================
778 //function : BeginReadRootSection
779 //purpose  : ----------------------- ROOT : READ
780 //=======================================================================
781
782 Storage_Error FSD_BinaryFile::BeginReadRootSection() 
783 {
784  if (!fseek(myStream,myHeader.broot,SEEK_SET)) return Storage_VSOk;
785   else return Storage_VSSectionNotFound;
786 }
787
788 //=======================================================================
789 //function : RootSectionSize
790 //purpose  : 
791 //=======================================================================
792
793 Standard_Integer FSD_BinaryFile::RootSectionSize() 
794 {
795   Standard_Integer i;
796   
797   GetInteger(i);
798   return i;
799 }
800
801 //=======================================================================
802 //function : ReadRoot
803 //purpose  : 
804 //=======================================================================
805
806 void FSD_BinaryFile::ReadRoot(TCollection_AsciiString& rootName, Standard_Integer& aRef,TCollection_AsciiString& rootType) 
807 {
808   GetReference(aRef);
809   ReadString(rootName);
810   ReadString(rootType);
811 }
812
813 //=======================================================================
814 //function : EndReadRootSection
815 //purpose  : REF SECTION
816 //           write
817 //=======================================================================
818
819 Storage_Error FSD_BinaryFile::EndReadRootSection() 
820 {
821  if (!fseek(myStream,myHeader.eroot,SEEK_SET)) return Storage_VSOk;
822   else return Storage_VSSectionNotFound;
823 }
824
825 //=======================================================================
826 //function : BeginWriteRefSection
827 //purpose  : -------------------------- REF : WRITE
828 //=======================================================================
829
830 Storage_Error FSD_BinaryFile::BeginWriteRefSection() 
831 {
832   myHeader.bref = ftell(myStream);
833
834   return Storage_VSOk;
835 }
836
837 //=======================================================================
838 //function : SetRefSectionSize
839 //purpose  : 
840 //=======================================================================
841
842 void FSD_BinaryFile::SetRefSectionSize(const Standard_Integer aSize) 
843 {
844   PutInteger(aSize);
845 }
846
847 //=======================================================================
848 //function : WriteReferenceType
849 //purpose  : 
850 //=======================================================================
851
852 void FSD_BinaryFile::WriteReferenceType(const Standard_Integer reference,const Standard_Integer typeNum) 
853 {
854   PutReference(reference);
855   PutInteger(typeNum);
856 }
857
858 //=======================================================================
859 //function : EndWriteRefSection
860 //purpose  : read
861 //=======================================================================
862
863 Storage_Error FSD_BinaryFile::EndWriteRefSection() 
864 {
865   myHeader.eref = ftell(myStream);
866
867   return Storage_VSOk;
868 }
869
870 //=======================================================================
871 //function : BeginReadRefSection
872 //purpose  : ----------------------- REF : READ
873 //=======================================================================
874
875 Storage_Error FSD_BinaryFile::BeginReadRefSection() 
876 {
877  if (!fseek(myStream,myHeader.bref,SEEK_SET)) return Storage_VSOk;
878   else return Storage_VSSectionNotFound;
879 }
880
881 //=======================================================================
882 //function : RefSectionSize
883 //purpose  : 
884 //=======================================================================
885
886 Standard_Integer FSD_BinaryFile::RefSectionSize() 
887 {
888   Standard_Integer i;
889
890   GetInteger(i);
891   return i;
892 }
893
894 //=======================================================================
895 //function : ReadReferenceType
896 //purpose  : 
897 //=======================================================================
898
899 void FSD_BinaryFile::ReadReferenceType(Standard_Integer& reference,
900                                  Standard_Integer& typeNum) 
901 {
902   GetReference(reference);
903   GetInteger(typeNum);
904 }
905
906 //=======================================================================
907 //function : EndReadRefSection
908 //purpose  : DATA SECTION
909 //           write
910 //=======================================================================
911
912 Storage_Error FSD_BinaryFile::EndReadRefSection() 
913 {
914  if (!fseek(myStream,myHeader.eref,SEEK_SET)) return Storage_VSOk;
915   else return Storage_VSSectionNotFound;
916 }
917
918 //=======================================================================
919 //function : BeginWriteDataSection
920 //purpose  : -------------------- DATA : WRITE
921 //=======================================================================
922
923 Storage_Error FSD_BinaryFile::BeginWriteDataSection() 
924 {
925   myHeader.bdata = ftell(myStream);
926
927   return Storage_VSOk;
928 }
929
930 //=======================================================================
931 //function : WritePersistentObjectHeader
932 //purpose  : 
933 //=======================================================================
934
935 void FSD_BinaryFile::WritePersistentObjectHeader(const Standard_Integer aRef,
936                                            const Standard_Integer aType) 
937 {
938   PutReference(aRef);
939   PutInteger(aType);
940 }
941
942 //=======================================================================
943 //function : BeginWritePersistentObjectData
944 //purpose  : 
945 //=======================================================================
946
947 void FSD_BinaryFile::BeginWritePersistentObjectData() 
948 {
949 }
950
951 //=======================================================================
952 //function : BeginWriteObjectData
953 //purpose  : 
954 //=======================================================================
955
956 void FSD_BinaryFile::BeginWriteObjectData() 
957 {
958 }
959
960 //=======================================================================
961 //function : EndWriteObjectData
962 //purpose  : 
963 //=======================================================================
964
965 void FSD_BinaryFile::EndWriteObjectData() 
966 {
967 }
968
969 //=======================================================================
970 //function : EndWritePersistentObjectData
971 //purpose  : 
972 //=======================================================================
973
974 void FSD_BinaryFile::EndWritePersistentObjectData() 
975 {
976 }
977
978 //=======================================================================
979 //function : EndWriteDataSection
980 //purpose  : read
981 //=======================================================================
982
983 Storage_Error FSD_BinaryFile::EndWriteDataSection() 
984 {
985   myHeader.edata = ftell(myStream);
986   
987   fseek(myStream,myHeader.binfo,SEEK_SET);
988   WriteHeader();
989   return Storage_VSOk;
990 }
991
992 //=======================================================================
993 //function : BeginReadDataSection
994 //purpose  : ---------------------- DATA : READ
995 //=======================================================================
996
997 Storage_Error FSD_BinaryFile::BeginReadDataSection() 
998 {
999  if (!fseek(myStream,myHeader.bdata,SEEK_SET)) return Storage_VSOk;
1000   else return Storage_VSSectionNotFound;
1001 }
1002
1003 //=======================================================================
1004 //function : ReadPersistentObjectHeader
1005 //purpose  : 
1006 //=======================================================================
1007
1008 void FSD_BinaryFile::ReadPersistentObjectHeader(Standard_Integer& aRef,
1009                                           Standard_Integer& aType) 
1010 {
1011   GetReference(aRef);
1012   GetInteger(aType);
1013 }
1014
1015 //=======================================================================
1016 //function : BeginReadPersistentObjectData
1017 //purpose  : 
1018 //=======================================================================
1019
1020 void FSD_BinaryFile::BeginReadPersistentObjectData() 
1021 {
1022 }
1023
1024 //=======================================================================
1025 //function : BeginReadObjectData
1026 //purpose  : 
1027 //=======================================================================
1028
1029 void FSD_BinaryFile::BeginReadObjectData() 
1030 {
1031 }
1032
1033 //=======================================================================
1034 //function : EndReadObjectData
1035 //purpose  : 
1036 //=======================================================================
1037
1038 void FSD_BinaryFile::EndReadObjectData() 
1039 {
1040 }
1041
1042 //=======================================================================
1043 //function : EndReadPersistentObjectData
1044 //purpose  : 
1045 //=======================================================================
1046
1047 void FSD_BinaryFile::EndReadPersistentObjectData() 
1048 {
1049 }
1050
1051 //=======================================================================
1052 //function : EndReadDataSection
1053 //purpose  : 
1054 //=======================================================================
1055
1056 Storage_Error FSD_BinaryFile::EndReadDataSection() 
1057 {
1058  if (!fseek(myStream,myHeader.edata,SEEK_SET)) return Storage_VSOk;
1059   else return Storage_VSSectionNotFound;
1060 }
1061
1062 //=======================================================================
1063 //function : WriteString
1064 //purpose  : write string at the current position.
1065 //=======================================================================
1066
1067 void FSD_BinaryFile::WriteString(const TCollection_AsciiString& aString)
1068 {
1069   Standard_Integer size;
1070
1071   size = aString.Length();
1072
1073   PutInteger(size);
1074
1075   if (size > 0) {
1076     if (!fwrite(aString.ToCString(),aString.Length(),1,myStream)) Storage_StreamWriteError::Raise();
1077   }
1078 }
1079
1080 //=======================================================================
1081 //function : ReadString
1082 //purpose  : read string from the current position.
1083 //=======================================================================
1084
1085 void FSD_BinaryFile::ReadString(TCollection_AsciiString& aString)
1086 {
1087   Standard_Integer size = 0;
1088
1089   GetInteger(size);
1090   if (size > 0) {
1091     Standard_Character *c = (Standard_Character *)Standard::Allocate((size+1) * sizeof(Standard_Character));
1092     if (!fread(c,size,1,myStream)) Storage_StreamWriteError::Raise();
1093     c[size] = '\0';
1094     aString = c;
1095     Standard::Free(c);
1096   }
1097   else {
1098     aString.Clear();
1099   }
1100 }
1101
1102 //=======================================================================
1103 //function : WriteExtendedString
1104 //purpose  : write string at the current position.
1105 //=======================================================================
1106
1107 void FSD_BinaryFile::WriteExtendedString(const TCollection_ExtendedString& aString)
1108 {
1109   Standard_Integer size;
1110
1111   size = aString.Length();
1112
1113   PutInteger(size);
1114
1115   if (size > 0) {
1116     Standard_ExtString anExtStr;
1117 #if OCCT_BINARY_FILE_DO_INVERSE
1118     TCollection_ExtendedString aCopy = aString;
1119     anExtStr = aCopy.ToExtString();
1120
1121     Standard_PExtCharacter pChar;
1122     //
1123     pChar=(Standard_PExtCharacter)anExtStr;
1124     
1125     for (Standard_Integer i=0; i < size; i++)
1126       pChar[i] = InverseExtChar (pChar[i]);
1127 #else
1128     anExtStr = aString.ToExtString();
1129 #endif
1130     if (!fwrite(anExtStr,sizeof(Standard_ExtCharacter)*aString.Length(),1,myStream))
1131       Storage_StreamWriteError::Raise();
1132   }
1133 }
1134
1135 //=======================================================================
1136 //function : ReadExtendedString
1137 //purpose  : read string from the current position.
1138 //=======================================================================
1139
1140 void FSD_BinaryFile::ReadExtendedString(TCollection_ExtendedString& aString)
1141 {
1142   Standard_Integer size = 0;
1143
1144   GetInteger(size);
1145   if (size > 0) {
1146     Standard_ExtCharacter *c = (Standard_ExtCharacter *)
1147       Standard::Allocate((size+1) * sizeof(Standard_ExtCharacter));
1148     if (!fread(c,size*sizeof(Standard_ExtCharacter),1,myStream))
1149       Storage_StreamWriteError::Raise();
1150     c[size] = '\0';
1151 #if OCCT_BINARY_FILE_DO_INVERSE
1152     for (Standard_Integer i=0; i < size; i++)
1153       c[i] = InverseExtChar (c[i]);
1154 #endif
1155     aString = c;
1156     Standard::Free(c);
1157   }
1158   else {
1159     aString.Clear();
1160   }
1161 }
1162
1163 //=======================================================================
1164 //function : WriteHeader
1165 //purpose  : 
1166 //=======================================================================
1167
1168 void FSD_BinaryFile::WriteHeader()
1169 {
1170   PutInteger(myHeader.testindian);
1171   PutInteger(myHeader.binfo);
1172   PutInteger(myHeader.einfo);
1173   PutInteger(myHeader.bcomment);
1174   PutInteger(myHeader.ecomment);
1175   PutInteger(myHeader.btype);
1176   PutInteger(myHeader.etype);
1177   PutInteger(myHeader.broot);
1178   PutInteger(myHeader.eroot);
1179   PutInteger(myHeader.bref);
1180   PutInteger(myHeader.eref);
1181   PutInteger(myHeader.bdata);
1182   PutInteger(myHeader.edata);
1183 }
1184
1185 //=======================================================================
1186 //function : ReadHeader
1187 //purpose  : 
1188 //=======================================================================
1189
1190 void FSD_BinaryFile::ReadHeader()
1191 {
1192   GetInteger(myHeader.testindian);
1193   GetInteger(myHeader.binfo);
1194   GetInteger(myHeader.einfo);
1195   GetInteger(myHeader.bcomment);
1196   GetInteger(myHeader.ecomment);
1197   GetInteger(myHeader.btype);
1198   GetInteger(myHeader.etype);
1199   GetInteger(myHeader.broot);
1200   GetInteger(myHeader.eroot);
1201   GetInteger(myHeader.bref);
1202   GetInteger(myHeader.eref);
1203   GetInteger(myHeader.bdata);
1204   GetInteger(myHeader.edata);
1205 }
1206
1207
1208 //=======================================================================
1209 //function : Tell
1210 //purpose  : return position in the file. Return -1 upon error.
1211 //=======================================================================
1212
1213 Storage_Position FSD_BinaryFile::Tell()
1214 {
1215   return (Storage_Position) ftell(myStream);
1216 }
1217
1218 //=======================================================================
1219 //function : InverseReal
1220 //purpose  : Inverses bytes in the real value
1221 //=======================================================================
1222
1223 Standard_Real FSD_BinaryFile::InverseReal (const Standard_Real theValue)
1224 {
1225   Standard_STATIC_ASSERT(sizeof(Standard_Real) == 2 * sizeof(Standard_Integer));
1226   union {
1227     Standard_Integer i[2];
1228     Standard_Real    aValue;
1229   } aWrapUnion;
1230
1231   aWrapUnion.aValue = theValue;
1232
1233   Standard_Integer aTemp = aWrapUnion.i[1];
1234   aWrapUnion.i[1] = InverseInt(aWrapUnion.i[0]);
1235   aWrapUnion.i[0] = InverseInt(aTemp);
1236
1237   return aWrapUnion.aValue;
1238 }
1239
1240 //=======================================================================
1241 //function : InverseShortReal
1242 //purpose  : Inverses bytes in the short real value
1243 //=======================================================================
1244
1245 Standard_ShortReal FSD_BinaryFile::InverseShortReal (const Standard_ShortReal theValue)
1246 {
1247   Standard_STATIC_ASSERT(sizeof(Standard_ShortReal) == sizeof(Standard_Integer));
1248   union {
1249     Standard_ShortReal aValue;
1250     Standard_Integer   aResult;
1251   } aWrapUnion;
1252
1253   aWrapUnion.aValue  = theValue;
1254   aWrapUnion.aResult = InverseInt (aWrapUnion.aResult);
1255
1256   return aWrapUnion.aValue;
1257 }
1258
1259 //=======================================================================
1260 //function : InverseSize
1261 //purpose  : Inverses bytes in size_t type instance
1262 //=======================================================================
1263
1264 template<int size>
1265 inline Standard_Size OCCT_InverseSizeSpecialized (const Standard_Size theValue, int);
1266
1267 template<>
1268 inline Standard_Size OCCT_InverseSizeSpecialized <4> (const Standard_Size theValue, int)
1269 {
1270   return FSD_BinaryFile::InverseInt(static_cast<Standard_Integer>(theValue));
1271 }
1272
1273 template<>
1274 inline Standard_Size OCCT_InverseSizeSpecialized <8> (const Standard_Size theValue, int)
1275 {
1276   union {
1277     Standard_Integer i[2];
1278     Standard_Size    aValue;
1279   } aWrapUnion;
1280
1281   aWrapUnion.aValue = theValue;
1282
1283   Standard_Integer aTemp = aWrapUnion.i[1];
1284   aWrapUnion.i[1] = FSD_BinaryFile::InverseInt(aWrapUnion.i[0]);
1285   aWrapUnion.i[0] = FSD_BinaryFile::InverseInt(aTemp);
1286
1287   return aWrapUnion.aValue;
1288 }
1289
1290 Standard_Size FSD_BinaryFile::InverseSize (const Standard_Size theValue)
1291 {
1292   return OCCT_InverseSizeSpecialized <sizeof(Standard_Size)> (theValue, 0);
1293 }