10afce93a3035d0b40e14974ea19a4b7ef826ba2
[occt.git] / src / FSD / FSD_File.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 #include <FSD_File.hxx>
16
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
27 const Standard_CString MAGICNUMBER = "FSDFILE";
28 const Standard_CString ENDOFNORMALEXTENDEDSECTION = "BEGIN_REF_SECTION";
29 const Standard_Integer SIZEOFNORMALEXTENDEDSECTION = 16;
30
31 #define USEOSDREAL 1
32
33 //=======================================================================
34 //function : FSD_File
35 //purpose  : 
36 //=======================================================================
37
38 FSD_File::FSD_File()
39 {
40
41 }
42
43 //=======================================================================
44 //function : IsGoodFileType
45 //purpose  : INFO SECTION
46 //           write
47 //=======================================================================
48
49 Storage_Error FSD_File::IsGoodFileType(const TCollection_AsciiString& aName)
50 {
51   FSD_File      f;
52   Storage_Error s;
53
54   s = f.Open(aName,Storage_VSRead);
55
56   if (s == Storage_VSOk) {
57     TCollection_AsciiString l;
58     Standard_Size        len = strlen(FSD_File::MagicNumber());
59
60     f.ReadChar(l,len);
61
62     f.Close();
63
64     if (strncmp(FSD_File::MagicNumber(),l.ToCString(),len) != 0) {
65       s = Storage_VSFormatError;
66     }
67   }
68
69   return s;
70 }
71
72 //=======================================================================
73 //function : Open
74 //purpose  : 
75 //=======================================================================
76
77 Storage_Error FSD_File::Open(const TCollection_AsciiString& aName,const Storage_OpenMode aMode)
78 {
79   Storage_Error result = Storage_VSOk;
80
81   SetName(aName);
82
83   if (OpenMode() == Storage_VSNone)
84   {
85     std::ios_base::openmode anOpenMode = std::ios_base::openmode(0);
86     switch (aMode)
87     {
88       case Storage_VSNone:
89       {
90         break;
91       }
92       case Storage_VSRead:
93       {
94         // ios::nocreate is not portable
95         anOpenMode = ios::in;
96         break;
97       }
98       case Storage_VSWrite:
99       {
100         anOpenMode = ios::out;
101         break;
102       }
103       case Storage_VSReadWrite:
104       {
105         anOpenMode = ios::in | ios::out;
106         break;
107       }
108     }
109     if (anOpenMode != 0)
110     {
111       OSD_OpenStream (myStream, aName.ToCString(), anOpenMode);
112     }
113     if (myStream.fail()) {
114       result = Storage_VSOpenError;
115     }
116     else {
117       myStream.precision(17);
118       myStream.imbue (std::locale::classic()); // use always C locale
119       SetOpenMode(aMode);
120     }
121   }
122   else {
123     result = Storage_VSAlreadyOpen;
124   }
125
126   return result;
127 }
128
129 //=======================================================================
130 //function : IsEnd
131 //purpose  : 
132 //=======================================================================
133
134 Standard_Boolean FSD_File::IsEnd()
135 {
136   return myStream.eof();
137 }
138
139 //=======================================================================
140 //function : Close
141 //purpose  : 
142 //=======================================================================
143
144 Storage_Error FSD_File::Close()
145 {
146   Storage_Error result = Storage_VSOk;
147
148   if (OpenMode() != Storage_VSNone) {
149     myStream.close();
150     SetOpenMode(Storage_VSNone);
151   }
152   else {
153     result = Storage_VSNotOpen;
154   }
155
156   return result;
157 }
158
159 //=======================================================================
160 //function : MagicNumber
161 //purpose  : ------------------ PROTECTED
162 //=======================================================================
163
164 Standard_CString FSD_File::MagicNumber()
165 {
166   return MAGICNUMBER;
167 }
168
169 //=======================================================================
170 //function : FlushEndOfLine
171 //purpose  : 
172 //=======================================================================
173
174 void FSD_File::FlushEndOfLine()
175 {
176   TCollection_AsciiString aDummy;
177   ReadLine (aDummy); // flush is nothing more than to read till the line-break
178 }
179
180 //=======================================================================
181 //function : ReadLine
182 //purpose  : read from the current position to the end of line.
183 //=======================================================================
184
185 void FSD_File::ReadLine(TCollection_AsciiString& buffer)
186 {
187   char Buffer[8193];
188   Standard_Boolean IsEnd = Standard_False;
189   
190   buffer.Clear();
191
192   while (!IsEnd && !FSD_File::IsEnd()) {
193     Buffer[0] = '\0';
194     myStream.getline(Buffer,8192,'\n');
195     
196 //    char c;
197 //    if (myStream.get(c) && c != '\n') {
198 //      buffer += Buffer;
199 //      buffer += c;
200 //    }
201 //    else {
202       buffer += Buffer;
203       IsEnd = Standard_True;
204 //    }
205   }
206 }
207
208 //=======================================================================
209 //function : WriteExtendedLine
210 //purpose  : write from the current position to the end of line.
211 //=======================================================================
212
213 void FSD_File::WriteExtendedLine(const TCollection_ExtendedString& buffer)
214 {
215   Standard_ExtString extBuffer;
216   Standard_Integer   i,c,d;
217
218   extBuffer = buffer.ToExtString();
219
220   for (i = 0; i < buffer.Length(); i++) {
221     c = (extBuffer[i] & 0x0000FF00 ) >> 8 ;
222     d = extBuffer[i] & 0x000000FF;
223
224     myStream << (char)c << (char)d;
225   }
226
227   myStream << (char)0 << "\n";
228 }
229
230 //=======================================================================
231 //function : ReadExtendedLine
232 //purpose  : 
233 //=======================================================================
234
235 void FSD_File::ReadExtendedLine(TCollection_ExtendedString& buffer)
236 {
237   char c = '\0';
238   Standard_ExtCharacter i = 0,j,count = 0;
239   Standard_Boolean fin = Standard_False;
240   Standard_CString tg = ENDOFNORMALEXTENDEDSECTION;
241  
242   buffer.Clear();
243
244   while (!fin && !IsEnd()) {
245     myStream.get(c);
246
247     if (c == tg[count]) count++;
248     else count = 0;
249     if (count < SIZEOFNORMALEXTENDEDSECTION) {
250       j = 0;
251       i = (Standard_ExtCharacter)c;
252       if (c == '\0') fin = Standard_True;
253       i = (i << 8);
254       
255       myStream.get(c);
256       if (c == tg[count]) count++;
257       else count = 0;
258       if (count < SIZEOFNORMALEXTENDEDSECTION) {
259         j = (Standard_ExtCharacter)c;
260         if (c != '\n') {
261           fin = Standard_False;
262           i |= (0x00FF & j);
263           buffer += (Standard_ExtCharacter)i;
264         }
265       }
266       else {
267         throw Storage_StreamExtCharParityError();
268       }
269     }
270     else {
271       throw Storage_StreamExtCharParityError();
272     }
273   }
274 }
275
276 //=======================================================================
277 //function : ReadChar
278 //purpose  : read <rsize> character from the current position.
279 //=======================================================================
280
281 void FSD_File::ReadChar(TCollection_AsciiString& buffer, const Standard_Size rsize)
282 {
283   char             c;
284   Standard_Size ccount = 0;
285
286   buffer.Clear();
287
288   while (!IsEnd() && (ccount < rsize)) {
289     myStream.get(c);
290     buffer += c;
291     ccount++;
292   }
293 }
294
295 //=======================================================================
296 //function : ReadString
297 //purpose  : read from the first none space character position to the end of line.
298 //=======================================================================
299
300 void FSD_File::ReadString(TCollection_AsciiString& buffer)
301 {
302   char Buffer[8193];
303   char *bpos;
304   Standard_Boolean IsEnd = Standard_False,isFirstTime = Standard_True;
305   
306   buffer.Clear();
307   
308   while (!IsEnd && !FSD_File::IsEnd()) {
309     Buffer[0] = '\0';
310     myStream.getline(Buffer,8192,'\n');
311     bpos = Buffer;
312
313     // LeftAdjust
314     //
315     if (isFirstTime) {
316       isFirstTime = Standard_False;
317       while (*bpos == '\n' || *bpos == ' ') bpos++;
318     }
319 //    char c;
320 //    if (myStream.get(c) && c != '\n') {
321 //      buffer += bpos;
322 //      buffer += c;
323 //    }
324 //    else {
325       buffer += bpos;
326       IsEnd = Standard_True;
327 //    }
328   }
329   
330 }
331
332 //=======================================================================
333 //function : ReadWord
334 //purpose  : read from the current position to the next white space or end of line.
335 //=======================================================================
336
337 void FSD_File::ReadWord(TCollection_AsciiString& buffer)
338 {
339   char c = '\0';
340   char b[8193],*tmpb;
341   Standard_Boolean IsEnd = Standard_False;
342   Standard_Integer i;
343
344   tmpb = b;
345   memset(b,'\0',8193);
346   buffer.Clear();
347
348   while (!IsEnd && !FSD_File::IsEnd()) {
349     myStream.get(c);
350     if ((c != ' ') && (c != '\n')) IsEnd = Standard_True;
351   }
352
353   IsEnd = Standard_False;
354   i = 0;
355
356   while (!IsEnd && !FSD_File::IsEnd()) {
357     if (i == 8192) {
358       buffer += b;
359       tmpb = b;
360       memset(b,'\0',8193);
361       i = 0;
362     }
363     *tmpb = c;
364     tmpb++; i++;
365     myStream.get(c);
366     if ((c == '\n') || (c == ' ')) IsEnd = Standard_True;
367   }
368
369   buffer += b;
370 }
371
372 //=======================================================================
373 //function : FindTag
374 //purpose  : 
375 //=======================================================================
376
377 Storage_Error FSD_File::FindTag(const Standard_CString aTag)
378 {
379   TCollection_AsciiString l;
380   
381   ReadString(l);
382
383   while ((strcmp(l.ToCString(),aTag) != 0) && !IsEnd()) {
384     ReadString(l);
385   }
386
387   if (IsEnd()) {
388     return Storage_VSSectionNotFound;
389   }
390   else {
391     return Storage_VSOk;
392   }
393 }
394
395 //=======================================================================
396 //function : SkipObject
397 //purpose  : 
398 //=======================================================================
399
400 void FSD_File::SkipObject()
401 {
402   FlushEndOfLine();
403 }
404
405 //=======================================================================
406 //function : PutReference
407 //purpose  : ---------------------- PUBLIC : PUT
408 //=======================================================================
409
410 Storage_BaseDriver& FSD_File::PutReference(const Standard_Integer aValue)
411 {
412   myStream << aValue << " ";
413   if (myStream.bad()) throw Storage_StreamWriteError();
414   return *this;
415 }
416
417 //=======================================================================
418 //function : PutCharacter
419 //purpose  : 
420 //=======================================================================
421
422 Storage_BaseDriver& FSD_File::PutCharacter(const Standard_Character aValue)
423 {
424   unsigned short i;
425
426   i = aValue;
427   myStream << i << " ";
428   if (myStream.bad()) throw Storage_StreamWriteError();
429   return *this;
430 }
431
432 //=======================================================================
433 //function : PutExtCharacter
434 //purpose  : 
435 //=======================================================================
436
437 Storage_BaseDriver& FSD_File::PutExtCharacter(const Standard_ExtCharacter aValue)
438 {
439   myStream << (short )aValue << " ";
440   if (myStream.bad()) throw Storage_StreamWriteError();
441   return *this;
442 }
443
444 //=======================================================================
445 //function : PutInteger
446 //purpose  : 
447 //=======================================================================
448
449 Storage_BaseDriver& FSD_File::PutInteger(const Standard_Integer aValue)
450 {
451   myStream << aValue << " ";
452   if (myStream.bad()) throw Storage_StreamWriteError();
453   return *this;
454 }
455
456 //=======================================================================
457 //function : PutBoolean
458 //purpose  : 
459 //=======================================================================
460
461 Storage_BaseDriver& FSD_File::PutBoolean(const Standard_Boolean aValue)
462 {
463   myStream << ((Standard_Integer)aValue) << " ";
464   if (myStream.bad()) throw Storage_StreamWriteError();
465   return *this;
466 }
467
468 //=======================================================================
469 //function : PutReal
470 //purpose  : 
471 //=======================================================================
472
473 Storage_BaseDriver& FSD_File::PutReal(const Standard_Real aValue)
474 {
475   myStream << ((Standard_Real)aValue) << " ";
476   if (myStream.bad()) throw Storage_StreamWriteError();
477   return *this;
478 }
479
480 //=======================================================================
481 //function : PutShortReal
482 //purpose  : 
483 //=======================================================================
484
485 Storage_BaseDriver& FSD_File::PutShortReal(const Standard_ShortReal aValue)
486 {
487   myStream << aValue << " ";
488   if (myStream.bad()) throw Storage_StreamWriteError();
489   return *this;
490 }
491
492 //=======================================================================
493 //function : GetReference
494 //purpose  : ----------------- PUBLIC : GET
495 //=======================================================================
496
497 Storage_BaseDriver& FSD_File::GetReference(Standard_Integer& aValue)
498 {
499   if (!(myStream >> aValue)) throw Storage_StreamTypeMismatchError();
500
501   return *this;
502 }
503
504 //=======================================================================
505 //function : GetCharacter
506 //purpose  : 
507 //=======================================================================
508
509 Storage_BaseDriver& FSD_File::GetCharacter(Standard_Character& aValue)
510 {
511   unsigned short i = 0;
512   if (!(myStream >> i)) {
513     // SGI : donne une erreur mais a une bonne valeur pour les caracteres ecrits
514     //       signes (-80 fait ios::badbit, mais la variable i est initialisee)
515     //
516     if (i == 0) throw Storage_StreamTypeMismatchError();
517     myStream.clear(ios::goodbit); // .clear(0) is not portable
518   }
519   aValue = (char)i;
520
521   return *this;
522 }
523
524 //=======================================================================
525 //function : GetExtCharacter
526 //purpose  : 
527 //=======================================================================
528
529 Storage_BaseDriver& FSD_File::GetExtCharacter(Standard_ExtCharacter& aValue)
530 {
531   short aChar = 0;
532   if (!(myStream >> aChar)) throw Storage_StreamTypeMismatchError();
533   aValue = aChar;
534   return *this;
535 }
536
537 //=======================================================================
538 //function : GetInteger
539 //purpose  : 
540 //=======================================================================
541
542 Storage_BaseDriver& FSD_File::GetInteger(Standard_Integer& aValue)
543 {
544   if (!(myStream >> aValue)) throw Storage_StreamTypeMismatchError();
545
546   return *this;
547 }
548
549 //=======================================================================
550 //function : GetBoolean
551 //purpose  : 
552 //=======================================================================
553
554 Storage_BaseDriver& FSD_File::GetBoolean(Standard_Boolean& aValue)
555 {
556   if (!(myStream >> aValue)) throw Storage_StreamTypeMismatchError();
557
558   return *this;
559 }
560
561 //=======================================================================
562 //function : GetReal
563 //purpose  : 
564 //=======================================================================
565
566 Storage_BaseDriver& FSD_File::GetReal(Standard_Real& aValue)
567 {
568 #ifdef USEOSDREAL
569   char realbuffer[100];
570
571   realbuffer[0] = '\0';
572   if (!(myStream >> realbuffer)) throw Storage_StreamTypeMismatchError();
573   if (!OSD::CStringToReal(realbuffer,aValue)) throw Storage_StreamTypeMismatchError();
574
575   return *this;
576 #else
577   if (!(myStream >> aValue)) throw Storage_StreamTypeMismatchError();
578
579   return *this;
580 #endif
581 }
582
583 //=======================================================================
584 //function : GetShortReal
585 //purpose  : 
586 //=======================================================================
587
588 Storage_BaseDriver& FSD_File::GetShortReal(Standard_ShortReal& aValue)
589 {
590 #ifdef USEOSDREAL
591   char realbuffer[100];
592   Standard_Real r = 0.0;
593
594   realbuffer[0] = '\0';
595   if (!(myStream >> realbuffer)) throw Storage_StreamTypeMismatchError();
596   if (!OSD::CStringToReal(realbuffer,r)) throw Storage_StreamTypeMismatchError();
597
598   aValue = (Standard_ShortReal)r;
599
600   return *this;
601 #else
602   if (!(myStream >> aValue)) throw Storage_StreamTypeMismatchError();
603  return *this;
604 #endif
605 }
606
607 //=======================================================================
608 //function : Destroy
609 //purpose  : 
610 //=======================================================================
611
612 void FSD_File::Destroy()
613 {
614   if (OpenMode() != Storage_VSNone) {
615     Close();
616   }
617 }
618
619 //=======================================================================
620 //function : BeginWriteInfoSection
621 //purpose  : -------------------------- INFO : WRITE
622 //=======================================================================
623
624 Storage_Error FSD_File::BeginWriteInfoSection() 
625 {
626   myStream << FSD_File::MagicNumber() << '\n';
627   myStream << "BEGIN_INFO_SECTION\n";
628   if (myStream.bad()) throw Storage_StreamWriteError();
629
630   return Storage_VSOk;
631 }
632
633 //=======================================================================
634 //function : WriteInfo
635 //purpose  : 
636 //=======================================================================
637
638 void FSD_File::WriteInfo(const Standard_Integer nbObj,
639                          const TCollection_AsciiString& dbVersion,
640                          const TCollection_AsciiString& date,
641                          const TCollection_AsciiString& schemaName,
642                          const TCollection_AsciiString& schemaVersion,
643                          const TCollection_ExtendedString& appName,
644                          const TCollection_AsciiString& appVersion,
645                          const TCollection_ExtendedString& dataType,
646                          const TColStd_SequenceOfAsciiString& userInfo) 
647 {
648   Standard_Integer i;
649
650   myStream << nbObj;
651   myStream << "\n";
652   myStream << dbVersion.ToCString() << "\n";
653   myStream << date.ToCString() << "\n";
654   myStream << schemaName.ToCString() << "\n";
655   myStream << schemaVersion.ToCString() << "\n";
656   WriteExtendedLine(appName);
657   myStream << appVersion.ToCString() << "\n";
658   WriteExtendedLine(dataType);
659   myStream << userInfo.Length() << "\n";
660
661   if (myStream.bad()) throw Storage_StreamWriteError();
662
663   for (i = 1; i <= userInfo.Length(); i++) {
664     myStream << userInfo.Value(i).ToCString() << "\n";
665     if (myStream.bad()) throw Storage_StreamWriteError();
666   }
667 }
668
669 //=======================================================================
670 //function : EndWriteInfoSection
671 //purpose  : read
672 //=======================================================================
673
674 Storage_Error FSD_File::EndWriteInfoSection() 
675 {
676   myStream << "END_INFO_SECTION\n";
677   if (myStream.bad())  throw Storage_StreamWriteError();
678   return Storage_VSOk;
679 }
680
681 //=======================================================================
682 //function : BeginReadInfoSection
683 //purpose  : 
684 //=======================================================================
685
686 Storage_Error FSD_File::BeginReadInfoSection() 
687 {
688   Storage_Error s;
689   TCollection_AsciiString l;
690   Standard_Size        len = strlen(FSD_File::MagicNumber());
691
692   ReadChar(l,len);
693   
694   if (strncmp(FSD_File::MagicNumber(),l.ToCString(),len) != 0) {
695     s = Storage_VSFormatError;
696   }
697   else {
698     s = FindTag("BEGIN_INFO_SECTION");
699   }
700
701   return s;
702 }
703
704 //=======================================================================
705 //function : ReadInfo
706 //purpose  : ------------------- INFO : READ
707 //=======================================================================
708
709 void FSD_File::ReadInfo(Standard_Integer& nbObj,
710                         TCollection_AsciiString& dbVersion,
711                         TCollection_AsciiString& date,
712                         TCollection_AsciiString& schemaName,
713                         TCollection_AsciiString& schemaVersion,
714                         TCollection_ExtendedString& appName,
715                         TCollection_AsciiString& appVersion,
716                         TCollection_ExtendedString& dataType,
717                         TColStd_SequenceOfAsciiString& userInfo) 
718 {
719   if (!(myStream >> nbObj)) throw Storage_StreamTypeMismatchError();
720
721   FlushEndOfLine();
722
723   ReadLine(dbVersion);
724   ReadLine(date);
725   ReadLine(schemaName);
726   ReadLine(schemaVersion);
727   ReadExtendedLine(appName);
728   ReadLine(appVersion);
729   ReadExtendedLine(dataType);
730
731   Standard_Integer i,len = 0;
732
733   if (!(myStream >> len)) throw Storage_StreamTypeMismatchError();
734
735   FlushEndOfLine();
736
737   TCollection_AsciiString line;
738
739   for (i = 1; i <= len && !IsEnd(); i++) {
740     ReadLine(line);
741     userInfo.Append(line);
742     line.Clear();
743   }
744 }
745
746 //=======================================================================
747 //function : ReadCompleteInfo
748 //purpose  : 
749 //           
750 //=======================================================================
751 void FSD_File::ReadCompleteInfo( Standard_IStream& /*theIStream*/, Handle(Storage_Data)& /*theData*/)
752 {
753
754 }
755
756 //=======================================================================
757 //function : EndReadInfoSection
758 //purpose  : COMMENTS SECTION
759 //           write
760 //=======================================================================
761
762 Storage_Error FSD_File::EndReadInfoSection() 
763 {
764   return FindTag("END_INFO_SECTION");
765 }
766
767 //=======================================================================
768 //function : BeginWriteCommentSection
769 //purpose  : ---------------- COMMENTS : WRITE
770 //=======================================================================
771
772 Storage_Error FSD_File::BeginWriteCommentSection() 
773 {
774   myStream << "BEGIN_COMMENT_SECTION\n";
775   if (myStream.bad()) throw Storage_StreamWriteError();
776   return Storage_VSOk;
777 }
778
779 //=======================================================================
780 //function : WriteComment
781 //purpose  : 
782 //=======================================================================
783
784 void FSD_File::WriteComment(const TColStd_SequenceOfExtendedString& aCom)
785 {
786  Standard_Integer i,aSize;
787
788  aSize = aCom.Length();
789  myStream << aSize << "\n";
790  if (myStream.bad()) throw Storage_StreamWriteError();
791
792  for (i = 1; i <= aSize; i++) {
793    WriteExtendedLine(aCom.Value(i));
794    if (myStream.bad()) throw Storage_StreamWriteError();
795  }
796 }
797
798 //=======================================================================
799 //function : EndWriteCommentSection
800 //purpose  : read
801 //=======================================================================
802
803 Storage_Error FSD_File::EndWriteCommentSection() 
804 {
805   myStream << "END_COMMENT_SECTION\n";
806   if (myStream.bad()) throw Storage_StreamWriteError();
807   return Storage_VSOk;
808 }
809
810 //=======================================================================
811 //function : BeginReadCommentSection
812 //purpose  : ---------------- COMMENTS : READ
813 //=======================================================================
814
815 Storage_Error FSD_File::BeginReadCommentSection() 
816 {
817   return FindTag("BEGIN_COMMENT_SECTION");
818 }
819
820 //=======================================================================
821 //function : ReadComment
822 //purpose  : 
823 //=======================================================================
824
825 void FSD_File::ReadComment(TColStd_SequenceOfExtendedString& aCom)
826 {
827   TCollection_ExtendedString line;
828   Standard_Integer           len,i;
829
830   if (!(myStream >> len)) throw Storage_StreamTypeMismatchError();
831   
832   FlushEndOfLine();  
833
834   for (i = 1; i <= len && !IsEnd(); i++) {
835     ReadExtendedLine(line);
836     aCom.Append(line);
837     line.Clear();
838   }
839 }
840
841 //=======================================================================
842 //function : EndReadCommentSection
843 //purpose  : 
844 //=======================================================================
845
846 Storage_Error FSD_File::EndReadCommentSection() 
847 {
848   return FindTag("END_COMMENT_SECTION");
849 }
850
851 //=======================================================================
852 //function : BeginWriteTypeSection
853 //purpose  : --------------- TYPE : WRITE
854 //=======================================================================
855
856 Storage_Error FSD_File::BeginWriteTypeSection() 
857 {
858   myStream << "BEGIN_TYPE_SECTION\n";
859   if (myStream.bad()) throw Storage_StreamWriteError();
860   return Storage_VSOk;
861 }
862
863 //=======================================================================
864 //function : SetTypeSectionSize
865 //purpose  : 
866 //=======================================================================
867
868 void FSD_File::SetTypeSectionSize(const Standard_Integer aSize) 
869 {
870   myStream << aSize << "\n";
871   if (myStream.bad()) throw Storage_StreamWriteError();
872 }
873
874 //=======================================================================
875 //function : WriteTypeInformations
876 //purpose  : 
877 //=======================================================================
878
879 void FSD_File::WriteTypeInformations(const Standard_Integer typeNum,
880                                       const TCollection_AsciiString& typeName) 
881 {
882   myStream << typeNum << " " << typeName.ToCString() << "\n";
883   if (myStream.bad()) throw Storage_StreamWriteError();
884 }
885
886 //=======================================================================
887 //function : EndWriteTypeSection
888 //purpose  : read
889 //=======================================================================
890
891 Storage_Error FSD_File::EndWriteTypeSection() 
892 {
893   myStream << "END_TYPE_SECTION\n";
894   if (myStream.bad()) throw Storage_StreamWriteError();
895   return Storage_VSOk;
896 }
897
898 //=======================================================================
899 //function : BeginReadTypeSection
900 //purpose  : ------------------- TYPE : READ
901 //=======================================================================
902
903 Storage_Error FSD_File::BeginReadTypeSection() 
904 {
905   return FindTag("BEGIN_TYPE_SECTION");
906 }
907
908 //=======================================================================
909 //function : TypeSectionSize
910 //purpose  : 
911 //=======================================================================
912
913 Standard_Integer FSD_File::TypeSectionSize() 
914 {
915   Standard_Integer i;
916
917   if (!(myStream >> i)) throw Storage_StreamTypeMismatchError();
918
919   FlushEndOfLine();
920
921   return i;
922 }
923
924 //=======================================================================
925 //function : ReadTypeInformations
926 //purpose  : 
927 //=======================================================================
928
929 void FSD_File::ReadTypeInformations(Standard_Integer& typeNum,
930                                     TCollection_AsciiString& typeName) 
931 {
932   if (!(myStream >> typeNum)) throw Storage_StreamTypeMismatchError();
933   if (!(myStream >> typeName)) throw Storage_StreamTypeMismatchError();
934   FlushEndOfLine();
935 }
936
937 //=======================================================================
938 //function : EndReadTypeSection
939 //purpose  : ROOT SECTION
940 //           write
941 //=======================================================================
942
943 Storage_Error FSD_File::EndReadTypeSection() 
944 {
945   return FindTag("END_TYPE_SECTION");
946 }
947
948 //=======================================================================
949 //function : BeginWriteRootSection
950 //purpose  : -------------------- ROOT : WRITE
951 //=======================================================================
952
953 Storage_Error FSD_File::BeginWriteRootSection() 
954 {
955   myStream << "BEGIN_ROOT_SECTION\n";
956   if (myStream.bad()) throw Storage_StreamWriteError();
957   return Storage_VSOk;
958 }
959
960 //=======================================================================
961 //function : SetRootSectionSize
962 //purpose  : 
963 //=======================================================================
964
965 void FSD_File::SetRootSectionSize(const Standard_Integer aSize) 
966 {
967   myStream << aSize << "\n";
968   if (myStream.bad()) throw Storage_StreamWriteError();
969 }
970
971 //=======================================================================
972 //function : WriteRoot
973 //purpose  : 
974 //=======================================================================
975
976 void FSD_File::WriteRoot(const TCollection_AsciiString& rootName, const Standard_Integer aRef, const TCollection_AsciiString& rootType) 
977 {
978   myStream << aRef << " " << rootName.ToCString() << " " << rootType.ToCString() << "\n";
979   if (myStream.bad()) throw Storage_StreamWriteError();
980 }
981
982 //=======================================================================
983 //function : EndWriteRootSection
984 //purpose  : read
985 //=======================================================================
986
987 Storage_Error FSD_File::EndWriteRootSection() 
988 {
989   myStream << "END_ROOT_SECTION\n";
990   if (myStream.bad()) throw Storage_StreamWriteError();
991   return Storage_VSOk;
992 }
993
994 //=======================================================================
995 //function : BeginReadRootSection
996 //purpose  : ----------------------- ROOT : READ
997 //=======================================================================
998
999 Storage_Error FSD_File::BeginReadRootSection() 
1000 {
1001   return FindTag("BEGIN_ROOT_SECTION");
1002 }
1003
1004 //=======================================================================
1005 //function : RootSectionSize
1006 //purpose  : 
1007 //=======================================================================
1008
1009 Standard_Integer FSD_File::RootSectionSize() 
1010 {
1011   Standard_Integer i;
1012
1013   if (!(myStream >> i)) throw Storage_StreamTypeMismatchError();
1014   
1015   FlushEndOfLine();
1016   
1017   return i;
1018 }
1019
1020 //=======================================================================
1021 //function : ReadRoot
1022 //purpose  : 
1023 //=======================================================================
1024
1025 void FSD_File::ReadRoot(TCollection_AsciiString& rootName, Standard_Integer& aRef,TCollection_AsciiString& rootType) 
1026 {
1027   if (!(myStream >> aRef)) throw Storage_StreamTypeMismatchError();
1028   ReadWord(rootName);
1029   ReadWord(rootType);
1030 }
1031
1032 //=======================================================================
1033 //function : EndReadRootSection
1034 //purpose  : REF SECTION
1035 //           write
1036 //=======================================================================
1037
1038 Storage_Error FSD_File::EndReadRootSection() 
1039 {
1040   return FindTag("END_ROOT_SECTION");
1041 }
1042
1043 //=======================================================================
1044 //function : BeginWriteRefSection
1045 //purpose  : -------------------------- REF : WRITE
1046 //=======================================================================
1047
1048 Storage_Error FSD_File::BeginWriteRefSection() 
1049 {
1050   myStream << "BEGIN_REF_SECTION\n";
1051   if (myStream.bad()) throw Storage_StreamWriteError();
1052   return Storage_VSOk;
1053 }
1054
1055 //=======================================================================
1056 //function : SetRefSectionSize
1057 //purpose  : 
1058 //=======================================================================
1059
1060 void FSD_File::SetRefSectionSize(const Standard_Integer aSize) 
1061 {
1062   myStream << aSize << "\n";
1063   if (myStream.bad()) throw Storage_StreamWriteError();
1064 }
1065
1066 //=======================================================================
1067 //function : WriteReferenceType
1068 //purpose  : 
1069 //=======================================================================
1070
1071 void FSD_File::WriteReferenceType(const Standard_Integer reference,
1072                                   const Standard_Integer typeNum) 
1073 {
1074   myStream << reference << " " << typeNum << "\n";
1075   if (myStream.bad()) throw Storage_StreamWriteError();
1076 }
1077
1078 //=======================================================================
1079 //function : EndWriteRefSection
1080 //purpose  : read
1081 //=======================================================================
1082
1083 Storage_Error FSD_File::EndWriteRefSection() 
1084 {
1085   myStream << "END_REF_SECTION\n";
1086   if (myStream.bad()) throw Storage_StreamWriteError();
1087   return Storage_VSOk;
1088 }
1089
1090 //=======================================================================
1091 //function : BeginReadRefSection
1092 //purpose  : ----------------------- REF : READ
1093 //=======================================================================
1094
1095 Storage_Error FSD_File::BeginReadRefSection() 
1096 {
1097   return FindTag("BEGIN_REF_SECTION");
1098 }
1099
1100 //=======================================================================
1101 //function : RefSectionSize
1102 //purpose  : 
1103 //=======================================================================
1104
1105 Standard_Integer FSD_File::RefSectionSize() 
1106 {
1107   Standard_Integer i;
1108
1109   if (!(myStream >> i)) throw Storage_StreamTypeMismatchError();
1110   FlushEndOfLine();
1111
1112   return i;
1113 }
1114
1115 //=======================================================================
1116 //function : ReadReferenceType
1117 //purpose  : 
1118 //=======================================================================
1119
1120 void FSD_File::ReadReferenceType(Standard_Integer& reference,
1121                                  Standard_Integer& typeNum) 
1122 {
1123   if (!(myStream >> reference)) throw Storage_StreamTypeMismatchError();
1124   if (!(myStream >> typeNum)) throw Storage_StreamTypeMismatchError();
1125   FlushEndOfLine();
1126 }
1127
1128 //=======================================================================
1129 //function : EndReadRefSection
1130 //purpose  : DATA SECTION
1131 //           write
1132 //=======================================================================
1133
1134 Storage_Error FSD_File::EndReadRefSection() 
1135 {
1136   return FindTag("END_REF_SECTION");
1137 }
1138
1139 //=======================================================================
1140 //function : BeginWriteDataSection
1141 //purpose  : -------------------- DATA : WRITE
1142 //=======================================================================
1143
1144 Storage_Error FSD_File::BeginWriteDataSection() 
1145 {
1146   myStream << "BEGIN_DATA_SECTION";
1147   if (myStream.bad()) throw Storage_StreamWriteError();
1148   return Storage_VSOk;
1149 }
1150
1151 //=======================================================================
1152 //function : WritePersistentObjectHeader
1153 //purpose  : 
1154 //=======================================================================
1155
1156 void FSD_File::WritePersistentObjectHeader(const Standard_Integer aRef,
1157                                            const Standard_Integer aType) 
1158 {
1159   myStream << "\n#" << aRef << "=%" << aType;
1160   if (myStream.bad()) throw Storage_StreamWriteError();
1161 }
1162
1163 //=======================================================================
1164 //function : BeginWritePersistentObjectData
1165 //purpose  : 
1166 //=======================================================================
1167
1168 void FSD_File::BeginWritePersistentObjectData() 
1169 {
1170   myStream << "( ";
1171   if (myStream.bad()) throw Storage_StreamWriteError();
1172 }
1173
1174 //=======================================================================
1175 //function : BeginWriteObjectData
1176 //purpose  : 
1177 //=======================================================================
1178
1179 void FSD_File::BeginWriteObjectData() 
1180 {
1181   myStream << "( ";
1182   if (myStream.bad()) throw Storage_StreamWriteError();
1183 }
1184
1185 //=======================================================================
1186 //function : EndWriteObjectData
1187 //purpose  : 
1188 //=======================================================================
1189
1190 void FSD_File::EndWriteObjectData() 
1191 {
1192   myStream << ") ";
1193   if (myStream.bad()) throw Storage_StreamWriteError();
1194 }
1195
1196 //=======================================================================
1197 //function : EndWritePersistentObjectData
1198 //purpose  : 
1199 //=======================================================================
1200
1201 void FSD_File::EndWritePersistentObjectData() 
1202 {
1203   myStream << ")";
1204   if (myStream.bad()) throw Storage_StreamWriteError();
1205 }
1206
1207 //=======================================================================
1208 //function : EndWriteDataSection
1209 //purpose  : read
1210 //=======================================================================
1211
1212 Storage_Error FSD_File::EndWriteDataSection() 
1213 {
1214   myStream << "\nEND_DATA_SECTION\n";
1215   if (myStream.bad()) throw Storage_StreamWriteError();
1216   return Storage_VSOk;
1217 }
1218
1219 //=======================================================================
1220 //function : BeginReadDataSection
1221 //purpose  : ---------------------- DATA : READ
1222 //=======================================================================
1223
1224 Storage_Error FSD_File::BeginReadDataSection() 
1225 {
1226   return FindTag("BEGIN_DATA_SECTION");
1227 }
1228
1229 //=======================================================================
1230 //function : ReadPersistentObjectHeader
1231 //purpose  : 
1232 //=======================================================================
1233
1234 void FSD_File::ReadPersistentObjectHeader(Standard_Integer& aRef,
1235                                           Standard_Integer& aType) 
1236 {
1237   char c;
1238
1239   myStream.get(c);
1240
1241   while (c != '#') {
1242     if (IsEnd() || (c != ' ') || (c == '\n')) {
1243       throw Storage_StreamFormatError();
1244     }
1245     myStream.get(c);
1246   }
1247
1248   if (!(myStream >> aRef)) throw Storage_StreamTypeMismatchError();
1249
1250   myStream.get(c);
1251
1252
1253    while (c != '=') {
1254     if (IsEnd() || (c != ' ') || (c == '\n')) {
1255       throw Storage_StreamFormatError();
1256     }
1257     myStream.get(c);
1258   }
1259
1260   myStream.get(c);
1261
1262   while (c != '%') {
1263     if (IsEnd() || (c != ' ') || (c == '\n')) {
1264       throw Storage_StreamFormatError();
1265     }
1266     myStream.get(c);
1267   }
1268
1269   if (!(myStream >> aType)) throw Storage_StreamTypeMismatchError();
1270 //  cout << "REF:" << aRef << " TYPE:"<< aType << endl;
1271 }
1272
1273 //=======================================================================
1274 //function : BeginReadPersistentObjectData
1275 //purpose  : 
1276 //=======================================================================
1277
1278 void FSD_File::BeginReadPersistentObjectData() 
1279 {
1280   char c;
1281   myStream.get(c);
1282   while (c != '(') {
1283     if (IsEnd() || (c != ' ') || (c == '\n')) {
1284       throw Storage_StreamFormatError();
1285     }
1286     myStream.get(c);
1287   }
1288
1289 //cout << "BeginReadPersistentObjectData" << endl;
1290 }
1291
1292 //=======================================================================
1293 //function : BeginReadObjectData
1294 //purpose  : 
1295 //=======================================================================
1296
1297 void FSD_File::BeginReadObjectData() 
1298 {
1299
1300   char c;
1301   myStream.get(c);
1302   while (c != '(') {
1303     if (IsEnd() || (c != ' ') || (c == '\n')) {
1304       throw Storage_StreamFormatError();
1305     }
1306     myStream.get(c);
1307   }
1308
1309 //  cout << "BeginReadObjectData" << endl;
1310 }
1311
1312 //=======================================================================
1313 //function : EndReadObjectData
1314 //purpose  : 
1315 //=======================================================================
1316
1317 void FSD_File::EndReadObjectData() 
1318 {
1319
1320   char c;
1321   myStream.get(c);
1322   while (c != ')') {
1323     if (IsEnd() || (c != ' ') || (c == '\n')) {
1324       throw Storage_StreamFormatError();
1325     }
1326     myStream.get(c);
1327   }
1328
1329 //  cout << "EndReadObjectData" << endl;
1330 }
1331
1332 //=======================================================================
1333 //function : EndReadPersistentObjectData
1334 //purpose  : 
1335 //=======================================================================
1336
1337 void FSD_File::EndReadPersistentObjectData() 
1338 {
1339
1340   char c;
1341
1342   myStream.get(c);
1343   while (c != ')') {
1344     if (IsEnd() || (c != ' ') || (c == '\n')) {
1345       throw Storage_StreamFormatError();
1346     }
1347     myStream.get(c);
1348   }
1349
1350   myStream.get(c);
1351   while (c != '\n') {
1352     if (IsEnd() || (c != ' ')) {
1353       throw Storage_StreamFormatError();
1354     }
1355     myStream.get(c);
1356   }
1357 //  cout << "EndReadPersistentObjectData" << endl;
1358 }
1359
1360 //=======================================================================
1361 //function : EndReadDataSection
1362 //purpose  : 
1363 //=======================================================================
1364
1365 Storage_Error FSD_File::EndReadDataSection() 
1366 {
1367   return FindTag("END_DATA_SECTION");
1368 }
1369
1370 //=======================================================================
1371 //function : Tell
1372 //purpose  : return position in the file. Return -1 upon error.
1373 //=======================================================================
1374
1375 Storage_Position FSD_File::Tell()
1376 {
1377   switch (OpenMode()) {
1378   case Storage_VSRead:
1379     return (Storage_Position) myStream.tellp();
1380   case Storage_VSWrite:
1381     return (Storage_Position) myStream.tellg();
1382   case Storage_VSReadWrite: {
1383     Storage_Position aPosR  = (Storage_Position) myStream.tellp();
1384     Storage_Position aPosW  = (Storage_Position) myStream.tellg();
1385     if (aPosR < aPosW)
1386       return aPosW;
1387     else
1388       return aPosR;
1389   }
1390   default: return -1;
1391   }
1392 }