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,Standard_Transient)
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 //
~Storage_Bucket()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 
Clear()80 void Storage_Bucket::Clear()
81 {
82   myCurrentSpace = -1;
83 }
84 
85 //=======================================================================
86 //function : Append
87 //purpose  :
88 //=======================================================================
89 
Append(Standard_Persistent * sp)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 
Value(const Standard_Integer theIndex) const101 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 
Storage_BucketOfPersistent(const Standard_Integer theBucketSize,const Standard_Integer theBucketNumber)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 
Clear()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 
~Storage_BucketOfPersistent()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 
Value(const Standard_Integer theIndex)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 
Append(const Handle (Standard_Persistent)& sp)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.get();
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.get();
199 }
200 
201 //=======================================================================
202 //function : Storage_BucketIterator
203 //purpose  :
204 //=======================================================================
205 
Storage_BucketIterator(Storage_BucketOfPersistent * aBucketManager)206 Storage_BucketIterator::Storage_BucketIterator
207                          (Storage_BucketOfPersistent* aBucketManager)
208 : myBucket(0), myCurrentBucket(0),
209   myCurrentBucketIndex(0), myCurrentIndex(0),
210   myBucketNumber(0), myMoreObject(Standard_False)
211 {
212   if (aBucketManager) {
213     myBucket             = aBucketManager;
214     myCurrentBucket      = myBucket->myBuckets[0];
215     myBucketNumber       = aBucketManager->myNumberOfBucket;
216     myCurrentBucketIndex = 0;
217     myCurrentIndex       = 0;
218     myMoreObject         = Standard_True;
219   }
220 }
221 
222 //=======================================================================
223 //function : Reset
224 //purpose  :
225 //=======================================================================
226 
Reset()227 void Storage_BucketIterator::Reset()
228 {
229   if (myBucket) {
230     myCurrentBucket = myBucket->myBuckets[0];
231     myBucketNumber  = myBucket->myNumberOfBucket;
232     myCurrentIndex  = 0;
233     myCurrentBucketIndex = 0;
234     myMoreObject = Standard_True;
235   }
236   else myMoreObject         = Standard_False;
237 }
238 
239 //=======================================================================
240 //function : Init
241 //purpose  :
242 //=======================================================================
243 
Init(Storage_BucketOfPersistent * aBucketManager)244 void Storage_BucketIterator::Init(Storage_BucketOfPersistent* aBucketManager)
245 {
246   if (aBucketManager) {
247     myBucket        = aBucketManager;
248     myCurrentBucket = myBucket->myBuckets[0];
249     myBucketNumber  = aBucketManager->myNumberOfBucket;
250     myCurrentIndex  = 0;
251     myCurrentBucketIndex = 0;
252     myMoreObject = Standard_True;
253   }
254   else myMoreObject         = Standard_False;
255 }
256 
257 //=======================================================================
258 //function : Next
259 //purpose  :
260 //=======================================================================
261 
Next()262 void Storage_BucketIterator::Next()
263 {
264   if (!myMoreObject) return;
265 
266   if (myCurrentIndex < myCurrentBucket->myCurrentSpace) {
267     myCurrentIndex++;
268   }
269   else {
270     myCurrentIndex = 0;
271     myCurrentBucketIndex++;
272     if (myCurrentBucketIndex < myBucketNumber) {
273       myCurrentBucket = myBucket->myBuckets[myCurrentBucketIndex];
274     }
275     else {
276       myMoreObject = Standard_False;
277     }
278   }
279 }
280 
281 //=======================================================================
282 //function : Storage_Schema
283 //purpose  : USER API -- --------------------------------------------------------------
284 //           IMPLEMENTATION BucketOfPersistent
285 //=======================================================================
286 
Storage_Schema()287 Storage_Schema::Storage_Schema()
288 {
289   Clear();
290   ResetDefaultCallBack();
291   myCallBackState = Standard_False;
292 }
293 
294 //=======================================================================
295 //function : SetVersion
296 //purpose  : returns version of the schema
297 //=======================================================================
298 
SetVersion(const TCollection_AsciiString & aVersion)299 void Storage_Schema::SetVersion(const TCollection_AsciiString& aVersion)
300 {
301   myVersion = aVersion;
302 }
303 
304 //=======================================================================
305 //function : Version
306 //purpose  : returns the version of the schema
307 //=======================================================================
308 
Version() const309 TCollection_AsciiString Storage_Schema::Version() const
310 {
311   return myVersion;
312 }
313 
314 //=======================================================================
315 //function : SetName
316 //purpose  : set the schema's name
317 //=======================================================================
318 
SetName(const TCollection_AsciiString & aSchemaName)319 void Storage_Schema::SetName(const TCollection_AsciiString& aSchemaName)
320 {
321   myName = aSchemaName;
322 }
323 
324 //=======================================================================
325 //function : Name
326 //purpose  : returns the schema's name
327 //=======================================================================
328 
Name() const329 TCollection_AsciiString Storage_Schema::Name() const
330 {
331   return myName;
332 }
333 
334 //=======================================================================
335 //function : Write
336 //purpose  : write
337 //Arguments:
338 //           s: driver to write
339 //           raises  if  the  stream  is  not  opened  in  VSWrite  or
340 //           VSReadWrite
341 //=======================================================================
342 
Write(const Handle (Storage_BaseDriver)& theDriver,const Handle (Storage_Data)& aData) const343 void Storage_Schema::Write (const Handle(Storage_BaseDriver)& theDriver,
344                             const Handle(Storage_Data)& aData) const
345 {
346  if (aData.IsNull()) return;
347 
348   // add all the persistent to write...
349   //
350   Standard_Integer                 posfrom,posto;
351   Handle(Standard_Persistent)      p;
352   Handle(Storage_HSeqOfRoot)       plist;
353   TCollection_AsciiString          errorContext("AddPersistent");
354   Storage_Schema::ISetCurrentData(aData);
355 
356   Handle(Storage_InternalData) iData = aData->InternalData();
357 
358   aData->Clear();
359   aData->ClearErrorStatus();
360 
361   plist = aData->Roots();
362 
363   for (posto = 1; posto <= plist->Length(); posto++) {
364     PersistentToAdd(plist->Value(posto)->Object());
365   }
366 
367   for (posto = 1; posto <= plist->Length(); posto++) {
368 //    AddTypeSelection(plist->Value(posto)->Object());
369   }
370 
371   for (posfrom = plist->Length() + 1; posfrom <= iData->myPtoA.Length(); posfrom++) {
372 //    AddTypeSelection(iData->myPtoA.Value(posfrom));
373   }
374 
375   // ...and now we write
376   //
377   Standard_Integer            i,
378                               len;
379 
380  aData->HeaderData()->SetCreationDate(ICreationDate());
381  aData->HeaderData()->SetStorageVersion(Storage::Version());
382  aData->HeaderData()->SetNumberOfObjects(iData->myPtoA.Length());
383  aData->HeaderData()->SetSchemaName(myName);
384  aData->HeaderData()->SetSchemaVersion(myVersion);
385 
386   if ((theDriver->OpenMode() == Storage_VSWrite) || (theDriver->OpenMode() == Storage_VSReadWrite)) {
387     try {
388       OCC_CATCH_SIGNALS
389       errorContext = "BeginWriteInfoSection";
390       theDriver->BeginWriteInfoSection();
391       errorContext = "WriteInfo";
392       theDriver->WriteInfo(aData->NumberOfObjects(),
393                            aData->StorageVersion(),
394                            aData->CreationDate(),
395                            aData->SchemaName(),
396                            aData->SchemaVersion(),
397                            aData->ApplicationName(),
398                            aData->ApplicationVersion(),
399                            aData->DataType(),
400                            aData->UserInfo());
401       errorContext = "EndWriteInfoSection";
402       theDriver->EndWriteInfoSection();
403 
404       errorContext = "BeginWriteCommentSection";
405       theDriver->BeginWriteCommentSection();
406       errorContext = "WriteComment";
407       theDriver->WriteComment(aData->Comments());
408       errorContext = "EndWriteCommentSection";
409       theDriver->EndWriteCommentSection();
410 
411       Handle(TColStd_HSequenceOfAsciiString) tlist;
412 
413       tlist = aData->Types();
414 
415       errorContext = "BeginWriteTypeSection";
416       theDriver->BeginWriteTypeSection();
417       len = aData->NumberOfTypes();
418 
419       Handle(Storage_HArrayOfCallBack) WFunc = new Storage_HArrayOfCallBack(1,len);
420 
421       theDriver->SetTypeSectionSize(len);
422 
423       Storage_DataMapIteratorOfMapOfCallBack cbit(iData->myTypeBinding);
424       Handle(Storage_TypedCallBack) atcallBack;
425 
426       for (; cbit.More(); cbit.Next()) {
427         atcallBack = cbit.Value();
428         WFunc->SetValue(atcallBack->Index(),atcallBack->CallBack());
429       }
430 
431       errorContext = "WriteTypeInformations";
432       for (i = 1; i <= len; i++) {
433         theDriver->WriteTypeInformations(i,tlist->Value(i).ToCString());
434       }
435 
436       errorContext = "EndWriteTypeSection";
437       theDriver->EndWriteTypeSection();
438 
439       errorContext = "BeginWriteRootSection";
440       theDriver->BeginWriteRootSection();
441       theDriver->SetRootSectionSize(plist->Length());
442 
443       errorContext = "WriteRoot";
444       for (i = 1; i <= plist->Length(); i++) {
445         theDriver->WriteRoot(plist->Value(i)->Name(),i,"PDocStd_Document");
446       }
447 
448       errorContext = "EndWriteRootSection";
449       theDriver->EndWriteRootSection();
450 
451       errorContext = "BeginWriteRefSection";
452       theDriver->BeginWriteRefSection();
453       theDriver->SetRefSectionSize(iData->myObjId - 1);
454       errorContext = "WriteReferenceType";
455 
456       Storage_BucketIterator bit(&iData->myPtoA);
457 
458       while(bit.More()) {
459         p = bit.Value();
460         if (!p.IsNull()) theDriver->WriteReferenceType(p->_refnum,p->_typenum);
461         bit.Next();
462       }
463 
464       errorContext = "EndWriteRefSection";
465       theDriver->EndWriteRefSection();
466 
467       errorContext = "BeginWriteDataSection";
468       theDriver->BeginWriteDataSection();
469 
470       Handle(Storage_Schema) me = this;
471 
472       errorContext = "Write";
473 
474       bit.Reset();
475 
476       while(bit.More()) {
477         p = bit.Value();
478         if (!p.IsNull()) {
479           WFunc->Value(p->_typenum)->Write(p, theDriver, me);
480           p->_typenum = 0;
481         }
482         bit.Next();
483       }
484 
485       errorContext = "EndWriteDataSection";
486       theDriver->EndWriteDataSection();
487     }
488     catch(Storage_StreamWriteError const&) {
489       aData->SetErrorStatus(Storage_VSWriteError);
490       aData->SetErrorStatusExtension(errorContext);
491     }
492   }
493   else {
494     aData->SetErrorStatus(Storage_VSModeError);
495     aData->SetErrorStatusExtension("OpenMode");
496   }
497 
498   iData->Clear();
499   Clear();
500 }
501 
502 //=======================================================================
503 //function : AddReadUnknownTypeCallBack
504 //purpose  : add two functions to the callback list
505 //=======================================================================
506 
AddReadUnknownTypeCallBack(const TCollection_AsciiString & aTypeName,const Handle (Storage_CallBack)& aCallBack)507 void Storage_Schema::AddReadUnknownTypeCallBack
508                          (const TCollection_AsciiString& aTypeName,
509                           const Handle(Storage_CallBack)& aCallBack)
510 {
511   if (!aCallBack.IsNull()) {
512      Handle(Storage_TypedCallBack) aTCallBack = new Storage_TypedCallBack(aTypeName,aCallBack);
513 
514      myCallBack.Bind(aTypeName,aTCallBack);
515   }
516 }
517 
518 //=======================================================================
519 //function : RemoveReadUnknownTypeCallBack
520 //purpose  : remove a callback for a type
521 //=======================================================================
522 
RemoveReadUnknownTypeCallBack(const TCollection_AsciiString & aTypeName)523 void Storage_Schema::RemoveReadUnknownTypeCallBack
524                          (const TCollection_AsciiString& aTypeName)
525 {
526   if (myCallBack.IsBound(aTypeName)) {
527     myCallBack.UnBind(aTypeName);
528   }
529 }
530 
531 //=======================================================================
532 //function : InstalledCallBackList
533 //purpose  : returns  a  list  of   type  name  with  installed
534 //           callback.
535 //=======================================================================
536 
Handle(TColStd_HSequenceOfAsciiString)537 Handle(TColStd_HSequenceOfAsciiString) Storage_Schema::
538                           InstalledCallBackList() const
539 {
540   Storage_DataMapIteratorOfMapOfCallBack it(myCallBack);
541   Handle(TColStd_HSequenceOfAsciiString) result = new TColStd_HSequenceOfAsciiString;
542 
543   for (; it.More(); it.Next()) {
544     result->Append(it.Key());
545   }
546 
547   return result;
548 }
549 
550 //=======================================================================
551 //function : ClearCallBackList
552 //purpose  : clear all callback from schema instance.
553 //=======================================================================
554 
ClearCallBackList()555 void Storage_Schema::ClearCallBackList()
556 {
557   myCallBack.Clear();
558 }
559 
560 //=======================================================================
561 //function : UseDefaultCallBack
562 //purpose  : install  a  callback  for  all  unknown  type. the
563 //           objects with unknown types  will be skipped. (look
564 //           SkipObject method in BaseDriver)
565 //=======================================================================
566 
UseDefaultCallBack()567 void Storage_Schema::UseDefaultCallBack()
568 {
569   myCallBackState = Standard_True;
570 }
571 
572 //=======================================================================
573 //function : DontUseDefaultCallBack
574 //purpose  : tells schema to uninstall the default callback.
575 //=======================================================================
576 
DontUseDefaultCallBack()577 void Storage_Schema::DontUseDefaultCallBack()
578 {
579   myCallBackState = Standard_False;
580 }
581 
582 //=======================================================================
583 //function : IsUsingDefaultCallBack
584 //purpose  : ask if the schema is using the default callback.
585 //=======================================================================
586 
IsUsingDefaultCallBack() const587 Standard_Boolean Storage_Schema::IsUsingDefaultCallBack() const
588 {
589   return myCallBackState;
590 }
591 
592 //=======================================================================
593 //function : SetDefaultCallBack
594 //purpose  : overload the  default  function  for build.(use to
595 //           set an  error  message  or  skip  an  object while
596 //           reading an unknown type).
597 //=======================================================================
598 
SetDefaultCallBack(const Handle (Storage_CallBack)& f)599 void Storage_Schema::SetDefaultCallBack(const Handle(Storage_CallBack)& f)
600 {
601   myDefaultCallBack = f;
602 }
603 
604 //=======================================================================
605 //function : ResetDefaultCallBack
606 //purpose  : reset  the  default  function  defined  by Storage
607 //           package.
608 //=======================================================================
609 
ResetDefaultCallBack()610 void Storage_Schema::ResetDefaultCallBack()
611 {
612   myDefaultCallBack = new Storage_DefaultCallBack;
613 }
614 
615 //=======================================================================
616 //function : DefaultCallBack
617 //purpose  : returns   the   read   function   used   when  the
618 //           UseDefaultCallBack() is set.
619 //=======================================================================
620 
Handle(Storage_CallBack)621 Handle(Storage_CallBack) Storage_Schema::DefaultCallBack() const
622 {
623   return myDefaultCallBack;
624 }
625 
626 //=======================================================================
627 //function : BindType
628 //purpose  :
629 //=======================================================================
630 
BindType(const TCollection_AsciiString & aTypeName,const Handle (Storage_CallBack)& aCallBack) const631 void Storage_Schema::BindType
632                          (const TCollection_AsciiString& aTypeName,
633                           const Handle(Storage_CallBack)& aCallBack) const
634 {
635   if (!HasTypeBinding(aTypeName)) {
636       Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
637       Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
638       Handle(Storage_TypedCallBack) c = new Storage_TypedCallBack(aTypeName,aCallBack);
639 
640       tData->AddType(aTypeName,iData->myTypeId);
641       c->SetIndex(iData->myTypeId++);
642       iData->myTypeBinding.Bind(aTypeName,c);
643   }
644 }
645 
646 //=======================================================================
647 //function : TypeBinding
648 //purpose  :
649 //=======================================================================
650 
Handle(Storage_CallBack)651 Handle(Storage_CallBack) Storage_Schema::TypeBinding
652                          (const TCollection_AsciiString& aTypeName) const
653 {
654   Handle(Storage_CallBack) result;
655 
656   if (HasTypeBinding(aTypeName)) {
657     Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
658 
659     result =  iData->myTypeBinding.Find(aTypeName)->CallBack();
660   }
661 
662   return result;
663 }
664 
665 //=======================================================================
666 //function : AddPersistent
667 //purpose  :
668 //=======================================================================
669 
AddPersistent(const Handle (Standard_Persistent)& sp,const Standard_CString tName) const670 Standard_Boolean Storage_Schema::AddPersistent
671                          (const Handle(Standard_Persistent)& sp,
672                           const Standard_CString tName) const
673 {
674   Standard_Boolean result = Standard_False;
675 
676   if (!sp.IsNull()) {
677     Handle(Storage_InternalData)     iData = Storage_Schema::ICurrentData()->InternalData();
678 
679     if (sp->_typenum == 0) {
680       Standard_Integer         aTypenum;
681       static TCollection_AsciiString  aTypeName;
682       aTypeName = tName;
683       Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
684 
685       aTypenum = iData->myTypeBinding.Find(aTypeName)->Index();
686 
687       sp->_typenum = aTypenum;
688       sp->_refnum = iData->myObjId++;
689 
690       result = Standard_True;
691     }
692   }
693 
694   return result;
695 }
696 
697 //=======================================================================
698 //function : PersistentToAdd
699 //purpose  :
700 //=======================================================================
701 
PersistentToAdd(const Handle (Standard_Persistent)& sp) const702 Standard_Boolean Storage_Schema::PersistentToAdd
703                          (const Handle(Standard_Persistent)& sp) const
704 {
705  Standard_Boolean result = Standard_False;
706 
707   if (!sp.IsNull()) {
708     Handle(Storage_InternalData) di = Storage_Schema::ICurrentData()->InternalData();
709 
710     if (sp->_typenum == 0 && sp->_refnum != -1) {
711       result = Standard_True;
712       sp->_refnum = -1;
713       di->myPtoA.Append(sp);
714     }
715   }
716 
717   return result;
718 }
719 
720 //=======================================================================
721 //function : Clear
722 //purpose  :
723 //=======================================================================
724 
Clear() const725 void Storage_Schema::Clear() const
726 {
727   Storage_Schema::ICurrentData().Nullify();
728 }
729 
730 #ifdef DATATYPE_MIGRATION
731 //=======================================================================
732 // environment variable CSF_MIGRATION_TYPES should define full path of a file
733 // containing migration types table: oldtype - newtype
734 //=======================================================================
CheckTypeMigration(const TCollection_AsciiString & oldName,TCollection_AsciiString & newName)735 Standard_Boolean Storage_Schema::CheckTypeMigration(
736                                   const TCollection_AsciiString&  oldName,
737 				  TCollection_AsciiString&  newName)
738 {
739   static Standard_Boolean isChecked(Standard_False);
740   static DataMapOfAStringAString aDMap;
741   Standard_Boolean aMigration(Standard_False);
742 
743   if(!isChecked) {
744     isChecked = Standard_True;
745 //    TCollection_AsciiString aFileName = getenv("CSF_MIGRATION_TYPES");
746     OSD_Environment csf(TCollection_AsciiString("CSF_MIGRATION_TYPES"));
747     TCollection_AsciiString aFileName = csf.Value();
748     if(aFileName.Length() > 0) {
749       OSD_Path aPath(aFileName,OSD_Default);
750       OSD_File aFile;
751       aFile.SetPath(aPath);
752       if(aFile.Exists()) {
753 	OSD_Protection aProt(OSD_R,OSD_R,OSD_R,OSD_R);
754 	aFile.Open(OSD_ReadOnly, aProt);
755 	if(aFile.IsOpen() && aFile.IsReadable()) {
756 	  TCollection_AsciiString aLine;
757 	  Standard_Integer aNbReaded(0);
758 	  for (;;) {
759 	    aFile.ReadLine(aLine, 80, aNbReaded);
760 	    if(aFile.IsAtEnd() || !aNbReaded) {
761 	      aFile.Close();
762 	      break;
763 	    }
764 #ifdef OCCT_DEBUG
765 	    std::cout << "Storage_Sheme:: Line: = " << aLine <<std::endl;
766 #endif
767 	    TCollection_AsciiString aKey, aValue;
768 	    aKey = aLine.Token();
769 	    aValue = aLine.Token(" \t\n\r", 2);
770 	    aDMap.Bind(aKey, aValue);
771 	  }
772         }
773       }
774       else
775       {
776         // hard-code migration table for known types
777 	aDMap.Bind("TDataStd_Shape",          "TDataXtd_Shape");
778 	aDMap.Bind("TDataStd_Constraint",     "TDataXtd_Constraint");
779         aDMap.Bind("TDataStd_Geometry",       "TDataXtd_Geometry");
780 	aDMap.Bind("TDataStd_Axis",           "TDataXtd_Axis");
781 	aDMap.Bind("TDataStd_Point",          "TDataXtd_Point");
782 	aDMap.Bind("TDataStd_Plane",          "TDataXtd_Plane");
783 	aDMap.Bind("TDataStd_Position",       "TDataXtd_Position");
784 	aDMap.Bind("TDataStd_Placement",      "TDataXtd_Placement");
785 	aDMap.Bind("TDataStd_PatternStd",     "TDataXtd_PatternStd");
786 	aDMap.Bind("TPrsStd_AISPresentation", "TDataXtd_Presentation");
787         aDMap.Bind("PDataStd_Shape",          "PDataXtd_Shape");
788         aDMap.Bind("PDataStd_Constraint",     "PDataXtd_Constraint");
789         aDMap.Bind("PDataStd_Geometry",       "PDataXtd_Geometry");
790         aDMap.Bind("PDataStd_Axis",           "PDataXtd_Axis");
791         aDMap.Bind("PDataStd_Point",          "PDataXtd_Point");
792         aDMap.Bind("PDataStd_Plane",          "PDataXtd_Plane");
793         aDMap.Bind("PDataStd_Position",       "PDataXtd_Position");
794         aDMap.Bind("PDataStd_Placement",      "PDataXtd_Placement");
795         aDMap.Bind("PDataStd_PatternStd",     "PDataXtd_PatternStd");
796       }
797 #ifdef OCCT_DEBUG
798       std::cout << "Storage_Sheme:: aDataMap.Size = " << aDMap.Extent() << std::endl;
799 #endif
800     }
801   }
802 
803   if(aDMap.Extent()) {
804     if(aDMap.IsBound(oldName)) {
805       newName.Clear();
806       newName = aDMap.Find(oldName);
807       aMigration = Standard_True;
808 #ifdef OCCT_DEBUG
809       std::cout << " newName = " << newName << std::endl;
810 #endif
811     }
812   }
813   return aMigration;
814 }
815 #endif
816 
817 //=======================================================================
818 //function : ISetCurrentData
819 //purpose  :
820 //=======================================================================
821 
ISetCurrentData(const Handle (Storage_Data)& dData)822 void Storage_Schema::ISetCurrentData(const Handle(Storage_Data)& dData)
823 {
824   Storage_Schema::ICurrentData() = dData;
825 }
826 
827 //=======================================================================
828 //function : ICurrentData
829 //purpose  :
830 //=======================================================================
831 
Handle(Storage_Data)832 Handle(Storage_Data)& Storage_Schema::ICurrentData()
833 {
834   static Handle(Storage_Data) _Storage_CData;
835   return _Storage_CData;
836 }
837 
838 #define SLENGTH 80
839 
840 //=======================================================================
841 //function : ICreationDate
842 //purpose  :
843 //=======================================================================
844 
ICreationDate()845 TCollection_AsciiString Storage_Schema::ICreationDate()
846 {
847   char nowstr[SLENGTH];
848   time_t nowbin;
849   struct tm *nowstruct;
850   if (time(&nowbin) == (time_t)-1)
851   {
852 #ifdef OCCT_DEBUG
853     std::cerr << "Storage ERROR : Could not get time of day from time()" << std::endl;
854 #endif
855   }
856 
857   nowstruct = localtime(&nowbin);
858 
859   if (strftime(nowstr, SLENGTH, "%m/%d/%Y", nowstruct) == (size_t) 0)
860   {
861 #ifdef OCCT_DEBUG
862     std::cerr << "Storage ERROR : Could not get string from strftime()" << std::endl;
863 #endif
864   }
865 
866   TCollection_AsciiString t(nowstr);
867   return t;
868 }
869