0022815: Missing delete operator for placement new
[occt.git] / src / Storage / Storage_Schema.cxx
1 #include <Storage_Schema.ixx>
2
3 #include <TColStd_HSequenceOfAsciiString.hxx>
4 #include <TColStd_MapOfAsciiString.hxx>
5
6 #include <Storage.hxx>
7 #include <Storage_BucketOfPersistent.hxx>
8 #include <Storage_InternalData.hxx>
9 #include <Storage_TypedCallBack.hxx>
10 #include <Storage_HPArray.hxx>
11 #include <Storage_HSeqOfRoot.hxx>
12 #include <Storage_Root.hxx>
13 #include <Storage_DataMapIteratorOfMapOfCallBack.hxx>
14 #include <Storage_DefaultCallBack.hxx>
15 #include <Storage_HArrayOfCallBack.hxx>
16
17 #include <Storage_StreamModeError.hxx>
18 #include <Storage_StreamFormatError.hxx>
19 #include <Storage_StreamWriteError.hxx>
20 #include <Storage_StreamReadError.hxx>
21 #include <Storage_StreamUnknownTypeError.hxx>
22 #include <Storage_StreamTypeMismatchError.hxx>
23 #include <Storage_StreamExtCharParityError.hxx>
24 #include <Standard_ErrorHandler.hxx>
25
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29
30 #if defined(HAVE_TIME_H) || defined(WNT)
31 # include <time.h>
32 #endif
33
34 #ifdef HAVE_SYS_TIME_H
35 # include <sys/time.h>
36 #endif
37
38 #include <locale.h>
39 #include <stdio.h>
40
41 #define DATATYPE_MIGRATION
42
43 #ifdef DATATYPE_MIGRATION
44 #include <NCollection_DataMap.hxx>
45 #include <OSD_File.hxx>
46 #include <OSD_Path.hxx>
47 #include <OSD_Protection.hxx>
48 #include <OSD_Environment.hxx>
49
50 typedef NCollection_DataMap <TCollection_AsciiString, 
51   TCollection_AsciiString> DataMapOfAStringAString;
52
53 #endif
54
55 // IMPLEMENTATION BucketOfPersistent
56 //
57 Storage_Bucket::~Storage_Bucket()
58 {
59   Standard::Free((Standard_Address&)mySpace);
60   mySpace = 0L;
61   mySpaceSize = 0;
62   Clear();
63 }
64
65 //=======================================================================
66 //function : Clear
67 //purpose  : 
68 //=======================================================================
69
70 void Storage_Bucket::Clear()
71 {
72   myCurrentSpace = -1;
73 }
74
75 //=======================================================================
76 //function : Append
77 //purpose  : 
78 //=======================================================================
79
80 void Storage_Bucket::Append(Standard_Persistent *sp)
81 {
82   myCurrentSpace++;
83   mySpace[myCurrentSpace] = sp;
84 }
85
86 //=======================================================================
87 //function : Value
88 //purpose  : 
89 //=======================================================================
90
91 Standard_Persistent* Storage_Bucket::Value
92                          (const Standard_Integer theIndex) const
93 {
94   return mySpace[theIndex];
95 }
96
97 //=======================================================================
98 //function : Storage_BucketOfPersistent
99 //purpose  : 
100 //=======================================================================
101
102 Storage_BucketOfPersistent::Storage_BucketOfPersistent
103                          (const Standard_Integer theBucketSize,
104                           const Standard_Integer theBucketNumber)
105 : myNumberOfBucket(1),myNumberOfBucketAllocated(theBucketNumber),myBucketSize
106                          (theBucketSize)
107 {
108   myBuckets =  (Storage_Bucket**)Standard::Allocate
109                          (sizeof(Storage_Bucket*) * theBucketNumber);
110   myBuckets[0] = new Storage_Bucket(myBucketSize);
111   myCurrentBucket = myBuckets[0];
112   myLength = 0;
113   myCurrentBucketNumber = 0;
114 }
115
116 //=======================================================================
117 //function : Clear
118 //purpose  : 
119 //=======================================================================
120
121 void Storage_BucketOfPersistent::Clear()
122 {
123   if (myBuckets) {
124     Standard_Integer i;
125
126     for (i = 1; i < myNumberOfBucket; i++) delete myBuckets[i];
127     myNumberOfBucket = 1;
128     myCurrentBucket = myBuckets[0];
129     myCurrentBucket->Clear();
130     myCurrentBucketNumber = 0;
131     myLength = 0;
132   }
133 }
134
135 Storage_BucketOfPersistent::~Storage_BucketOfPersistent()
136 {
137   Clear();
138   delete myBuckets[0];
139   Standard::Free((Standard_Address&)myBuckets);
140   myBuckets = 0L;
141 }
142
143 //=======================================================================
144 //function : Value
145 //purpose  : 
146 //=======================================================================
147
148 Standard_Persistent* Storage_BucketOfPersistent::Value
149                          (const Standard_Integer theIndex)
150 {
151   Standard_Integer theInd,theCurrentBucketNumber,tecurrentind = theIndex - 1;
152   theCurrentBucketNumber = tecurrentind / myBucketSize;
153   theInd = tecurrentind - (myBucketSize * theCurrentBucketNumber);
154
155   return myBuckets[theCurrentBucketNumber]->mySpace[theInd];
156
157 }
158
159 //=======================================================================
160 //function : Append
161 //purpose  : 
162 //=======================================================================
163
164 void Storage_BucketOfPersistent::Append(const Handle(Standard_Persistent)& sp)
165 {
166   myCurrentBucket->myCurrentSpace++;
167
168   if (myCurrentBucket->myCurrentSpace != myBucketSize) {
169     myLength++;
170     myCurrentBucket->mySpace[myCurrentBucket->myCurrentSpace] = sp.operator->();
171     return;
172   }
173
174   myCurrentBucket->myCurrentSpace--;
175   myNumberOfBucket++;
176   myCurrentBucketNumber++;
177
178   if (myNumberOfBucket > myNumberOfBucketAllocated) {
179     Standard_Size e = sizeof(Storage_Bucket*) * myNumberOfBucketAllocated;
180     myBuckets =  (Storage_Bucket**)Standard::Reallocate((Standard_Address&)myBuckets, e * 2);
181     myNumberOfBucketAllocated *= 2;
182   }
183
184   myBuckets[myCurrentBucketNumber] = new Storage_Bucket(myBucketSize);
185   myCurrentBucket = myBuckets[myCurrentBucketNumber];
186   myCurrentBucket->myCurrentSpace++;
187   myLength++;
188   myCurrentBucket->mySpace[myCurrentBucket->myCurrentSpace] = sp.operator->();
189 }
190
191 //=======================================================================
192 //function : Storage_BucketIterator
193 //purpose  : 
194 //=======================================================================
195
196 Storage_BucketIterator::Storage_BucketIterator
197                          (Storage_BucketOfPersistent* aBucketManager)
198 {
199   if (aBucketManager) {
200     myBucket             = aBucketManager;
201     myCurrentBucket      = myBucket->myBuckets[0];
202     myBucketNumber       = aBucketManager->myNumberOfBucket;
203     myCurrentBucketIndex = 0;
204     myCurrentIndex       = 0;
205     myMoreObject         = Standard_True;
206   }
207   else myMoreObject         = Standard_False;
208 }
209
210 //=======================================================================
211 //function : Reset
212 //purpose  : 
213 //=======================================================================
214
215 void Storage_BucketIterator::Reset()
216 {
217   if (myBucket) {
218     myCurrentBucket = myBucket->myBuckets[0];
219     myBucketNumber  = myBucket->myNumberOfBucket;
220     myCurrentIndex  = 0;
221     myCurrentBucketIndex = 0;
222     myMoreObject = Standard_True;
223   }
224   else myMoreObject         = Standard_False;
225 }
226
227 //=======================================================================
228 //function : Init
229 //purpose  : 
230 //=======================================================================
231
232 void Storage_BucketIterator::Init(Storage_BucketOfPersistent* aBucketManager)
233 {
234   if (aBucketManager) {
235     myBucket        = aBucketManager;
236     myCurrentBucket = myBucket->myBuckets[0];
237     myBucketNumber  = aBucketManager->myNumberOfBucket;
238     myCurrentIndex  = 0;
239     myCurrentBucketIndex = 0;
240     myMoreObject = Standard_True;
241   }
242   else myMoreObject         = Standard_False;
243 }
244
245 //=======================================================================
246 //function : Next
247 //purpose  : 
248 //=======================================================================
249
250 void Storage_BucketIterator::Next()
251 {
252   if (!myMoreObject) return;
253
254   if (myCurrentIndex < myCurrentBucket->myCurrentSpace) {
255     myCurrentIndex++;
256   }
257   else {
258     myCurrentIndex = 0;
259     myCurrentBucketIndex++;
260     if (myCurrentBucketIndex < myBucketNumber) {
261       myCurrentBucket = myBucket->myBuckets[myCurrentBucketIndex];
262     }
263     else {
264       myMoreObject = Standard_False;
265     }
266   }
267 }
268
269 //=======================================================================
270 //function : Storage_Schema
271 //purpose  : USER API -- --------------------------------------------------------------
272 //           IMPLEMENTATION BucketOfPersistent
273 //=======================================================================
274
275 Storage_Schema::Storage_Schema()
276 {
277   Clear();
278   ResetDefaultCallBack();
279   myCallBackState = Standard_False;
280   myNestedState = Standard_False;
281 }
282
283 //=======================================================================
284 //function : SetVersion
285 //purpose  : returns version of the schema
286 //=======================================================================
287
288 void Storage_Schema::SetVersion(const TCollection_AsciiString& aVersion)
289 {
290   myVersion = aVersion;
291 }
292
293 //=======================================================================
294 //function : Version
295 //purpose  : returns the version of the schema
296 //=======================================================================
297
298 TCollection_AsciiString Storage_Schema::Version() const
299 {
300   return myVersion;
301 }
302
303 //=======================================================================
304 //function : SetName
305 //purpose  : set the schema's name
306 //=======================================================================
307
308 void Storage_Schema::SetName(const TCollection_AsciiString& aSchemaName)
309 {
310   myName = aSchemaName;
311 }
312
313 //=======================================================================
314 //function : Name
315 //purpose  : returns the schema's name
316 //=======================================================================
317
318 TCollection_AsciiString Storage_Schema::Name() const
319 {
320   return myName;
321 }
322
323 //=======================================================================
324 //function : Write
325 //purpose  : write 
326 //Arguments:
327 //           s: driver to write
328 //           raises  if  the  stream  is  not  opened  in  VSWrite  or
329 //           VSReadWrite
330 //=======================================================================
331
332 void Storage_Schema::Write
333                          (Storage_BaseDriver& f,
334                           const Handle(Storage_Data)& aData) const
335 {
336  if (aData.IsNull()) return;
337
338   // add all the persistent to write...
339   //
340   Standard_Integer                 posfrom,posto;
341   Handle(Standard_Persistent)      p;
342   Handle(Storage_HSeqOfRoot)       plist;
343   TCollection_AsciiString          errorContext("AddPersistent");
344   Storage_Schema::ISetCurrentData(aData);
345
346   Handle(Storage_InternalData) iData = aData->InternalData();
347
348   aData->Clear();
349   aData->ClearErrorStatus();
350
351   plist = aData->Roots();
352
353   for (posto = 1; posto <= plist->Length(); posto++) {
354     PersistentToAdd(plist->Value(posto)->Object());
355   }
356
357   for (posto = 1; posto <= plist->Length(); posto++) {
358     AddTypeSelection(plist->Value(posto)->Object());
359   }
360
361   for (posfrom = plist->Length() + 1; posfrom <= iData->myPtoA.Length(); posfrom++) {
362     AddTypeSelection(iData->myPtoA.Value(posfrom));
363   }
364
365   // ...and now we write
366   //
367   Standard_Integer            i,
368                               len;
369
370  aData->HeaderData()->SetCreationDate(ICreationDate());
371  aData->HeaderData()->SetStorageVersion(Storage::Version());
372  aData->HeaderData()->SetNumberOfObjects(iData->myPtoA.Length());
373  aData->HeaderData()->SetSchemaName(myName);
374  aData->HeaderData()->SetSchemaVersion(myVersion);
375
376   if ((f.OpenMode() == Storage_VSWrite) || (f.OpenMode() == Storage_VSReadWrite)) {
377     try {
378       OCC_CATCH_SIGNALS
379       errorContext = "BeginWriteInfoSection";
380       f.BeginWriteInfoSection();
381       errorContext = "WriteInfo";
382       f.WriteInfo(aData->NumberOfObjects(),
383                   aData->StorageVersion(),
384                   aData->CreationDate(),
385                   aData->SchemaName(),
386                   aData->SchemaVersion(),
387                   aData->ApplicationName(),
388                   aData->ApplicationVersion(),
389                   aData->DataType(),
390                   aData->UserInfo());
391       errorContext = "EndWriteInfoSection";
392       f.EndWriteInfoSection();
393
394       errorContext = "BeginWriteCommentSection";
395       f.BeginWriteCommentSection();
396       errorContext = "WriteComment";
397       f.WriteComment(aData->Comments());
398       errorContext = "EndWriteCommentSection";
399       f.EndWriteCommentSection();
400
401       Handle(TColStd_HSequenceOfAsciiString) tlist;
402
403       tlist = aData->Types();
404
405       errorContext = "BeginWriteTypeSection";
406       f.BeginWriteTypeSection();
407       len = aData->NumberOfTypes();
408
409       Handle(Storage_HArrayOfCallBack) WFunc = new Storage_HArrayOfCallBack(1,len);
410
411       f.SetTypeSectionSize(len);
412
413       Storage_DataMapIteratorOfMapOfCallBack cbit(iData->myTypeBinding);
414       Handle(Storage_TypedCallBack) atcallBack;
415
416       for (; cbit.More(); cbit.Next()) {
417         atcallBack = cbit.Value();
418         WFunc->SetValue(atcallBack->Index(),atcallBack->CallBack());
419       }
420
421       errorContext = "WriteTypeInformations";
422       for (i = 1; i <= len; i++) {
423         f.WriteTypeInformations(i,tlist->Value(i).ToCString());
424       }
425
426       errorContext = "EndWriteTypeSection";
427       f.EndWriteTypeSection();
428
429       errorContext = "BeginWriteRootSection";
430       f.BeginWriteRootSection();
431       f.SetRootSectionSize(plist->Length());
432
433       errorContext = "WriteRoot";
434       for (i = 1; i <= plist->Length(); i++) {
435         f.WriteRoot(plist->Value(i)->Name(),i,plist->Value(i)->Type());
436       }
437
438       errorContext = "EndWriteRootSection";
439       f.EndWriteRootSection();
440
441       errorContext = "BeginWriteRefSection";
442       f.BeginWriteRefSection();
443       f.SetRefSectionSize(iData->myObjId - 1);
444       errorContext = "WriteReferenceType";
445
446       Storage_BucketIterator bit(&iData->myPtoA);
447
448       while(bit.More()) {
449         p = bit.Value();
450         if (!p.IsNull()) f.WriteReferenceType(p->_refnum,p->_typenum);
451         bit.Next();
452       }
453
454       errorContext = "EndWriteRefSection";
455       f.EndWriteRefSection();
456
457       errorContext = "BeginWriteDataSection";
458       f.BeginWriteDataSection();
459
460       Handle(Storage_Schema) me = this;
461
462       errorContext = "Write";
463
464       bit.Reset();
465
466       while(bit.More()) {
467         p = bit.Value();
468         if (!p.IsNull()) {
469           WFunc->Value(p->_typenum)->Write(p,f,me);
470           p->_typenum = 0;
471         }
472         bit.Next();
473       }
474
475       errorContext = "EndWriteDataSection";
476       f.EndWriteDataSection();
477     }
478     catch(Storage_StreamWriteError) {
479       aData->SetErrorStatus(Storage_VSWriteError);
480       aData->SetErrorStatusExtension(errorContext);
481     }
482   }
483   else {
484     aData->SetErrorStatus(Storage_VSModeError);
485     aData->SetErrorStatusExtension("OpenMode");
486   }
487
488   iData->Clear();
489   Clear();
490 }
491
492 //=======================================================================
493 //function : Read
494 //purpose  : ...and read a Storage file
495 //Arguments:
496 //           s: driver to read
497 //=======================================================================
498
499 Handle(Storage_Data) Storage_Schema::Read(Storage_BaseDriver& f) const
500 {
501   Handle(Storage_Data)          dData = new Storage_Data;
502   Storage_Error                errorCode;
503 static Standard_Boolean             result;
504 static Standard_Integer             len;
505 static Standard_Integer             i;
506   i = 0 ;
507   Handle(Standard_Persistent)  per;
508   Handle(Storage_HArrayOfCallBack) theCallBack;
509
510   Handle(Storage_InternalData) iData = dData->InternalData();
511   Handle(Storage_TypeData)     tData = dData->TypeData();
512   Handle(Storage_RootData)     rData = dData->RootData();
513   Handle(Storage_HeaderData)   hData = dData->HeaderData();
514
515   if ((f.OpenMode() == Storage_VSRead) || (f.OpenMode() == Storage_VSReadWrite)) {
516
517     Storage_Schema::ISetCurrentData(dData);
518
519     // IReadHeaderSection can set an error status
520     //
521     result = IReadHeaderSection(f,hData);
522
523     if (result) {
524       Handle(Storage_CallBack) accallBack;
525       Standard_Integer            p;
526       TCollection_AsciiString     typeName;
527
528       iData->myReadArray = new Storage_HPArray(1,dData->NumberOfObjects());
529
530       // IReadTypeSection can set an error status
531       //
532       result = IReadTypeSection(f,tData);
533
534       if (result) {
535         len = dData->NumberOfTypes();
536         theCallBack = new Storage_HArrayOfCallBack(1,len);
537         {
538           try {
539             OCC_CATCH_SIGNALS
540             for (i = 1; i <= len; i++) {
541               typeName = tData->Type(i);
542               p = tData->Type(typeName);
543               theCallBack->SetValue(p,CallBackSelection(typeName));
544             }
545           }
546           catch(Storage_StreamUnknownTypeError) {
547             result = Standard_False;
548             dData->SetErrorStatus(Storage_VSUnknownType);
549             dData->SetErrorStatusExtension(typeName);
550           }
551         }
552       }
553       else {
554         dData->SetErrorStatus(tData->ErrorStatus());
555         dData->SetErrorStatusExtension(tData->ErrorStatusExtension());
556       }
557     }
558     else {
559       dData->SetErrorStatus(hData->ErrorStatus());
560       dData->SetErrorStatusExtension(hData->ErrorStatusExtension());
561     }
562
563     if (result) {
564       result = IReadRootSection(f,rData);
565       dData->SetErrorStatus(rData->ErrorStatus());
566       if (!result) dData->SetErrorStatusExtension(rData->ErrorStatusExtension());
567     }
568
569     if (result) {
570       Standard_Integer otype,oref;
571
572       errorCode = f.BeginReadRefSection();
573
574       if (errorCode == Storage_VSOk) {
575         {
576           try {
577             OCC_CATCH_SIGNALS
578             len = f.RefSectionSize();
579
580             for (i = 1; i <= len; i++) {
581               f.ReadReferenceType(oref,otype);
582               iData->myReadArray->ChangeValue(oref) = theCallBack->Value(otype)->New();
583               if (!iData->myReadArray->ChangeValue(oref).IsNull()) iData->myReadArray->ChangeValue(oref)->_typenum = otype;
584             }
585           }
586           catch(Storage_StreamTypeMismatchError) {
587             TCollection_AsciiString aOref = oref;
588             result = Standard_False;
589             dData->SetErrorStatus(Storage_VSTypeMismatch);
590             dData->SetErrorStatusExtension(aOref);
591           }
592         }
593
594         if (result) {
595           errorCode = f.EndReadRefSection();
596           result = (errorCode == Storage_VSOk);
597           dData->SetErrorStatus(errorCode);
598           if (!result) dData->SetErrorStatusExtension("EndReadRefSection");
599         }
600       }
601       else {
602         result = Standard_False;
603         dData->SetErrorStatus(errorCode);
604         dData->SetErrorStatusExtension("BeginReadRefSection");
605       }
606     }
607
608     if (result) {
609       errorCode = f.BeginReadDataSection();
610       result = (errorCode == Storage_VSOk);
611       dData->SetErrorStatus(errorCode);
612       if (!result) dData->SetErrorStatusExtension("BeginReadDataSection");
613     }
614
615     if (result) {
616       Handle(Storage_Schema) me = this;
617       Handle(Storage_CallBack) rcback;
618
619       {
620         try {
621           OCC_CATCH_SIGNALS
622           for (i = 1; i <= dData->NumberOfObjects(); i++) {
623             Handle(Standard_Persistent) pobj = iData->myReadArray->Value(i);
624             if (!pobj.IsNull()) {
625               rcback = theCallBack->Value(pobj->_typenum);
626               rcback->Read(pobj,f,me);
627               pobj->_typenum = 0;
628             }
629           }
630         }
631         catch(Storage_StreamTypeMismatchError) {
632           result = Standard_False;
633           dData->SetErrorStatus(Storage_VSTypeMismatch);
634           dData->SetErrorStatusExtension(i-1);
635         }
636         catch(Storage_StreamFormatError) {
637           result = Standard_False;
638           dData->SetErrorStatus(Storage_VSFormatError);
639           dData->SetErrorStatusExtension(i-1);
640         }
641         catch(Storage_StreamReadError) {
642           result = Standard_False;
643           dData->SetErrorStatus(Storage_VSFormatError);
644           dData->SetErrorStatusExtension(i-1);
645         }
646       }
647
648       if (result) {
649         Handle(Storage_HSeqOfRoot) rlist = rData->Roots();
650         Handle(Storage_Root)       rroot;
651
652         for(i = 1; i <= dData->NumberOfRoots(); i++) {
653           rroot = rlist->Value(i);
654           rData->UpdateRoot(rroot->Name(),iData->myReadArray->Value(rroot->Reference()));
655         }
656
657         errorCode = f.EndReadDataSection();
658         result = (errorCode == Storage_VSOk);
659         dData->SetErrorStatus(errorCode);
660         if (!result) dData->SetErrorStatusExtension("EndReadDataSection");
661       }
662     }
663   }
664   else {
665     dData->SetErrorStatus(Storage_VSModeError);
666     dData->SetErrorStatusExtension("OpenMode");
667   }
668
669   iData->Clear();
670   Clear();
671
672   return dData;
673 }
674
675 //=======================================================================
676 //function : ReadHeaderSection
677 //purpose  : read the header part of the stream
678 //Arguments:
679 //           s: driver to read
680 //=======================================================================
681
682 Handle(Storage_HeaderData) Storage_Schema::ReadHeaderSection
683                          (Storage_BaseDriver& s) const
684 {
685   Handle(Storage_HeaderData) result = new Storage_HeaderData;
686
687   if ((s.OpenMode() == Storage_VSRead) || (s.OpenMode() == Storage_VSReadWrite)) {
688     IReadHeaderSection(s,result);
689   }
690   else {
691     result->SetErrorStatus(Storage_VSModeError);
692     result->SetErrorStatusExtension("OpenMode");
693   }
694
695   return result;
696 }
697
698 //=======================================================================
699 //function : ReadTypeSection
700 //purpose  : fill the TypeData with the  names of the type used
701 //           in a stream
702 //Arguments:
703 //           s: driver to read
704 //=======================================================================
705
706 Handle(Storage_TypeData) Storage_Schema::ReadTypeSection
707                          (Storage_BaseDriver& f) const
708 {
709   Handle(Storage_TypeData) result = new Storage_TypeData;
710
711   if ((f.OpenMode() == Storage_VSRead) || (f.OpenMode() == Storage_VSReadWrite)) {
712     IReadTypeSection(f,result);
713   }
714   else {
715     result->SetErrorStatus(Storage_VSModeError);
716     result->SetErrorStatusExtension("OpenMode");
717   }
718
719   return result;
720 }
721
722 //=======================================================================
723 //function : ReadRootSection
724 //purpose  : read root part of the file
725 //Arguments:
726 //           s: driver to read
727 //=======================================================================
728
729 Handle(Storage_RootData) Storage_Schema::ReadRootSection
730                          (Storage_BaseDriver& f) const
731 {
732   Handle(Storage_RootData) result = new Storage_RootData;
733
734   if ((f.OpenMode() == Storage_VSRead) || (f.OpenMode() == Storage_VSReadWrite)) {
735     IReadRootSection(f,result);
736   }
737   else {
738     result->SetErrorStatus(Storage_VSModeError);
739     result->SetErrorStatusExtension("OpenMode");
740   }
741
742   return result;
743 }
744
745 //=======================================================================
746 //function : SchemaKnownTypes
747 //purpose  : returns the known types of a schema
748 //=======================================================================
749
750 const TColStd_SequenceOfAsciiString& Storage_Schema::SchemaKnownTypes() const
751 {
752   static TColStd_SequenceOfAsciiString aSeq;
753   return aSeq;
754 }
755
756 //=======================================================================
757 //function : GetAllSchemaKnownTypes
758 //purpose  : returns the all known types  of a schema and their
759 //           nested schemes.
760 //PTV      : add get of all known type for inheritance of schemas
761 //=======================================================================
762
763 Handle(TColStd_HSequenceOfAsciiString) Storage_Schema::
764                           GetAllSchemaKnownTypes() const
765 {
766   Handle(TColStd_HSequenceOfAsciiString) aSeqOfType = new TColStd_HSequenceOfAsciiString;
767   const TColStd_SequenceOfAsciiString& alocalTypeList = SchemaKnownTypes();
768
769   for (Standard_Integer k = 1; k <= alocalTypeList.Length(); k++)
770     aSeqOfType->Append(alocalTypeList.Value(k));
771
772   // get nested schemas
773   Handle(Storage_HArrayOfSchema) aNestedSchemas = NestedSchemas();
774   if (!aNestedSchemas.IsNull())
775   {
776     for (Standard_Integer i = aNestedSchemas->Lower(); i <= aNestedSchemas->Upper(); i++)
777     {
778       Handle(Storage_Schema) aSchema = aNestedSchemas->Value(i);
779       if (aSchema.IsNull())
780         continue;
781
782       Handle(TColStd_HSequenceOfAsciiString) typeList = aSchema->GetAllSchemaKnownTypes();
783       for (Standard_Integer j = 1; j <= typeList->Length(); j++)
784         aSeqOfType->Append(typeList->Value(j));
785     }
786   }
787
788   return aSeqOfType;
789 }
790
791 //=======================================================================
792 //function : HasUnknownType
793 //purpose  : indicates whether  the  are  types  in  the driver
794 //           which are not known from  the schema and for which
795 //           no callbacks have been set. The unknown types can
796 //           be read in <theUnknownTypes>.
797 //=======================================================================
798
799 Standard_Boolean Storage_Schema::HasUnknownType
800                          (Storage_BaseDriver& f,
801                           TColStd_SequenceOfAsciiString& theUnknownTypes) const
802 {
803   Standard_Boolean result = Standard_False;
804   Handle(TColStd_HSequenceOfAsciiString) typeList = GetAllSchemaKnownTypes();
805
806   Handle(Storage_TypeData) tData;
807
808   tData = ReadTypeSection(f);
809
810   result = (tData->ErrorStatus() != Storage_VSOk);
811
812   if (!result) {
813     Standard_Integer i;
814     TColStd_MapOfAsciiString names;
815
816     for (i = 1; i <= typeList->Length(); i++) {
817       names.Add(typeList->Value(i));
818     }
819
820     Handle(TColStd_HSequenceOfAsciiString) flist = tData->Types();
821
822     for (i = 1; i <= flist->Length(); i++) {
823       if (!names.Contains(flist->Value(i))) {
824         theUnknownTypes.Append(flist->Value(i));
825         result = Standard_True;
826       }
827     }
828   }
829
830   return result;
831 }
832
833 //=======================================================================
834 //function : SetNestedSchemas
835 //purpose  : 
836 //=======================================================================
837
838 void Storage_Schema::SetNestedSchemas
839                          (const Handle(Storage_HArrayOfSchema)& theSchemas)
840 {
841   myArrayOfSchema = theSchemas;
842 }
843
844 //=======================================================================
845 //function : ClearNestedSchemas
846 //purpose  : 
847 //=======================================================================
848
849 void Storage_Schema::ClearNestedSchemas()
850 {
851   myArrayOfSchema.Nullify();
852 }
853
854 //=======================================================================
855 //function : NestedSchemas
856 //purpose  : 
857 //=======================================================================
858
859 Handle(Storage_HArrayOfSchema) Storage_Schema::NestedSchemas() const
860 {
861   return myArrayOfSchema;
862 }
863
864 //=======================================================================
865 //function : AddReadUnknownTypeCallBack
866 //purpose  : add two functions to the callback list
867 //=======================================================================
868
869 void Storage_Schema::AddReadUnknownTypeCallBack
870                          (const TCollection_AsciiString& aTypeName,
871                           const Handle(Storage_CallBack)& aCallBack)
872 {
873   if (!aCallBack.IsNull()) {
874      Handle(Storage_TypedCallBack) aTCallBack = new Storage_TypedCallBack(aTypeName,aCallBack);
875
876      myCallBack.Bind(aTypeName,aTCallBack);
877   }
878 }
879
880 //=======================================================================
881 //function : RemoveReadUnknownTypeCallBack
882 //purpose  : remove a callback for a type
883 //=======================================================================
884
885 void Storage_Schema::RemoveReadUnknownTypeCallBack
886                          (const TCollection_AsciiString& aTypeName)
887 {
888   if (myCallBack.IsBound(aTypeName)) {
889     myCallBack.UnBind(aTypeName);
890   }
891 }
892
893 //=======================================================================
894 //function : InstalledCallBackList
895 //purpose  : returns  a  list  of   type  name  with  installed
896 //           callback.
897 //=======================================================================
898
899 Handle(TColStd_HSequenceOfAsciiString) Storage_Schema::
900                           InstalledCallBackList() const
901 {
902   Storage_DataMapIteratorOfMapOfCallBack it(myCallBack);
903   Handle(TColStd_HSequenceOfAsciiString) result = new TColStd_HSequenceOfAsciiString;
904
905   for (; it.More(); it.Next()) {
906     result->Append(it.Key());
907   }
908
909   return result;
910 }
911
912 //=======================================================================
913 //function : ClearCallBackList
914 //purpose  : clear all callback from schema instance.
915 //=======================================================================
916
917 void Storage_Schema::ClearCallBackList()
918 {
919   myCallBack.Clear();
920 }
921
922 //=======================================================================
923 //function : UseDefaultCallBack
924 //purpose  : install  a  callback  for  all  unknown  type. the
925 //           objects with unknown types  will be skipped. (look
926 //           SkipObject method in BaseDriver)
927 //=======================================================================
928
929 void Storage_Schema::UseDefaultCallBack()
930 {
931   myCallBackState = Standard_True;
932 }
933
934 //=======================================================================
935 //function : DontUseDefaultCallBack
936 //purpose  : tells schema to uninstall the default callback.
937 //=======================================================================
938
939 void Storage_Schema::DontUseDefaultCallBack()
940 {
941   myCallBackState = Standard_False;
942 }
943
944 //=======================================================================
945 //function : IsUsingDefaultCallBack
946 //purpose  : ask if the schema is using the default callback.
947 //=======================================================================
948
949 Standard_Boolean Storage_Schema::IsUsingDefaultCallBack() const
950 {
951   return myCallBackState;
952 }
953
954 //=======================================================================
955 //function : SetDefaultCallBack
956 //purpose  : overload the  default  function  for build.(use to
957 //           set an  error  message  or  skip  an  object while
958 //           reading an unknown type).
959 //=======================================================================
960
961 void Storage_Schema::SetDefaultCallBack(const Handle(Storage_CallBack)& f)
962 {
963   myDefaultCallBack = f;
964 }
965
966 //=======================================================================
967 //function : ResetDefaultCallBack
968 //purpose  : reset  the  default  function  defined  by Storage
969 //           package.
970 //=======================================================================
971
972 void Storage_Schema::ResetDefaultCallBack()
973 {
974   myDefaultCallBack = new Storage_DefaultCallBack;
975 }
976
977 //=======================================================================
978 //function : DefaultCallBack
979 //purpose  : returns   the   read   function   used   when  the
980 //           UseDefaultCallBack() is set.
981 //=======================================================================
982
983 Handle(Storage_CallBack) Storage_Schema::DefaultCallBack() const
984 {
985   return myDefaultCallBack;
986 }
987
988 //=======================================================================
989 //function : ResolveUnknownType
990 //purpose  : 
991 //=======================================================================
992
993 Handle(Storage_CallBack) Storage_Schema::ResolveUnknownType
994                          (const TCollection_AsciiString&     aTypeName,
995                           const Handle(Standard_Persistent)& p,
996                           const Storage_SolveMode            aMode) const
997 {
998   Handle(Storage_CallBack) theCallBack;
999
1000   if (!myArrayOfSchema.IsNull()) {
1001     Standard_Integer i;
1002     Standard_Boolean IsNotFound     = Standard_True;
1003     Standard_Boolean AlreadyMatched;
1004
1005     for(i = myArrayOfSchema->Lower(); i <= myArrayOfSchema->Upper() && IsNotFound; i++) {
1006       Handle(Storage_Schema) aSchema = myArrayOfSchema->Value(i);
1007
1008       if (!aSchema.IsNull()) {
1009         AlreadyMatched = aSchema->SetNested();
1010         if (!AlreadyMatched) {
1011           if (aMode == Storage_WriteSolve || aMode == Storage_ReadSolve) {
1012             theCallBack = aSchema->CallBackSelection(aTypeName);
1013           }
1014           else if (aMode == Storage_AddSolve) {
1015             theCallBack = aSchema->AddTypeSelection(p);
1016           }
1017           aSchema->UnsetNested();
1018           IsNotFound = theCallBack.IsNull();
1019         }
1020       }
1021     }
1022   }
1023
1024   if (!myNestedState && theCallBack.IsNull()) {
1025     if (myCallBack.IsBound(aTypeName)) {
1026       theCallBack = myCallBack.Find(aTypeName)->CallBack();
1027     }
1028     else if (myCallBackState == Standard_True) {
1029       theCallBack = myDefaultCallBack;
1030     }
1031     else {
1032       Clear();
1033       Standard_SStream aMsg;
1034
1035       aMsg << "Unknown type " << aTypeName << " in schema ";
1036
1037       if (!myName.IsEmpty()) {
1038         aMsg << myName;
1039       }
1040
1041       Storage_StreamUnknownTypeError::Raise(aMsg);
1042     }
1043   }
1044
1045   return theCallBack;
1046 }
1047
1048 //=======================================================================
1049 //function : CallBackSelection
1050 //purpose  : 
1051 //=======================================================================
1052
1053 Handle(Storage_CallBack) Storage_Schema::CallBackSelection
1054                          (const TCollection_AsciiString&) const
1055 {
1056   Handle(Storage_CallBack) theCallBack;
1057
1058   return theCallBack;
1059 }
1060
1061 //=======================================================================
1062 //function : AddTypeSelection
1063 //purpose  : 
1064 //=======================================================================
1065
1066 Handle(Storage_CallBack)  Storage_Schema::AddTypeSelection
1067                          (const Handle(Standard_Persistent)&) const
1068 {
1069   Handle(Storage_CallBack) theCallBack;
1070
1071   return theCallBack;
1072 }
1073
1074 //=======================================================================
1075 //function : BindType
1076 //purpose  : 
1077 //=======================================================================
1078
1079 void Storage_Schema::BindType
1080                          (const TCollection_AsciiString& aTypeName,
1081                           const Handle(Storage_CallBack)& aCallBack) const
1082 {
1083   if (!HasTypeBinding(aTypeName)) {
1084       Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
1085       Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
1086       Handle(Storage_TypedCallBack) c = new Storage_TypedCallBack(aTypeName,aCallBack);
1087
1088       tData->AddType(aTypeName,iData->myTypeId);
1089       c->SetIndex(iData->myTypeId++);
1090       iData->myTypeBinding.Bind(aTypeName,c);
1091   }
1092 }
1093
1094 //=======================================================================
1095 //function : TypeBinding
1096 //purpose  : 
1097 //=======================================================================
1098
1099 Handle(Storage_CallBack) Storage_Schema::TypeBinding
1100                          (const TCollection_AsciiString& aTypeName) const
1101 {
1102   Handle(Storage_CallBack) result;
1103
1104   if (HasTypeBinding(aTypeName)) {
1105     Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
1106
1107     result =  iData->myTypeBinding.Find(aTypeName)->CallBack();
1108   }
1109
1110   return result;
1111 }
1112
1113 //=======================================================================
1114 //function : ReadPersistentReference
1115 //purpose  : 
1116 //=======================================================================
1117
1118 void Storage_Schema::ReadPersistentReference
1119                          (Handle(Standard_Persistent)& sp,
1120                           Storage_BaseDriver&          f)
1121 {
1122   Standard_Integer ref;
1123
1124   f.GetReference(ref);
1125
1126   if (ref != 0) {
1127     Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
1128
1129     sp = iData->myReadArray->Value(ref);
1130   }
1131   else {
1132     sp.Nullify();
1133   }
1134 }
1135
1136 //=======================================================================
1137 //function : AddPersistent
1138 //purpose  : 
1139 //=======================================================================
1140
1141 Standard_Boolean Storage_Schema::AddPersistent
1142                          (const Handle(Standard_Persistent)& sp,
1143                           const Standard_CString tName) const
1144 {
1145   Standard_Boolean result = Standard_False;
1146
1147   if (!sp.IsNull()) {
1148     Handle(Storage_InternalData)     iData = Storage_Schema::ICurrentData()->InternalData();
1149
1150     if (sp->_typenum == 0) {
1151       Standard_Integer         aTypenum;
1152       static TCollection_AsciiString  aTypeName;
1153       aTypeName = tName;
1154       Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
1155
1156       aTypenum = iData->myTypeBinding.Find(aTypeName)->Index();
1157
1158       sp->_typenum = aTypenum;
1159       sp->_refnum = iData->myObjId++;
1160
1161       result = Standard_True;
1162     }
1163   }
1164
1165   return result;
1166 }
1167
1168 //=======================================================================
1169 //function : PersistentToAdd
1170 //purpose  : 
1171 //=======================================================================
1172
1173 Standard_Boolean Storage_Schema::PersistentToAdd
1174                          (const Handle(Standard_Persistent)& sp) const
1175 {
1176  Standard_Boolean result = Standard_False;
1177
1178   if (!sp.IsNull()) {
1179     Handle(Storage_InternalData) di = Storage_Schema::ICurrentData()->InternalData();
1180
1181     if (sp->_typenum == 0 && sp->_refnum != -1) {
1182       result = Standard_True;
1183       sp->_refnum = -1;
1184       di->myPtoA.Append(sp);
1185     }
1186   }
1187
1188   return result;
1189 }
1190
1191 //=======================================================================
1192 //function : Clear
1193 //purpose  : 
1194 //=======================================================================
1195
1196 void Storage_Schema::Clear() const
1197 {
1198   Storage_Schema::ICurrentData().Nullify();
1199 }
1200
1201 //=======================================================================
1202 //function : IReadHeaderSection
1203 //purpose  : 
1204 //=======================================================================
1205
1206 Standard_Boolean Storage_Schema::IReadHeaderSection
1207                          (Storage_BaseDriver& f,
1208                           const Handle(Storage_HeaderData)& iData) const
1209 {
1210   Standard_Boolean                 result = Standard_False;
1211   Storage_Error                    errorCode;
1212   TCollection_AsciiString          uinfo,mStorageVersion,mDate,mSchemaName,mSchemaVersion,mApplicationVersion;
1213   TCollection_ExtendedString       mApplicationName,mDataType;
1214   TColStd_SequenceOfAsciiString    mUserInfo;
1215   TColStd_SequenceOfExtendedString mComment;
1216   Standard_Integer                 mNBObj;
1217
1218   errorCode = f.BeginReadInfoSection();
1219
1220   if (errorCode == Storage_VSOk) {
1221     {
1222       try {
1223         OCC_CATCH_SIGNALS
1224         f.ReadInfo(mNBObj,
1225                    mStorageVersion,
1226                    mDate,
1227                    mSchemaName,
1228                    mSchemaVersion,
1229                    mApplicationName,
1230                    mApplicationVersion,
1231                    mDataType,
1232                    mUserInfo);
1233       }
1234       catch(Storage_StreamTypeMismatchError) {
1235         iData->SetErrorStatus(Storage_VSTypeMismatch);
1236         iData->SetErrorStatusExtension("ReadInfo");
1237         return Standard_False;
1238       }
1239       catch(Storage_StreamExtCharParityError) {
1240         iData->SetErrorStatus(Storage_VSExtCharParityError);
1241         iData->SetErrorStatusExtension("ReadInfo");
1242         return Standard_False;
1243       }
1244     }
1245
1246
1247     errorCode = f.EndReadInfoSection();
1248
1249     iData->SetErrorStatus(errorCode);
1250
1251     result = (errorCode == Storage_VSOk);
1252
1253     if (result) {
1254       Standard_Integer i;
1255
1256       iData->SetNumberOfObjects(mNBObj);
1257       iData->SetStorageVersion(mStorageVersion);
1258       iData->SetCreationDate(mDate);
1259       iData->SetSchemaName(mSchemaName);
1260       iData->SetSchemaVersion(mSchemaVersion);
1261       iData->SetApplicationName(mApplicationName);
1262       iData->SetApplicationVersion(mApplicationVersion);
1263       iData->SetDataType(mDataType);
1264
1265       for (i = 1; i <= mUserInfo.Length(); i++) {
1266         iData->AddToUserInfo(mUserInfo.Value(i));
1267       }
1268
1269       errorCode = f.BeginReadCommentSection();
1270
1271       if (errorCode == Storage_VSOk) {
1272         {
1273           {
1274             try {
1275               OCC_CATCH_SIGNALS
1276               f.ReadComment(mComment);
1277             }
1278             catch(Storage_StreamTypeMismatchError) {
1279               iData->SetErrorStatus(Storage_VSTypeMismatch);
1280               iData->SetErrorStatusExtension("ReadComment");
1281               return Standard_False;
1282             }
1283             catch(Storage_StreamExtCharParityError) {
1284               iData->SetErrorStatus(Storage_VSExtCharParityError);
1285               iData->SetErrorStatusExtension("ReadComment");
1286               return Standard_False;
1287             }
1288           }
1289         }
1290
1291         errorCode = f.EndReadCommentSection();
1292         iData->SetErrorStatus(errorCode);
1293         iData->SetErrorStatusExtension("EndReadCommentSection");
1294         result = (errorCode == Storage_VSOk);
1295
1296         if (result) {
1297           for (i = 1; i <= mComment.Length(); i++) {
1298             iData->AddToComments(mComment.Value(i));
1299           }
1300         }
1301       }
1302       else {
1303         result = Standard_False;
1304         iData->SetErrorStatus(errorCode);
1305         iData->SetErrorStatusExtension("BeginReadCommentSection");
1306      }
1307     }
1308     else {
1309       iData->SetErrorStatusExtension("EndReadInfoSection");
1310     }
1311   }
1312   else {
1313     iData->SetErrorStatus(errorCode);
1314     iData->SetErrorStatusExtension("BeginReadInfoSection");
1315   }
1316
1317   return result;
1318 }
1319
1320
1321 #ifdef DATATYPE_MIGRATION
1322 //=======================================================================
1323 // environment variable CSF_MIGRATION_TYPES should define full path of a file
1324 // containing migration types table: oldtype - newtype
1325 //=======================================================================
1326 Standard_Boolean Storage_Schema::CheckTypeMigration(
1327                                   const TCollection_AsciiString&  oldName,
1328                                   TCollection_AsciiString&  newName)
1329 {
1330   static Standard_Boolean isChecked(Standard_False);
1331   static DataMapOfAStringAString aDMap;
1332   Standard_Boolean aMigration(Standard_False);
1333   
1334   if(!isChecked) {
1335     isChecked = Standard_True;
1336 //    TCollection_AsciiString aFileName = getenv("CSF_MIGRATION_TYPES");
1337     OSD_Environment csf(TCollection_AsciiString("CSF_MIGRATION_TYPES"));
1338     TCollection_AsciiString aFileName = csf.Value();
1339     if(aFileName.Length() > 0) {
1340       OSD_Path aPath(aFileName,OSD_Default);
1341       OSD_File aFile;
1342       aFile.SetPath(aPath);
1343       if(aFile.Exists()) {
1344         OSD_Protection aProt(OSD_R,OSD_R,OSD_R,OSD_R);
1345         aFile.Open(OSD_ReadOnly, aProt);
1346         if(aFile.IsOpen() && aFile.IsReadable()) {
1347           TCollection_AsciiString aLine;
1348           Standard_Integer aNbReaded(0);
1349           while (1) {
1350             aFile.ReadLine(aLine, 80, aNbReaded);
1351             if(aFile.IsAtEnd() || !aNbReaded) {
1352               aFile.Close();
1353               break;
1354             }
1355 #ifdef DATATYPE_MIGRATION_DEB
1356             cout << "Storage_Sheme:: Line: = " << aLine <<endl;
1357 #endif
1358             TCollection_AsciiString aKey, aValue;
1359             aKey = aLine.Token();
1360             aValue = aLine.Token(" \t\n\r", 2);
1361             aDMap.Bind(aKey, aValue);
1362           }
1363         }
1364       }
1365 #ifdef DATATYPE_MIGRATION_DEB
1366       cout << "Storage_Sheme:: aDataMap.Size = " << aDMap.Extent() <<endl;
1367 #endif
1368     }
1369   }
1370
1371   if(aDMap.Extent()) {
1372     if(aDMap.IsBound(oldName)) {
1373       newName.Clear();
1374       newName = aDMap.Find(oldName);
1375       aMigration = Standard_True;
1376 #ifdef DATATYPE_MIGRATION_DEB
1377       cout << " newName = " << newName << endl;
1378 #endif
1379     }
1380   } 
1381   return aMigration;
1382 }
1383 #endif
1384
1385 //=======================================================================
1386 //function : IReadTypeSection
1387 //purpose  : 
1388 //=======================================================================
1389
1390 Standard_Boolean Storage_Schema::IReadTypeSection
1391                          (Storage_BaseDriver& f,
1392                           const Handle(Storage_TypeData)& tData) const
1393 {
1394 static Standard_Boolean         result;
1395   TCollection_AsciiString  typeName;
1396   Standard_Integer         typeNum;
1397
1398   Storage_Error      errorCode;
1399   Standard_Integer len,i;
1400
1401   result = Standard_False;
1402   errorCode = f.BeginReadTypeSection();
1403
1404   if (errorCode == Storage_VSOk) {
1405     try {
1406       OCC_CATCH_SIGNALS
1407       len = f.TypeSectionSize();
1408
1409       for (i = 1; i <= len; i++) {
1410         f.ReadTypeInformations(typeNum,typeName);
1411 #ifdef DATATYPE_MIGRATION
1412         TCollection_AsciiString  newName;       
1413         if(CheckTypeMigration(typeName, newName)) {
1414 #ifdef DATATYPE_MIGRATION_DEB
1415           cout << "CheckTypeMigration:OldType = " <<typeName << " Len = "<<typeName.Length()<<endl;
1416           cout << "CheckTypeMigration:NewType = " <<newName  << " Len = "<< newName.Length()<<endl;
1417 #endif
1418           typeName = newName;
1419         }
1420 #endif
1421         tData->AddType(typeName,typeNum);
1422       }
1423       result = Standard_True;
1424     }
1425     catch(Storage_StreamTypeMismatchError) {
1426       tData->SetErrorStatus(Storage_VSTypeMismatch);
1427       tData->SetErrorStatusExtension("ReadTypeInformations");
1428       return Standard_False;
1429     }
1430
1431     if (result) {
1432       errorCode = f.EndReadTypeSection();
1433       result = (errorCode == Storage_VSOk);
1434
1435       tData->SetErrorStatus(errorCode);
1436       if (!result) tData->SetErrorStatusExtension("EndReadTypeSection");
1437     }
1438   }
1439   else {
1440     tData->SetErrorStatus(errorCode);
1441     tData->SetErrorStatusExtension("BeginReadTypeSection");
1442   }
1443
1444   return result;
1445 }
1446
1447 //=======================================================================
1448 //function : IReadRootSection
1449 //purpose  : 
1450 //=======================================================================
1451
1452 Standard_Boolean Storage_Schema::IReadRootSection
1453                          (Storage_BaseDriver& f,
1454                           const Handle(Storage_RootData)& rData) const
1455 {
1456 static Standard_Boolean            result;
1457   Standard_Integer            len,i,ref;
1458   Storage_Error               errorCode;
1459   Handle(Standard_Persistent) p;
1460   Handle(Storage_Root)        aRoot;
1461
1462   result = Standard_False;
1463   errorCode = f.BeginReadRootSection();
1464
1465   if (errorCode == Storage_VSOk) {
1466     TCollection_AsciiString rootName,typeName;
1467
1468     try {
1469       OCC_CATCH_SIGNALS
1470       len = f.RootSectionSize();
1471
1472       for (i = 1; i <= len; i++) {
1473         f.ReadRoot(rootName,ref,typeName);
1474         aRoot = new Storage_Root(rootName,p);
1475         aRoot->SetReference(ref);
1476         aRoot->SetType(typeName);
1477         rData->AddRoot(aRoot);
1478       }
1479       result = Standard_True;
1480     }
1481     catch(Storage_StreamTypeMismatchError) {
1482       result = Standard_False;
1483       rData->SetErrorStatus(Storage_VSTypeMismatch);
1484       rData->SetErrorStatusExtension("ReadRoot");
1485     }
1486
1487     if (result) {
1488       errorCode = f.EndReadRootSection();
1489       result = (errorCode == Storage_VSOk);
1490
1491       rData->SetErrorStatus(errorCode);
1492       if (!result) rData->SetErrorStatusExtension("EndReadRootSection");
1493     }
1494   }
1495   else {
1496     rData->SetErrorStatus(errorCode);
1497     rData->SetErrorStatusExtension("BeginReadRootSection");
1498   }
1499
1500   return result;
1501 }
1502
1503 //=======================================================================
1504 //function : ISetCurrentData
1505 //purpose  : 
1506 //=======================================================================
1507
1508 void Storage_Schema::ISetCurrentData(const Handle(Storage_Data)& dData)
1509 {
1510   Storage_Schema::ICurrentData() = dData;
1511 }
1512
1513 //=======================================================================
1514 //function : ICurrentData
1515 //purpose  : 
1516 //=======================================================================
1517
1518 Handle(Storage_Data)& Storage_Schema::ICurrentData()
1519 {
1520   static Handle(Storage_Data) _Storage_CData;
1521   return _Storage_CData;
1522 }
1523
1524 #define SLENGTH 80
1525
1526 //=======================================================================
1527 //function : ICreationDate
1528 //purpose  : 
1529 //=======================================================================
1530
1531 TCollection_AsciiString Storage_Schema::ICreationDate()
1532 {
1533  // on sauvegarde l'ancien LC_NUMERIC
1534   char *oldnum,*plocal ;
1535   plocal =   setlocale(LC_NUMERIC, NULL);
1536   oldnum = new char[strlen(plocal)+1] ;
1537   strcpy(oldnum,plocal);
1538
1539
1540   char nowstr[SLENGTH];
1541   time_t nowbin;
1542   struct tm *nowstruct;
1543
1544   (void)setlocale(LC_ALL, "");
1545
1546   if (time(&nowbin) == (time_t) - 1)
1547     cerr << "Storage ERROR : Could not get time of day from time()" << endl;
1548
1549   nowstruct = localtime(&nowbin);
1550
1551   if (strftime(nowstr, SLENGTH, "%m/%d/%Y", nowstruct) == (size_t) 0)
1552     cerr << "Storage ERROR : Could not get string from strftime()" << endl;
1553
1554   TCollection_AsciiString t(nowstr);
1555
1556   // on remet le LC_NUMERIC a la precedente valeur
1557   setlocale(LC_NUMERIC, oldnum);
1558   delete[] oldnum;
1559
1560   return t;
1561 }
1562
1563 //=======================================================================
1564 //function : SetNested
1565 //purpose  : 
1566 //=======================================================================
1567
1568 Standard_Boolean Storage_Schema::SetNested()
1569 {
1570   Standard_Boolean result = myNestedState;
1571
1572   myNestedState = Standard_True;
1573
1574   return result;
1575 }
1576
1577 //=======================================================================
1578 //function : IsNested
1579 //purpose  : 
1580 //=======================================================================
1581
1582 Standard_Boolean Storage_Schema::IsNested() const
1583 {
1584   return myNestedState;
1585 }
1586
1587 //=======================================================================
1588 //function : UnsetNested
1589 //purpose  : 
1590 //=======================================================================
1591
1592 Standard_Boolean Storage_Schema::UnsetNested()
1593 {
1594   Standard_Boolean result = myNestedState;
1595
1596   myNestedState = Standard_False;
1597
1598   return result;
1599 }