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