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