1 #include <Storage_Schema.ixx>
3 #include <TColStd_HSequenceOfAsciiString.hxx>
4 #include <TColStd_MapOfAsciiString.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>
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>
30 #if defined(HAVE_TIME_H) || defined(WNT)
34 #ifdef HAVE_SYS_TIME_H
35 # include <sys/time.h>
41 #define DATATYPE_MIGRATION
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>
50 typedef NCollection_DataMap <TCollection_AsciiString,
51 TCollection_AsciiString> DataMapOfAStringAString;
55 // IMPLEMENTATION BucketOfPersistent
57 Storage_Bucket::~Storage_Bucket()
59 Standard::Free((Standard_Address&)mySpace);
65 //=======================================================================
68 //=======================================================================
70 void Storage_Bucket::Clear()
75 //=======================================================================
78 //=======================================================================
80 void Storage_Bucket::Append(Standard_Persistent *sp)
83 mySpace[myCurrentSpace] = sp;
86 //=======================================================================
89 //=======================================================================
91 Standard_Persistent* Storage_Bucket::Value
92 (const Standard_Integer theIndex) const
94 return mySpace[theIndex];
97 //=======================================================================
98 //function : Storage_BucketOfPersistent
100 //=======================================================================
102 Storage_BucketOfPersistent::Storage_BucketOfPersistent
103 (const Standard_Integer theBucketSize,
104 const Standard_Integer theBucketNumber)
105 : myNumberOfBucket(1),myNumberOfBucketAllocated(theBucketNumber),myBucketSize
108 myBuckets = (Storage_Bucket**)Standard::Allocate
109 (sizeof(Storage_Bucket*) * theBucketNumber);
110 myBuckets[0] = new Storage_Bucket(myBucketSize);
111 myCurrentBucket = myBuckets[0];
113 myCurrentBucketNumber = 0;
116 //=======================================================================
119 //=======================================================================
121 void Storage_BucketOfPersistent::Clear()
126 for (i = 1; i < myNumberOfBucket; i++) delete myBuckets[i];
127 myNumberOfBucket = 1;
128 myCurrentBucket = myBuckets[0];
129 myCurrentBucket->Clear();
130 myCurrentBucketNumber = 0;
135 Storage_BucketOfPersistent::~Storage_BucketOfPersistent()
139 Standard::Free((Standard_Address&)myBuckets);
143 //=======================================================================
146 //=======================================================================
148 Standard_Persistent* Storage_BucketOfPersistent::Value
149 (const Standard_Integer theIndex)
151 Standard_Integer theInd,theCurrentBucketNumber,tecurrentind = theIndex - 1;
152 theCurrentBucketNumber = tecurrentind / myBucketSize;
153 theInd = tecurrentind - (myBucketSize * theCurrentBucketNumber);
155 return myBuckets[theCurrentBucketNumber]->mySpace[theInd];
159 //=======================================================================
162 //=======================================================================
164 void Storage_BucketOfPersistent::Append(const Handle(Standard_Persistent)& sp)
166 myCurrentBucket->myCurrentSpace++;
168 if (myCurrentBucket->myCurrentSpace != myBucketSize) {
170 myCurrentBucket->mySpace[myCurrentBucket->myCurrentSpace] = sp.operator->();
174 myCurrentBucket->myCurrentSpace--;
176 myCurrentBucketNumber++;
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;
184 myBuckets[myCurrentBucketNumber] = new Storage_Bucket(myBucketSize);
185 myCurrentBucket = myBuckets[myCurrentBucketNumber];
186 myCurrentBucket->myCurrentSpace++;
188 myCurrentBucket->mySpace[myCurrentBucket->myCurrentSpace] = sp.operator->();
191 //=======================================================================
192 //function : Storage_BucketIterator
194 //=======================================================================
196 Storage_BucketIterator::Storage_BucketIterator
197 (Storage_BucketOfPersistent* aBucketManager)
199 if (aBucketManager) {
200 myBucket = aBucketManager;
201 myCurrentBucket = myBucket->myBuckets[0];
202 myBucketNumber = aBucketManager->myNumberOfBucket;
203 myCurrentBucketIndex = 0;
205 myMoreObject = Standard_True;
207 else myMoreObject = Standard_False;
210 //=======================================================================
213 //=======================================================================
215 void Storage_BucketIterator::Reset()
218 myCurrentBucket = myBucket->myBuckets[0];
219 myBucketNumber = myBucket->myNumberOfBucket;
221 myCurrentBucketIndex = 0;
222 myMoreObject = Standard_True;
224 else myMoreObject = Standard_False;
227 //=======================================================================
230 //=======================================================================
232 void Storage_BucketIterator::Init(Storage_BucketOfPersistent* aBucketManager)
234 if (aBucketManager) {
235 myBucket = aBucketManager;
236 myCurrentBucket = myBucket->myBuckets[0];
237 myBucketNumber = aBucketManager->myNumberOfBucket;
239 myCurrentBucketIndex = 0;
240 myMoreObject = Standard_True;
242 else myMoreObject = Standard_False;
245 //=======================================================================
248 //=======================================================================
250 void Storage_BucketIterator::Next()
252 if (!myMoreObject) return;
254 if (myCurrentIndex < myCurrentBucket->myCurrentSpace) {
259 myCurrentBucketIndex++;
260 if (myCurrentBucketIndex < myBucketNumber) {
261 myCurrentBucket = myBucket->myBuckets[myCurrentBucketIndex];
264 myMoreObject = Standard_False;
269 //=======================================================================
270 //function : Storage_Schema
271 //purpose : USER API -- --------------------------------------------------------------
272 // IMPLEMENTATION BucketOfPersistent
273 //=======================================================================
275 Storage_Schema::Storage_Schema()
278 ResetDefaultCallBack();
279 myCallBackState = Standard_False;
280 myNestedState = Standard_False;
283 //=======================================================================
284 //function : SetVersion
285 //purpose : returns version of the schema
286 //=======================================================================
288 void Storage_Schema::SetVersion(const TCollection_AsciiString& aVersion)
290 myVersion = aVersion;
293 //=======================================================================
295 //purpose : returns the version of the schema
296 //=======================================================================
298 TCollection_AsciiString Storage_Schema::Version() const
303 //=======================================================================
305 //purpose : set the schema's name
306 //=======================================================================
308 void Storage_Schema::SetName(const TCollection_AsciiString& aSchemaName)
310 myName = aSchemaName;
313 //=======================================================================
315 //purpose : returns the schema's name
316 //=======================================================================
318 TCollection_AsciiString Storage_Schema::Name() const
323 //=======================================================================
327 // s: driver to write
328 // raises if the stream is not opened in VSWrite or
330 //=======================================================================
332 void Storage_Schema::Write
333 (Storage_BaseDriver& f,
334 const Handle(Storage_Data)& aData) const
336 if (aData.IsNull()) return;
338 // add all the persistent to write...
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);
346 Handle(Storage_InternalData) iData = aData->InternalData();
349 aData->ClearErrorStatus();
351 plist = aData->Roots();
353 for (posto = 1; posto <= plist->Length(); posto++) {
354 PersistentToAdd(plist->Value(posto)->Object());
357 for (posto = 1; posto <= plist->Length(); posto++) {
358 AddTypeSelection(plist->Value(posto)->Object());
361 for (posfrom = plist->Length() + 1; posfrom <= iData->myPtoA.Length(); posfrom++) {
362 AddTypeSelection(iData->myPtoA.Value(posfrom));
365 // ...and now we write
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);
376 if ((f.OpenMode() == Storage_VSWrite) || (f.OpenMode() == Storage_VSReadWrite)) {
379 errorContext = "BeginWriteInfoSection";
380 f.BeginWriteInfoSection();
381 errorContext = "WriteInfo";
382 f.WriteInfo(aData->NumberOfObjects(),
383 aData->StorageVersion(),
384 aData->CreationDate(),
386 aData->SchemaVersion(),
387 aData->ApplicationName(),
388 aData->ApplicationVersion(),
391 errorContext = "EndWriteInfoSection";
392 f.EndWriteInfoSection();
394 errorContext = "BeginWriteCommentSection";
395 f.BeginWriteCommentSection();
396 errorContext = "WriteComment";
397 f.WriteComment(aData->Comments());
398 errorContext = "EndWriteCommentSection";
399 f.EndWriteCommentSection();
401 Handle(TColStd_HSequenceOfAsciiString) tlist;
403 tlist = aData->Types();
405 errorContext = "BeginWriteTypeSection";
406 f.BeginWriteTypeSection();
407 len = aData->NumberOfTypes();
409 Handle(Storage_HArrayOfCallBack) WFunc = new Storage_HArrayOfCallBack(1,len);
411 f.SetTypeSectionSize(len);
413 Storage_DataMapIteratorOfMapOfCallBack cbit(iData->myTypeBinding);
414 Handle(Storage_TypedCallBack) atcallBack;
416 for (; cbit.More(); cbit.Next()) {
417 atcallBack = cbit.Value();
418 WFunc->SetValue(atcallBack->Index(),atcallBack->CallBack());
421 errorContext = "WriteTypeInformations";
422 for (i = 1; i <= len; i++) {
423 f.WriteTypeInformations(i,tlist->Value(i).ToCString());
426 errorContext = "EndWriteTypeSection";
427 f.EndWriteTypeSection();
429 errorContext = "BeginWriteRootSection";
430 f.BeginWriteRootSection();
431 f.SetRootSectionSize(plist->Length());
433 errorContext = "WriteRoot";
434 for (i = 1; i <= plist->Length(); i++) {
435 f.WriteRoot(plist->Value(i)->Name(),i,plist->Value(i)->Type());
438 errorContext = "EndWriteRootSection";
439 f.EndWriteRootSection();
441 errorContext = "BeginWriteRefSection";
442 f.BeginWriteRefSection();
443 f.SetRefSectionSize(iData->myObjId - 1);
444 errorContext = "WriteReferenceType";
446 Storage_BucketIterator bit(&iData->myPtoA);
450 if (!p.IsNull()) f.WriteReferenceType(p->_refnum,p->_typenum);
454 errorContext = "EndWriteRefSection";
455 f.EndWriteRefSection();
457 errorContext = "BeginWriteDataSection";
458 f.BeginWriteDataSection();
460 Handle(Storage_Schema) me = this;
462 errorContext = "Write";
469 WFunc->Value(p->_typenum)->Write(p,f,me);
475 errorContext = "EndWriteDataSection";
476 f.EndWriteDataSection();
478 catch(Storage_StreamWriteError) {
479 aData->SetErrorStatus(Storage_VSWriteError);
480 aData->SetErrorStatusExtension(errorContext);
484 aData->SetErrorStatus(Storage_VSModeError);
485 aData->SetErrorStatusExtension("OpenMode");
492 //=======================================================================
494 //purpose : ...and read a Storage file
497 //=======================================================================
499 Handle(Storage_Data) Storage_Schema::Read(Storage_BaseDriver& f) const
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;
507 Handle(Standard_Persistent) per;
508 Handle(Storage_HArrayOfCallBack) theCallBack;
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();
515 if ((f.OpenMode() == Storage_VSRead) || (f.OpenMode() == Storage_VSReadWrite)) {
517 Storage_Schema::ISetCurrentData(dData);
519 // IReadHeaderSection can set an error status
521 result = IReadHeaderSection(f,hData);
524 Handle(Storage_CallBack) accallBack;
526 TCollection_AsciiString typeName;
528 iData->myReadArray = new Storage_HPArray(1,dData->NumberOfObjects());
530 // IReadTypeSection can set an error status
532 result = IReadTypeSection(f,tData);
535 len = dData->NumberOfTypes();
536 theCallBack = new Storage_HArrayOfCallBack(1,len);
540 for (i = 1; i <= len; i++) {
541 typeName = tData->Type(i);
542 p = tData->Type(typeName);
543 theCallBack->SetValue(p,CallBackSelection(typeName));
546 catch(Storage_StreamUnknownTypeError) {
547 result = Standard_False;
548 dData->SetErrorStatus(Storage_VSUnknownType);
549 dData->SetErrorStatusExtension(typeName);
554 dData->SetErrorStatus(tData->ErrorStatus());
555 dData->SetErrorStatusExtension(tData->ErrorStatusExtension());
559 dData->SetErrorStatus(hData->ErrorStatus());
560 dData->SetErrorStatusExtension(hData->ErrorStatusExtension());
564 result = IReadRootSection(f,rData);
565 dData->SetErrorStatus(rData->ErrorStatus());
566 if (!result) dData->SetErrorStatusExtension(rData->ErrorStatusExtension());
570 Standard_Integer otype,oref;
572 errorCode = f.BeginReadRefSection();
574 if (errorCode == Storage_VSOk) {
578 len = f.RefSectionSize();
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;
586 catch(Storage_StreamTypeMismatchError) {
587 TCollection_AsciiString aOref = oref;
588 result = Standard_False;
589 dData->SetErrorStatus(Storage_VSTypeMismatch);
590 dData->SetErrorStatusExtension(aOref);
595 errorCode = f.EndReadRefSection();
596 result = (errorCode == Storage_VSOk);
597 dData->SetErrorStatus(errorCode);
598 if (!result) dData->SetErrorStatusExtension("EndReadRefSection");
602 result = Standard_False;
603 dData->SetErrorStatus(errorCode);
604 dData->SetErrorStatusExtension("BeginReadRefSection");
609 errorCode = f.BeginReadDataSection();
610 result = (errorCode == Storage_VSOk);
611 dData->SetErrorStatus(errorCode);
612 if (!result) dData->SetErrorStatusExtension("BeginReadDataSection");
616 Handle(Storage_Schema) me = this;
617 Handle(Storage_CallBack) rcback;
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);
631 catch(Storage_StreamTypeMismatchError) {
632 result = Standard_False;
633 dData->SetErrorStatus(Storage_VSTypeMismatch);
634 dData->SetErrorStatusExtension(i-1);
636 catch(Storage_StreamFormatError) {
637 result = Standard_False;
638 dData->SetErrorStatus(Storage_VSFormatError);
639 dData->SetErrorStatusExtension(i-1);
641 catch(Storage_StreamReadError) {
642 result = Standard_False;
643 dData->SetErrorStatus(Storage_VSFormatError);
644 dData->SetErrorStatusExtension(i-1);
649 Handle(Storage_HSeqOfRoot) rlist = rData->Roots();
650 Handle(Storage_Root) rroot;
652 for(i = 1; i <= dData->NumberOfRoots(); i++) {
653 rroot = rlist->Value(i);
654 rData->UpdateRoot(rroot->Name(),iData->myReadArray->Value(rroot->Reference()));
657 errorCode = f.EndReadDataSection();
658 result = (errorCode == Storage_VSOk);
659 dData->SetErrorStatus(errorCode);
660 if (!result) dData->SetErrorStatusExtension("EndReadDataSection");
665 dData->SetErrorStatus(Storage_VSModeError);
666 dData->SetErrorStatusExtension("OpenMode");
675 //=======================================================================
676 //function : ReadHeaderSection
677 //purpose : read the header part of the stream
680 //=======================================================================
682 Handle(Storage_HeaderData) Storage_Schema::ReadHeaderSection
683 (Storage_BaseDriver& s) const
685 Handle(Storage_HeaderData) result = new Storage_HeaderData;
687 if ((s.OpenMode() == Storage_VSRead) || (s.OpenMode() == Storage_VSReadWrite)) {
688 IReadHeaderSection(s,result);
691 result->SetErrorStatus(Storage_VSModeError);
692 result->SetErrorStatusExtension("OpenMode");
698 //=======================================================================
699 //function : ReadTypeSection
700 //purpose : fill the TypeData with the names of the type used
704 //=======================================================================
706 Handle(Storage_TypeData) Storage_Schema::ReadTypeSection
707 (Storage_BaseDriver& f) const
709 Handle(Storage_TypeData) result = new Storage_TypeData;
711 if ((f.OpenMode() == Storage_VSRead) || (f.OpenMode() == Storage_VSReadWrite)) {
712 IReadTypeSection(f,result);
715 result->SetErrorStatus(Storage_VSModeError);
716 result->SetErrorStatusExtension("OpenMode");
722 //=======================================================================
723 //function : ReadRootSection
724 //purpose : read root part of the file
727 //=======================================================================
729 Handle(Storage_RootData) Storage_Schema::ReadRootSection
730 (Storage_BaseDriver& f) const
732 Handle(Storage_RootData) result = new Storage_RootData;
734 if ((f.OpenMode() == Storage_VSRead) || (f.OpenMode() == Storage_VSReadWrite)) {
735 IReadRootSection(f,result);
738 result->SetErrorStatus(Storage_VSModeError);
739 result->SetErrorStatusExtension("OpenMode");
745 //=======================================================================
746 //function : SchemaKnownTypes
747 //purpose : returns the known types of a schema
748 //=======================================================================
750 const TColStd_SequenceOfAsciiString& Storage_Schema::SchemaKnownTypes() const
752 static TColStd_SequenceOfAsciiString aSeq;
756 //=======================================================================
757 //function : GetAllSchemaKnownTypes
758 //purpose : returns the all known types of a schema and their
760 //PTV : add get of all known type for inheritance of schemas
761 //=======================================================================
763 Handle(TColStd_HSequenceOfAsciiString) Storage_Schema::
764 GetAllSchemaKnownTypes() const
766 Handle(TColStd_HSequenceOfAsciiString) aSeqOfType = new TColStd_HSequenceOfAsciiString;
767 const TColStd_SequenceOfAsciiString& alocalTypeList = SchemaKnownTypes();
769 for (Standard_Integer k = 1; k <= alocalTypeList.Length(); k++)
770 aSeqOfType->Append(alocalTypeList.Value(k));
772 // get nested schemas
773 Handle(Storage_HArrayOfSchema) aNestedSchemas = NestedSchemas();
774 if (!aNestedSchemas.IsNull())
776 for (Standard_Integer i = aNestedSchemas->Lower(); i <= aNestedSchemas->Upper(); i++)
778 Handle(Storage_Schema) aSchema = aNestedSchemas->Value(i);
779 if (aSchema.IsNull())
782 Handle(TColStd_HSequenceOfAsciiString) typeList = aSchema->GetAllSchemaKnownTypes();
783 for (Standard_Integer j = 1; j <= typeList->Length(); j++)
784 aSeqOfType->Append(typeList->Value(j));
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 //=======================================================================
799 Standard_Boolean Storage_Schema::HasUnknownType
800 (Storage_BaseDriver& f,
801 TColStd_SequenceOfAsciiString& theUnknownTypes) const
803 Standard_Boolean result = Standard_False;
804 Handle(TColStd_HSequenceOfAsciiString) typeList = GetAllSchemaKnownTypes();
806 Handle(Storage_TypeData) tData;
808 tData = ReadTypeSection(f);
810 result = (tData->ErrorStatus() != Storage_VSOk);
814 TColStd_MapOfAsciiString names;
816 for (i = 1; i <= typeList->Length(); i++) {
817 names.Add(typeList->Value(i));
820 Handle(TColStd_HSequenceOfAsciiString) flist = tData->Types();
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;
833 //=======================================================================
834 //function : SetNestedSchemas
836 //=======================================================================
838 void Storage_Schema::SetNestedSchemas
839 (const Handle(Storage_HArrayOfSchema)& theSchemas)
841 myArrayOfSchema = theSchemas;
844 //=======================================================================
845 //function : ClearNestedSchemas
847 //=======================================================================
849 void Storage_Schema::ClearNestedSchemas()
851 myArrayOfSchema.Nullify();
854 //=======================================================================
855 //function : NestedSchemas
857 //=======================================================================
859 Handle(Storage_HArrayOfSchema) Storage_Schema::NestedSchemas() const
861 return myArrayOfSchema;
864 //=======================================================================
865 //function : AddReadUnknownTypeCallBack
866 //purpose : add two functions to the callback list
867 //=======================================================================
869 void Storage_Schema::AddReadUnknownTypeCallBack
870 (const TCollection_AsciiString& aTypeName,
871 const Handle(Storage_CallBack)& aCallBack)
873 if (!aCallBack.IsNull()) {
874 Handle(Storage_TypedCallBack) aTCallBack = new Storage_TypedCallBack(aTypeName,aCallBack);
876 myCallBack.Bind(aTypeName,aTCallBack);
880 //=======================================================================
881 //function : RemoveReadUnknownTypeCallBack
882 //purpose : remove a callback for a type
883 //=======================================================================
885 void Storage_Schema::RemoveReadUnknownTypeCallBack
886 (const TCollection_AsciiString& aTypeName)
888 if (myCallBack.IsBound(aTypeName)) {
889 myCallBack.UnBind(aTypeName);
893 //=======================================================================
894 //function : InstalledCallBackList
895 //purpose : returns a list of type name with installed
897 //=======================================================================
899 Handle(TColStd_HSequenceOfAsciiString) Storage_Schema::
900 InstalledCallBackList() const
902 Storage_DataMapIteratorOfMapOfCallBack it(myCallBack);
903 Handle(TColStd_HSequenceOfAsciiString) result = new TColStd_HSequenceOfAsciiString;
905 for (; it.More(); it.Next()) {
906 result->Append(it.Key());
912 //=======================================================================
913 //function : ClearCallBackList
914 //purpose : clear all callback from schema instance.
915 //=======================================================================
917 void Storage_Schema::ClearCallBackList()
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 //=======================================================================
929 void Storage_Schema::UseDefaultCallBack()
931 myCallBackState = Standard_True;
934 //=======================================================================
935 //function : DontUseDefaultCallBack
936 //purpose : tells schema to uninstall the default callback.
937 //=======================================================================
939 void Storage_Schema::DontUseDefaultCallBack()
941 myCallBackState = Standard_False;
944 //=======================================================================
945 //function : IsUsingDefaultCallBack
946 //purpose : ask if the schema is using the default callback.
947 //=======================================================================
949 Standard_Boolean Storage_Schema::IsUsingDefaultCallBack() const
951 return myCallBackState;
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 //=======================================================================
961 void Storage_Schema::SetDefaultCallBack(const Handle(Storage_CallBack)& f)
963 myDefaultCallBack = f;
966 //=======================================================================
967 //function : ResetDefaultCallBack
968 //purpose : reset the default function defined by Storage
970 //=======================================================================
972 void Storage_Schema::ResetDefaultCallBack()
974 myDefaultCallBack = new Storage_DefaultCallBack;
977 //=======================================================================
978 //function : DefaultCallBack
979 //purpose : returns the read function used when the
980 // UseDefaultCallBack() is set.
981 //=======================================================================
983 Handle(Storage_CallBack) Storage_Schema::DefaultCallBack() const
985 return myDefaultCallBack;
988 //=======================================================================
989 //function : ResolveUnknownType
991 //=======================================================================
993 Handle(Storage_CallBack) Storage_Schema::ResolveUnknownType
994 (const TCollection_AsciiString& aTypeName,
995 const Handle(Standard_Persistent)& p,
996 const Storage_SolveMode aMode) const
998 Handle(Storage_CallBack) theCallBack;
1000 if (!myArrayOfSchema.IsNull()) {
1002 Standard_Boolean IsNotFound = Standard_True;
1003 Standard_Boolean AlreadyMatched;
1005 for(i = myArrayOfSchema->Lower(); i <= myArrayOfSchema->Upper() && IsNotFound; i++) {
1006 Handle(Storage_Schema) aSchema = myArrayOfSchema->Value(i);
1008 if (!aSchema.IsNull()) {
1009 AlreadyMatched = aSchema->SetNested();
1010 if (!AlreadyMatched) {
1011 if (aMode == Storage_WriteSolve || aMode == Storage_ReadSolve) {
1012 theCallBack = aSchema->CallBackSelection(aTypeName);
1014 else if (aMode == Storage_AddSolve) {
1015 theCallBack = aSchema->AddTypeSelection(p);
1017 aSchema->UnsetNested();
1018 IsNotFound = theCallBack.IsNull();
1024 if (!myNestedState && theCallBack.IsNull()) {
1025 if (myCallBack.IsBound(aTypeName)) {
1026 theCallBack = myCallBack.Find(aTypeName)->CallBack();
1028 else if (myCallBackState == Standard_True) {
1029 theCallBack = myDefaultCallBack;
1033 Standard_SStream aMsg;
1035 aMsg << "Unknown type " << aTypeName << " in schema ";
1037 if (!myName.IsEmpty()) {
1041 Storage_StreamUnknownTypeError::Raise(aMsg);
1048 //=======================================================================
1049 //function : CallBackSelection
1051 //=======================================================================
1053 Handle(Storage_CallBack) Storage_Schema::CallBackSelection
1054 (const TCollection_AsciiString&) const
1056 Handle(Storage_CallBack) theCallBack;
1061 //=======================================================================
1062 //function : AddTypeSelection
1064 //=======================================================================
1066 Handle(Storage_CallBack) Storage_Schema::AddTypeSelection
1067 (const Handle(Standard_Persistent)&) const
1069 Handle(Storage_CallBack) theCallBack;
1074 //=======================================================================
1075 //function : BindType
1077 //=======================================================================
1079 void Storage_Schema::BindType
1080 (const TCollection_AsciiString& aTypeName,
1081 const Handle(Storage_CallBack)& aCallBack) const
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);
1088 tData->AddType(aTypeName,iData->myTypeId);
1089 c->SetIndex(iData->myTypeId++);
1090 iData->myTypeBinding.Bind(aTypeName,c);
1094 //=======================================================================
1095 //function : TypeBinding
1097 //=======================================================================
1099 Handle(Storage_CallBack) Storage_Schema::TypeBinding
1100 (const TCollection_AsciiString& aTypeName) const
1102 Handle(Storage_CallBack) result;
1104 if (HasTypeBinding(aTypeName)) {
1105 Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
1107 result = iData->myTypeBinding.Find(aTypeName)->CallBack();
1113 //=======================================================================
1114 //function : ReadPersistentReference
1116 //=======================================================================
1118 void Storage_Schema::ReadPersistentReference
1119 (Handle(Standard_Persistent)& sp,
1120 Storage_BaseDriver& f)
1122 Standard_Integer ref;
1124 f.GetReference(ref);
1127 Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
1129 sp = iData->myReadArray->Value(ref);
1136 //=======================================================================
1137 //function : AddPersistent
1139 //=======================================================================
1141 Standard_Boolean Storage_Schema::AddPersistent
1142 (const Handle(Standard_Persistent)& sp,
1143 const Standard_CString tName) const
1145 Standard_Boolean result = Standard_False;
1148 Handle(Storage_InternalData) iData = Storage_Schema::ICurrentData()->InternalData();
1150 if (sp->_typenum == 0) {
1151 Standard_Integer aTypenum;
1152 static TCollection_AsciiString aTypeName;
1154 Handle(Storage_TypeData) tData = Storage_Schema::ICurrentData()->TypeData();
1156 aTypenum = iData->myTypeBinding.Find(aTypeName)->Index();
1158 sp->_typenum = aTypenum;
1159 sp->_refnum = iData->myObjId++;
1161 result = Standard_True;
1168 //=======================================================================
1169 //function : PersistentToAdd
1171 //=======================================================================
1173 Standard_Boolean Storage_Schema::PersistentToAdd
1174 (const Handle(Standard_Persistent)& sp) const
1176 Standard_Boolean result = Standard_False;
1179 Handle(Storage_InternalData) di = Storage_Schema::ICurrentData()->InternalData();
1181 if (sp->_typenum == 0 && sp->_refnum != -1) {
1182 result = Standard_True;
1184 di->myPtoA.Append(sp);
1191 //=======================================================================
1194 //=======================================================================
1196 void Storage_Schema::Clear() const
1198 Storage_Schema::ICurrentData().Nullify();
1201 //=======================================================================
1202 //function : IReadHeaderSection
1204 //=======================================================================
1206 Standard_Boolean Storage_Schema::IReadHeaderSection
1207 (Storage_BaseDriver& f,
1208 const Handle(Storage_HeaderData)& iData) const
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;
1218 errorCode = f.BeginReadInfoSection();
1220 if (errorCode == Storage_VSOk) {
1230 mApplicationVersion,
1234 catch(Storage_StreamTypeMismatchError) {
1235 iData->SetErrorStatus(Storage_VSTypeMismatch);
1236 iData->SetErrorStatusExtension("ReadInfo");
1237 return Standard_False;
1239 catch(Storage_StreamExtCharParityError) {
1240 iData->SetErrorStatus(Storage_VSExtCharParityError);
1241 iData->SetErrorStatusExtension("ReadInfo");
1242 return Standard_False;
1247 errorCode = f.EndReadInfoSection();
1249 iData->SetErrorStatus(errorCode);
1251 result = (errorCode == Storage_VSOk);
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);
1265 for (i = 1; i <= mUserInfo.Length(); i++) {
1266 iData->AddToUserInfo(mUserInfo.Value(i));
1269 errorCode = f.BeginReadCommentSection();
1271 if (errorCode == Storage_VSOk) {
1276 f.ReadComment(mComment);
1278 catch(Storage_StreamTypeMismatchError) {
1279 iData->SetErrorStatus(Storage_VSTypeMismatch);
1280 iData->SetErrorStatusExtension("ReadComment");
1281 return Standard_False;
1283 catch(Storage_StreamExtCharParityError) {
1284 iData->SetErrorStatus(Storage_VSExtCharParityError);
1285 iData->SetErrorStatusExtension("ReadComment");
1286 return Standard_False;
1291 errorCode = f.EndReadCommentSection();
1292 iData->SetErrorStatus(errorCode);
1293 iData->SetErrorStatusExtension("EndReadCommentSection");
1294 result = (errorCode == Storage_VSOk);
1297 for (i = 1; i <= mComment.Length(); i++) {
1298 iData->AddToComments(mComment.Value(i));
1303 result = Standard_False;
1304 iData->SetErrorStatus(errorCode);
1305 iData->SetErrorStatusExtension("BeginReadCommentSection");
1309 iData->SetErrorStatusExtension("EndReadInfoSection");
1313 iData->SetErrorStatus(errorCode);
1314 iData->SetErrorStatusExtension("BeginReadInfoSection");
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)
1330 static Standard_Boolean isChecked(Standard_False);
1331 static DataMapOfAStringAString aDMap;
1332 Standard_Boolean aMigration(Standard_False);
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);
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);
1350 aFile.ReadLine(aLine, 80, aNbReaded);
1351 if(aFile.IsAtEnd() || !aNbReaded) {
1355 #ifdef DATATYPE_MIGRATION_DEB
1356 cout << "Storage_Sheme:: Line: = " << aLine <<endl;
1358 TCollection_AsciiString aKey, aValue;
1359 aKey = aLine.Token();
1360 aValue = aLine.Token(" \t\n\r", 2);
1361 aDMap.Bind(aKey, aValue);
1365 #ifdef DATATYPE_MIGRATION_DEB
1366 cout << "Storage_Sheme:: aDataMap.Size = " << aDMap.Extent() <<endl;
1371 if(aDMap.Extent()) {
1372 if(aDMap.IsBound(oldName)) {
1374 newName = aDMap.Find(oldName);
1375 aMigration = Standard_True;
1376 #ifdef DATATYPE_MIGRATION_DEB
1377 cout << " newName = " << newName << endl;
1385 //=======================================================================
1386 //function : IReadTypeSection
1388 //=======================================================================
1390 Standard_Boolean Storage_Schema::IReadTypeSection
1391 (Storage_BaseDriver& f,
1392 const Handle(Storage_TypeData)& tData) const
1394 static Standard_Boolean result;
1395 TCollection_AsciiString typeName;
1396 Standard_Integer typeNum;
1398 Storage_Error errorCode;
1399 Standard_Integer len,i;
1401 result = Standard_False;
1402 errorCode = f.BeginReadTypeSection();
1404 if (errorCode == Storage_VSOk) {
1407 len = f.TypeSectionSize();
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;
1421 tData->AddType(typeName,typeNum);
1423 result = Standard_True;
1425 catch(Storage_StreamTypeMismatchError) {
1426 tData->SetErrorStatus(Storage_VSTypeMismatch);
1427 tData->SetErrorStatusExtension("ReadTypeInformations");
1428 return Standard_False;
1432 errorCode = f.EndReadTypeSection();
1433 result = (errorCode == Storage_VSOk);
1435 tData->SetErrorStatus(errorCode);
1436 if (!result) tData->SetErrorStatusExtension("EndReadTypeSection");
1440 tData->SetErrorStatus(errorCode);
1441 tData->SetErrorStatusExtension("BeginReadTypeSection");
1447 //=======================================================================
1448 //function : IReadRootSection
1450 //=======================================================================
1452 Standard_Boolean Storage_Schema::IReadRootSection
1453 (Storage_BaseDriver& f,
1454 const Handle(Storage_RootData)& rData) const
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;
1462 result = Standard_False;
1463 errorCode = f.BeginReadRootSection();
1465 if (errorCode == Storage_VSOk) {
1466 TCollection_AsciiString rootName,typeName;
1470 len = f.RootSectionSize();
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);
1479 result = Standard_True;
1481 catch(Storage_StreamTypeMismatchError) {
1482 result = Standard_False;
1483 rData->SetErrorStatus(Storage_VSTypeMismatch);
1484 rData->SetErrorStatusExtension("ReadRoot");
1488 errorCode = f.EndReadRootSection();
1489 result = (errorCode == Storage_VSOk);
1491 rData->SetErrorStatus(errorCode);
1492 if (!result) rData->SetErrorStatusExtension("EndReadRootSection");
1496 rData->SetErrorStatus(errorCode);
1497 rData->SetErrorStatusExtension("BeginReadRootSection");
1503 //=======================================================================
1504 //function : ISetCurrentData
1506 //=======================================================================
1508 void Storage_Schema::ISetCurrentData(const Handle(Storage_Data)& dData)
1510 Storage_Schema::ICurrentData() = dData;
1513 //=======================================================================
1514 //function : ICurrentData
1516 //=======================================================================
1518 Handle(Storage_Data)& Storage_Schema::ICurrentData()
1520 static Handle(Storage_Data) _Storage_CData;
1521 return _Storage_CData;
1526 //=======================================================================
1527 //function : ICreationDate
1529 //=======================================================================
1531 TCollection_AsciiString Storage_Schema::ICreationDate()
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);
1540 char nowstr[SLENGTH];
1542 struct tm *nowstruct;
1544 (void)setlocale(LC_ALL, "");
1546 if (time(&nowbin) == (time_t) - 1)
1547 cerr << "Storage ERROR : Could not get time of day from time()" << endl;
1549 nowstruct = localtime(&nowbin);
1551 if (strftime(nowstr, SLENGTH, "%m/%d/%Y", nowstruct) == (size_t) 0)
1552 cerr << "Storage ERROR : Could not get string from strftime()" << endl;
1554 TCollection_AsciiString t(nowstr);
1556 // on remet le LC_NUMERIC a la precedente valeur
1557 setlocale(LC_NUMERIC, oldnum);
1563 //=======================================================================
1564 //function : SetNested
1566 //=======================================================================
1568 Standard_Boolean Storage_Schema::SetNested()
1570 Standard_Boolean result = myNestedState;
1572 myNestedState = Standard_True;
1577 //=======================================================================
1578 //function : IsNested
1580 //=======================================================================
1582 Standard_Boolean Storage_Schema::IsNested() const
1584 return myNestedState;
1587 //=======================================================================
1588 //function : UnsetNested
1590 //=======================================================================
1592 Standard_Boolean Storage_Schema::UnsetNested()
1594 Standard_Boolean result = myNestedState;
1596 myNestedState = Standard_False;