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