2167cabaee74f368982313bb8a4c729e8584e824
[occt.git] / src / Storage / Storage_Schema.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15
16 #include <Standard_ErrorHandler.hxx>
17 #include <Standard_Persistent.hxx>
18 #include <Standard_Type.hxx>
19 #include <Storage.hxx>
20 #include <Storage_BaseDriver.hxx>
21 #include <Storage_BucketOfPersistent.hxx>
22 #include <Storage_CallBack.hxx>
23 #include <Storage_Data.hxx>
24 #include <Storage_DataMapIteratorOfMapOfCallBack.hxx>
25 #include <Storage_DefaultCallBack.hxx>
26 #include <Storage_HArrayOfCallBack.hxx>
27 #include <Storage_HeaderData.hxx>
28 #include <Storage_HPArray.hxx>
29 #include <Storage_HSeqOfRoot.hxx>
30 #include <Storage_InternalData.hxx>
31 #include <Storage_Root.hxx>
32 #include <Storage_RootData.hxx>
33 #include <Storage_Schema.hxx>
34 #include <Storage_StreamExtCharParityError.hxx>
35 #include <Storage_StreamFormatError.hxx>
36 #include <Storage_StreamModeError.hxx>
37 #include <Storage_StreamReadError.hxx>
38 #include <Storage_StreamTypeMismatchError.hxx>
39 #include <Storage_StreamUnknownTypeError.hxx>
40 #include <Storage_StreamWriteError.hxx>
41 #include <Storage_TypeData.hxx>
42 #include <Storage_TypedCallBack.hxx>
43 #include <TCollection_AsciiString.hxx>
44 #include <TColStd_HSequenceOfAsciiString.hxx>
45 #include <TColStd_MapOfAsciiString.hxx>
46
47 #include <locale.h>
48 #include <stdio.h>
49 IMPLEMENT_STANDARD_RTTIEXT(Storage_Schema,MMgt_TShared)
50
51 #define DATATYPE_MIGRATION
52
53 #ifdef DATATYPE_MIGRATION
54 #include <NCollection_DataMap.hxx>
55 #include <OSD_File.hxx>
56 #include <OSD_Path.hxx>
57 #include <OSD_Protection.hxx>
58 #include <OSD_Environment.hxx>
59
60 typedef NCollection_DataMap <TCollection_AsciiString, 
61   TCollection_AsciiString> DataMapOfAStringAString;
62
63 #endif
64
65 // IMPLEMENTATION BucketOfPersistent
66 //
67 Storage_Bucket::~Storage_Bucket()
68 {
69   Standard::Free (mySpace);
70   mySpace = 0L;
71   mySpaceSize = 0;
72   Clear();
73 }
74
75 //=======================================================================
76 //function : Clear
77 //purpose  : 
78 //=======================================================================
79
80 void Storage_Bucket::Clear()
81 {
82   myCurrentSpace = -1;
83 }
84
85 //=======================================================================
86 //function : Append
87 //purpose  : 
88 //=======================================================================
89
90 void Storage_Bucket::Append(Standard_Persistent *sp)
91 {
92   myCurrentSpace++;
93   mySpace[myCurrentSpace] = sp;
94 }
95
96 //=======================================================================
97 //function : Value
98 //purpose  : 
99 //=======================================================================
100
101 Standard_Persistent* Storage_Bucket::Value
102                          (const Standard_Integer theIndex) const
103 {
104   return mySpace[theIndex];
105 }
106
107 //=======================================================================
108 //function : Storage_BucketOfPersistent
109 //purpose  : 
110 //=======================================================================
111
112 Storage_BucketOfPersistent::Storage_BucketOfPersistent
113                          (const Standard_Integer theBucketSize,
114                           const Standard_Integer theBucketNumber)
115 : myNumberOfBucket(1),myNumberOfBucketAllocated(theBucketNumber),myBucketSize
116                          (theBucketSize)
117 {
118   myBuckets =  (Storage_Bucket**)Standard::Allocate
119                          (sizeof(Storage_Bucket*) * theBucketNumber);
120   myBuckets[0] = new Storage_Bucket(myBucketSize);
121   myCurrentBucket = myBuckets[0];
122   myLength = 0;
123   myCurrentBucketNumber = 0;
124 }
125
126 //=======================================================================
127 //function : Clear
128 //purpose  : 
129 //=======================================================================
130
131 void Storage_BucketOfPersistent::Clear()
132 {
133   if (myBuckets) {
134     Standard_Integer i;
135
136     for (i = 1; i < myNumberOfBucket; i++) delete myBuckets[i];
137     myNumberOfBucket = 1;
138     myCurrentBucket = myBuckets[0];
139     myCurrentBucket->Clear();
140     myCurrentBucketNumber = 0;
141     myLength = 0;
142   }
143 }
144
145 Storage_BucketOfPersistent::~Storage_BucketOfPersistent()
146 {
147   Clear();
148   delete myBuckets[0];
149   Standard::Free (myBuckets);
150   myBuckets = 0L;
151 }
152
153 //=======================================================================
154 //function : Value
155 //purpose  : 
156 //=======================================================================
157
158 Standard_Persistent* Storage_BucketOfPersistent::Value
159                          (const Standard_Integer theIndex)
160 {
161   Standard_Integer theInd,theCurrentBucketNumber,tecurrentind = theIndex - 1;
162   theCurrentBucketNumber = tecurrentind / myBucketSize;
163   theInd = tecurrentind - (myBucketSize * theCurrentBucketNumber);
164
165   return myBuckets[theCurrentBucketNumber]->mySpace[theInd];
166
167 }
168
169 //=======================================================================
170 //function : Append
171 //purpose  : 
172 //=======================================================================
173
174 void Storage_BucketOfPersistent::Append(const Handle(Standard_Persistent)& sp)
175 {
176   myCurrentBucket->myCurrentSpace++;
177
178   if (myCurrentBucket->myCurrentSpace != myBucketSize) {
179     myLength++;
180     myCurrentBucket->mySpace[myCurrentBucket->myCurrentSpace] = sp.operator->();
181     return;
182   }
183
184   myCurrentBucket->myCurrentSpace--;
185   myNumberOfBucket++;
186   myCurrentBucketNumber++;
187
188   if (myNumberOfBucket > myNumberOfBucketAllocated) {
189     Standard_Size e = sizeof(Storage_Bucket*) * myNumberOfBucketAllocated;
190     myBuckets =  (Storage_Bucket**)Standard::Reallocate(myBuckets, e * 2);
191     myNumberOfBucketAllocated *= 2;
192   }
193
194   myBuckets[myCurrentBucketNumber] = new Storage_Bucket(myBucketSize);
195   myCurrentBucket = myBuckets[myCurrentBucketNumber];
196   myCurrentBucket->myCurrentSpace++;
197   myLength++;
198   myCurrentBucket->mySpace[myCurrentBucket->myCurrentSpace] = sp.operator->();
199 }
200
201 //=======================================================================
202 //function : Storage_BucketIterator
203 //purpose  : 
204 //=======================================================================
205
206 Storage_BucketIterator::Storage_BucketIterator
207                          (Storage_BucketOfPersistent* aBucketManager)
208 {
209   if (aBucketManager) {
210     myBucket             = aBucketManager;
211     myCurrentBucket      = myBucket->myBuckets[0];
212     myBucketNumber       = aBucketManager->myNumberOfBucket;
213     myCurrentBucketIndex = 0;
214     myCurrentIndex       = 0;
215     myMoreObject         = Standard_True;
216   }
217   else myMoreObject         = Standard_False;
218 }
219
220 //=======================================================================
221 //function : Reset
222 //purpose  : 
223 //=======================================================================
224
225 void Storage_BucketIterator::Reset()
226 {
227   if (myBucket) {
228     myCurrentBucket = myBucket->myBuckets[0];
229     myBucketNumber  = myBucket->myNumberOfBucket;
230     myCurrentIndex  = 0;
231     myCurrentBucketIndex = 0;
232     myMoreObject = Standard_True;
233   }
234   else myMoreObject         = Standard_False;
235 }
236
237 //=======================================================================
238 //function : Init
239 //purpose  : 
240 //=======================================================================
241
242 void Storage_BucketIterator::Init(Storage_BucketOfPersistent* aBucketManager)
243 {
244   if (aBucketManager) {
245     myBucket        = aBucketManager;
246     myCurrentBucket = myBucket->myBuckets[0];
247     myBucketNumber  = aBucketManager->myNumberOfBucket;
248     myCurrentIndex  = 0;
249     myCurrentBucketIndex = 0;
250     myMoreObject = Standard_True;
251   }
252   else myMoreObject         = Standard_False;
253 }
254
255 //=======================================================================
256 //function : Next
257 //purpose  : 
258 //=======================================================================
259
260 void Storage_BucketIterator::Next()
261 {
262   if (!myMoreObject) return;
263
264   if (myCurrentIndex < myCurrentBucket->myCurrentSpace) {
265     myCurrentIndex++;
266   }
267   else {
268     myCurrentIndex = 0;
269     myCurrentBucketIndex++;
270     if (myCurrentBucketIndex < myBucketNumber) {
271       myCurrentBucket = myBucket->myBuckets[myCurrentBucketIndex];
272     }
273     else {
274       myMoreObject = Standard_False;
275     }
276   }
277 }
278
279 //=======================================================================
280 //function : Storage_Schema
281 //purpose  : USER API -- --------------------------------------------------------------
282 //           IMPLEMENTATION BucketOfPersistent
283 //=======================================================================
284
285 Storage_Schema::Storage_Schema()
286 {
287   Clear();
288   ResetDefaultCallBack();
289   myCallBackState = Standard_False;
290 }
291
292 //=======================================================================
293 //function : SetVersion
294 //purpose  : returns version of the schema
295 //=======================================================================
296
297 void Storage_Schema::SetVersion(const TCollection_AsciiString& aVersion)
298 {
299   myVersion = aVersion;
300 }
301
302 //=======================================================================
303 //function : Version
304 //purpose  : returns the version of the schema
305 //=======================================================================
306
307 TCollection_AsciiString Storage_Schema::Version() const
308 {
309   return myVersion;
310 }
311
312 //=======================================================================
313 //function : SetName
314 //purpose  : set the schema's name
315 //=======================================================================
316
317 void Storage_Schema::SetName(const TCollection_AsciiString& aSchemaName)
318 {
319   myName = aSchemaName;
320 }
321
322 //=======================================================================
323 //function : Name
324 //purpose  : returns the schema's name
325 //=======================================================================
326
327 TCollection_AsciiString Storage_Schema::Name() const
328 {
329   return myName;
330 }
331
332 //=======================================================================
333 //function : Write
334 //purpose  : write 
335 //Arguments:
336 //           s: driver to write
337 //           raises  if  the  stream  is  not  opened  in  VSWrite  or
338 //           VSReadWrite
339 //=======================================================================
340
341 void Storage_Schema::Write
342                          (Storage_BaseDriver& f,
343                           const Handle(Storage_Data)& aData) const
344 {
345  if (aData.IsNull()) return;
346
347   // add all the persistent to write...
348   //
349   Standard_Integer                 posfrom,posto;
350   Handle(Standard_Persistent)      p;
351   Handle(Storage_HSeqOfRoot)       plist;
352   TCollection_AsciiString          errorContext("AddPersistent");
353   Storage_Schema::ISetCurrentData(aData);
354
355   Handle(Storage_InternalData) iData = aData->InternalData();
356
357   aData->Clear();
358   aData->ClearErrorStatus();
359
360   plist = aData->Roots();
361
362   for (posto = 1; posto <= plist->Length(); posto++) {
363     PersistentToAdd(plist->Value(posto)->Object());
364   }
365
366   for (posto = 1; posto <= plist->Length(); posto++) {
367 //    AddTypeSelection(plist->Value(posto)->Object());
368   }
369
370   for (posfrom = plist->Length() + 1; posfrom <= iData->myPtoA.Length(); posfrom++) {
371 //    AddTypeSelection(iData->myPtoA.Value(posfrom));
372   }
373
374   // ...and now we write
375   //
376   Standard_Integer            i,
377                               len;
378
379  aData->HeaderData()->SetCreationDate(ICreationDate());
380  aData->HeaderData()->SetStorageVersion(Storage::Version());
381  aData->HeaderData()->SetNumberOfObjects(iData->myPtoA.Length());
382  aData->HeaderData()->SetSchemaName(myName);
383  aData->HeaderData()->SetSchemaVersion(myVersion);
384
385   if ((f.OpenMode() == Storage_VSWrite) || (f.OpenMode() == Storage_VSReadWrite)) {
386     try {
387       OCC_CATCH_SIGNALS
388       errorContext = "BeginWriteInfoSection";
389       f.BeginWriteInfoSection();
390       errorContext = "WriteInfo";
391       f.WriteInfo(aData->NumberOfObjects(),
392                   aData->StorageVersion(),
393                   aData->CreationDate(),
394                   aData->SchemaName(),
395                   aData->SchemaVersion(),
396                   aData->ApplicationName(),
397                   aData->ApplicationVersion(),
398                   aData->DataType(),
399                   aData->UserInfo());
400       errorContext = "EndWriteInfoSection";
401       f.EndWriteInfoSection();
402
403       errorContext = "BeginWriteCommentSection";
404       f.BeginWriteCommentSection();
405       errorContext = "WriteComment";
406       f.WriteComment(aData->Comments());
407       errorContext = "EndWriteCommentSection";
408       f.EndWriteCommentSection();
409
410       Handle(TColStd_HSequenceOfAsciiString) tlist;
411
412       tlist = aData->Types();
413
414       errorContext = "BeginWriteTypeSection";
415       f.BeginWriteTypeSection();
416       len = aData->NumberOfTypes();
417
418       Handle(Storage_HArrayOfCallBack) WFunc = new Storage_HArrayOfCallBack(1,len);
419
420       f.SetTypeSectionSize(len);
421
422       Storage_DataMapIteratorOfMapOfCallBack cbit(iData->myTypeBinding);
423       Handle(Storage_TypedCallBack) atcallBack;
424
425       for (; cbit.More(); cbit.Next()) {
426         atcallBack = cbit.Value();
427         WFunc->SetValue(atcallBack->Index(),atcallBack->CallBack());
428       }
429
430       errorContext = "WriteTypeInformations";
431       for (i = 1; i <= len; i++) {
432         f.WriteTypeInformations(i,tlist->Value(i).ToCString());
433       }
434
435       errorContext = "EndWriteTypeSection";
436       f.EndWriteTypeSection();
437
438       errorContext = "BeginWriteRootSection";
439       f.BeginWriteRootSection();
440       f.SetRootSectionSize(plist->Length());
441
442       errorContext = "WriteRoot";
443       for (i = 1; i <= plist->Length(); i++) {
444         f.WriteRoot(plist->Value(i)->Name(),i,"PDocStd_Document");
445       }
446
447       errorContext = "EndWriteRootSection";
448       f.EndWriteRootSection();
449
450       errorContext = "BeginWriteRefSection";
451       f.BeginWriteRefSection();
452       f.SetRefSectionSize(iData->myObjId - 1);
453       errorContext = "WriteReferenceType";
454
455       Storage_BucketIterator bit(&iData->myPtoA);
456
457       while(bit.More()) {
458         p = bit.Value();
459         if (!p.IsNull()) f.WriteReferenceType(p->_refnum,p->_typenum);
460         bit.Next();
461       }
462
463       errorContext = "EndWriteRefSection";
464       f.EndWriteRefSection();
465
466       errorContext = "BeginWriteDataSection";
467       f.BeginWriteDataSection();
468
469       Handle(Storage_Schema) me = this;
470
471       errorContext = "Write";
472
473       bit.Reset();
474
475       while(bit.More()) {
476         p = bit.Value();
477         if (!p.IsNull()) {
478           WFunc->Value(p->_typenum)->Write(p,f,me);
479           p->_typenum = 0;
480         }
481         bit.Next();
482       }
483
484       errorContext = "EndWriteDataSection";
485       f.EndWriteDataSection();
486     }
487     catch(Storage_StreamWriteError) {
488       aData->SetErrorStatus(Storage_VSWriteError);
489       aData->SetErrorStatusExtension(errorContext);
490     }
491   }
492   else {
493     aData->SetErrorStatus(Storage_VSModeError);
494     aData->SetErrorStatusExtension("OpenMode");
495   }
496
497   iData->Clear();
498   Clear();
499 }
500
501 //=======================================================================
502 //function : AddReadUnknownTypeCallBack
503 //purpose  : add two functions to the callback list
504 //=======================================================================
505
506 void Storage_Schema::AddReadUnknownTypeCallBack
507                          (const TCollection_AsciiString& aTypeName,
508                           const Handle(Storage_CallBack)& aCallBack)
509 {
510   if (!aCallBack.IsNull()) {
511      Handle(Storage_TypedCallBack) aTCallBack = new Storage_TypedCallBack(aTypeName,aCallBack);
512
513      myCallBack.Bind(aTypeName,aTCallBack);
514   }
515 }
516
517 //=======================================================================
518 //function : RemoveReadUnknownTypeCallBack
519 //purpose  : remove a callback for a type
520 //=======================================================================
521
522 void Storage_Schema::RemoveReadUnknownTypeCallBack
523                          (const TCollection_AsciiString& aTypeName)
524 {
525   if (myCallBack.IsBound(aTypeName)) {
526     myCallBack.UnBind(aTypeName);
527   }
528 }
529
530 //=======================================================================
531 //function : InstalledCallBackList
532 //purpose  : returns  a  list  of   type  name  with  installed
533 //           callback.
534 //=======================================================================
535
536 Handle(TColStd_HSequenceOfAsciiString) Storage_Schema::
537                           InstalledCallBackList() const
538 {
539   Storage_DataMapIteratorOfMapOfCallBack it(myCallBack);
540   Handle(TColStd_HSequenceOfAsciiString) result = new TColStd_HSequenceOfAsciiString;
541
542   for (; it.More(); it.Next()) {
543     result->Append(it.Key());
544   }
545
546   return result;
547 }
548
549 //=======================================================================
550 //function : ClearCallBackList
551 //purpose  : clear all callback from schema instance.
552 //=======================================================================
553
554 void Storage_Schema::ClearCallBackList()
555 {
556   myCallBack.Clear();
557 }
558
559 //=======================================================================
560 //function : UseDefaultCallBack
561 //purpose  : install  a  callback  for  all  unknown  type. the
562 //           objects with unknown types  will be skipped. (look
563 //           SkipObject method in BaseDriver)
564 //=======================================================================
565
566 void Storage_Schema::UseDefaultCallBack()
567 {
568   myCallBackState = Standard_True;
569 }
570
571 //=======================================================================
572 //function : DontUseDefaultCallBack
573 //purpose  : tells schema to uninstall the default callback.
574 //=======================================================================
575
576 void Storage_Schema::DontUseDefaultCallBack()
577 {
578   myCallBackState = Standard_False;
579 }
580
581 //=======================================================================
582 //function : IsUsingDefaultCallBack
583 //purpose  : ask if the schema is using the default callback.
584 //=======================================================================
585
586 Standard_Boolean Storage_Schema::IsUsingDefaultCallBack() const
587 {
588   return myCallBackState;
589 }
590
591 //=======================================================================
592 //function : SetDefaultCallBack
593 //purpose  : overload the  default  function  for build.(use to
594 //           set an  error  message  or  skip  an  object while
595 //           reading an unknown type).
596 //=======================================================================
597
598 void Storage_Schema::SetDefaultCallBack(const Handle(Storage_CallBack)& f)
599 {
600   myDefaultCallBack = f;
601 }
602
603 //=======================================================================
604 //function : ResetDefaultCallBack
605 //purpose  : reset  the  default  function  defined  by Storage
606 //           package.
607 //=======================================================================
608
609 void Storage_Schema::ResetDefaultCallBack()
610 {
611   myDefaultCallBack = new Storage_DefaultCallBack;
612 }
613
614 //=======================================================================
615 //function : DefaultCallBack
616 //purpose  : returns   the   read   function   used   when  the
617 //           UseDefaultCallBack() is set.
618 //=======================================================================
619
620 Handle(Storage_CallBack) Storage_Schema::DefaultCallBack() const
621 {
622   return myDefaultCallBack;
623 }
624
625 //=======================================================================
626 //function : BindType
627 //purpose  : 
628 //=======================================================================
629
630 void Storage_Schema::BindType
631                          (const TCollection_AsciiString& aTypeName,
632                           const Handle(Storage_CallBack)& aCallBack) const
633 {
634   if (!HasTypeBinding(aTypeName)) {
635       Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
636       Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
637       Handle(Storage_TypedCallBack) c = new Storage_TypedCallBack(aTypeName,aCallBack);
638
639       tData->AddType(aTypeName,iData->myTypeId);
640       c->SetIndex(iData->myTypeId++);
641       iData->myTypeBinding.Bind(aTypeName,c);
642   }
643 }
644
645 //=======================================================================
646 //function : TypeBinding
647 //purpose  : 
648 //=======================================================================
649
650 Handle(Storage_CallBack) Storage_Schema::TypeBinding
651                          (const TCollection_AsciiString& aTypeName) const
652 {
653   Handle(Storage_CallBack) result;
654
655   if (HasTypeBinding(aTypeName)) {
656     Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
657
658     result =  iData->myTypeBinding.Find(aTypeName)->CallBack();
659   }
660
661   return result;
662 }
663
664 //=======================================================================
665 //function : AddPersistent
666 //purpose  : 
667 //=======================================================================
668
669 Standard_Boolean Storage_Schema::AddPersistent
670                          (const Handle(Standard_Persistent)& sp,
671                           const Standard_CString tName) const
672 {
673   Standard_Boolean result = Standard_False;
674
675   if (!sp.IsNull()) {
676     Handle(Storage_InternalData)     iData = Storage_Schema::ICurrentData()->InternalData();
677
678     if (sp->_typenum == 0) {
679       Standard_Integer         aTypenum;
680       static TCollection_AsciiString  aTypeName;
681       aTypeName = tName;
682       Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
683
684       aTypenum = iData->myTypeBinding.Find(aTypeName)->Index();
685
686       sp->_typenum = aTypenum;
687       sp->_refnum = iData->myObjId++;
688
689       result = Standard_True;
690     }
691   }
692
693   return result;
694 }
695
696 //=======================================================================
697 //function : PersistentToAdd
698 //purpose  : 
699 //=======================================================================
700
701 Standard_Boolean Storage_Schema::PersistentToAdd
702                          (const Handle(Standard_Persistent)& sp) const
703 {
704  Standard_Boolean result = Standard_False;
705
706   if (!sp.IsNull()) {
707     Handle(Storage_InternalData) di = Storage_Schema::ICurrentData()->InternalData();
708
709     if (sp->_typenum == 0 && sp->_refnum != -1) {
710       result = Standard_True;
711       sp->_refnum = -1;
712       di->myPtoA.Append(sp);
713     }
714   }
715
716   return result;
717 }
718
719 //=======================================================================
720 //function : Clear
721 //purpose  : 
722 //=======================================================================
723
724 void Storage_Schema::Clear() const
725 {
726   Storage_Schema::ICurrentData().Nullify();
727 }
728
729 #ifdef DATATYPE_MIGRATION
730 //=======================================================================
731 // environment variable CSF_MIGRATION_TYPES should define full path of a file
732 // containing migration types table: oldtype - newtype
733 //=======================================================================
734 Standard_Boolean Storage_Schema::CheckTypeMigration(
735                                   const TCollection_AsciiString&  oldName,
736                                   TCollection_AsciiString&  newName)
737 {
738   static Standard_Boolean isChecked(Standard_False);
739   static DataMapOfAStringAString aDMap;
740   Standard_Boolean aMigration(Standard_False);
741   
742   if(!isChecked) {
743     isChecked = Standard_True;
744 //    TCollection_AsciiString aFileName = getenv("CSF_MIGRATION_TYPES");
745     OSD_Environment csf(TCollection_AsciiString("CSF_MIGRATION_TYPES"));
746     TCollection_AsciiString aFileName = csf.Value();
747     if(aFileName.Length() > 0) {
748       OSD_Path aPath(aFileName,OSD_Default);
749       OSD_File aFile;
750       aFile.SetPath(aPath);
751       if(aFile.Exists()) {
752         OSD_Protection aProt(OSD_R,OSD_R,OSD_R,OSD_R);
753         aFile.Open(OSD_ReadOnly, aProt);
754         if(aFile.IsOpen() && aFile.IsReadable()) {
755           TCollection_AsciiString aLine;
756           Standard_Integer aNbReaded(0);
757           for (;;) {
758             aFile.ReadLine(aLine, 80, aNbReaded);
759             if(aFile.IsAtEnd() || !aNbReaded) {
760               aFile.Close();
761               break;
762             }
763 #ifdef OCCT_DEBUG
764             cout << "Storage_Sheme:: Line: = " << aLine <<endl;
765 #endif
766             TCollection_AsciiString aKey, aValue;
767             aKey = aLine.Token();
768             aValue = aLine.Token(" \t\n\r", 2);
769             aDMap.Bind(aKey, aValue);
770           }
771         }
772       }
773 #ifdef OCCT_DEBUG
774       cout << "Storage_Sheme:: aDataMap.Size = " << aDMap.Extent() <<endl;
775 #endif
776     }
777   }
778
779   if(aDMap.Extent()) {
780     if(aDMap.IsBound(oldName)) {
781       newName.Clear();
782       newName = aDMap.Find(oldName);
783       aMigration = Standard_True;
784 #ifdef OCCT_DEBUG
785       cout << " newName = " << newName << endl;
786 #endif
787     }
788   } 
789   return aMigration;
790 }
791 #endif
792
793 //=======================================================================
794 //function : ISetCurrentData
795 //purpose  : 
796 //=======================================================================
797
798 void Storage_Schema::ISetCurrentData(const Handle(Storage_Data)& dData)
799 {
800   Storage_Schema::ICurrentData() = dData;
801 }
802
803 //=======================================================================
804 //function : ICurrentData
805 //purpose  : 
806 //=======================================================================
807
808 Handle(Storage_Data)& Storage_Schema::ICurrentData()
809 {
810   static Handle(Storage_Data) _Storage_CData;
811   return _Storage_CData;
812 }
813
814 #define SLENGTH 80
815
816 //=======================================================================
817 //function : ICreationDate
818 //purpose  : 
819 //=======================================================================
820
821 TCollection_AsciiString Storage_Schema::ICreationDate()
822 {
823   char nowstr[SLENGTH];
824   time_t nowbin;
825   struct tm *nowstruct;
826   if (time(&nowbin) == (time_t)-1)
827   {
828 #ifdef OCCT_DEBUG
829     cerr << "Storage ERROR : Could not get time of day from time()" << endl;
830 #endif
831   }
832
833   nowstruct = localtime(&nowbin);
834
835   if (strftime(nowstr, SLENGTH, "%m/%d/%Y", nowstruct) == (size_t) 0)
836   {
837 #ifdef OCCT_DEBUG
838     cerr << "Storage ERROR : Could not get string from strftime()" << endl;
839 #endif
840   }
841
842   TCollection_AsciiString t(nowstr);
843   return t;
844 }