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