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