53d28b81e7328819776915a307728e7081fbd584
[occt.git] / src / BinObjMgt / BinObjMgt_Persistent.cxx
1 // Created on: 2002-10-30
2 // Created by: Michael SAZONOV
3 // Copyright (c) 2002-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #include <BinObjMgt_Persistent.ixx>
22 #include <TColStd_ListOfInteger.hxx>
23 #include <TDF_Tool.hxx>
24 #include <TColStd_ListIteratorOfListOfInteger.hxx>
25 #include <FSD_FileHeader.hxx>
26
27 #define BP_INTSIZE         ((Standard_Integer)sizeof(Standard_Integer))
28 #define BP_EXTCHARSIZE     ((Standard_Integer)sizeof(Standard_ExtCharacter))
29 #define BP_REALSIZE        ((Standard_Integer)sizeof(Standard_Real))
30 #define BP_SHORTREALSIZE   ((Standard_Integer)sizeof(Standard_ShortReal))
31 #define BP_UUIDSIZE        ((Standard_Integer)sizeof(BinObjMgt_UUID))
32
33 // We define a GUID structure that is different from Standard_UUID because
34 // the latter contains a 'unsigned long' member that has variables size
35 // (4 or 8 bits) thus making the persistent files non-portable.
36 // This structure below ensures the portability.
37 typedef struct {
38   unsigned int   Data1 ;        // 4-bytes long on all OS
39   unsigned short Data2 ;        // 2-bytes long on all OS
40   unsigned short Data3 ;        // 2-bytes long on all OS
41   unsigned char  Data4[8] ;     // 8-bytes long on all OS
42 } BinObjMgt_UUID ;
43
44 //=======================================================================
45 //function : BinObjMgt_Persistent
46 //purpose  : Empty constructor
47 //=======================================================================
48
49 BinObjMgt_Persistent::BinObjMgt_Persistent ()
50      : myIndex (1),
51        myOffset(BP_HEADSIZE),
52        mySize  (BP_HEADSIZE),
53        myIsError (Standard_False)
54 {
55   Init();
56 }
57
58 //=======================================================================
59 //function : Init
60 //purpose  : Initializes me to reuse again
61 //=======================================================================
62
63 void BinObjMgt_Persistent::Init ()
64 {
65   if (myData.IsEmpty()) {
66     Standard_Address aPiece = Standard::Allocate (BP_PIECESIZE);
67     myData.Append (aPiece);
68   }
69   Standard_Integer *aData = (Standard_Integer*) myData(1);
70   aData[0] = 0;         // Type Id
71   aData[1] = 0;         // Object Id
72   aData[2] = 0;         // Data length
73   myIndex = 1;
74   myOffset = BP_HEADSIZE;
75   mySize = BP_HEADSIZE;
76   myIsError = Standard_False;
77 }
78
79 //=======================================================================
80 //function : Write
81 //purpose  : Stores <me> to the stream.
82 //           inline Standard_OStream& operator<< (Standard_OStream&,
83 //           const BinObjMgt_Persistent&) is also available
84 //=======================================================================
85
86 Standard_OStream& BinObjMgt_Persistent::Write (Standard_OStream& theOS)
87 {
88   Standard_Integer nbWritten = 0;
89   Standard_Integer *aData = (Standard_Integer*) myData(1);
90   // update data length
91   aData[2] = mySize - BP_HEADSIZE;
92 #if DO_INVERSE
93   aData[0] = InverseInt (aData[0]);
94   aData[1] = InverseInt (aData[1]);
95   aData[2] = InverseInt (aData[2]);
96 #endif
97   for (Standard_Integer i=1;
98        theOS && nbWritten < mySize && i <= myData.Length();
99        i++) {
100     Standard_Integer nbToWrite = Min (mySize - nbWritten, BP_PIECESIZE);
101     theOS.write ((char*)myData(i), nbToWrite);
102     nbWritten += nbToWrite;
103   }
104   myIndex = 1;
105   myOffset = BP_HEADSIZE;
106   mySize = BP_HEADSIZE;
107   myIsError = Standard_False;
108   return theOS;
109 }
110
111 //=======================================================================
112 //function : Read
113 //purpose  : Retrieves <me> from the stream.
114 //           inline Standard_IStream& operator>> (Standard_IStream&,
115 //           BinObjMgt_Persistent&) is also available
116 //=======================================================================
117
118 Standard_IStream& BinObjMgt_Persistent::Read (Standard_IStream& theIS)
119 {
120   myIndex = 1;
121   myOffset = BP_HEADSIZE;
122   mySize = BP_HEADSIZE;
123   myIsError = Standard_False;
124
125   Standard_Integer *aData = (Standard_Integer*) myData(1);
126   aData[0] = 0;         // Type Id
127   aData[1] = 0;         // Object Id
128   aData[2] = 0;         // Data length
129
130   // read TypeId
131   theIS.read ((char*) &aData[0], BP_INTSIZE);
132 #if DO_INVERSE
133   aData[0] = InverseInt (aData[0]);
134 #endif
135   if (theIS && aData[0] > 0) {
136     // read Id and Length
137     theIS.read ((char*)&aData[1], 2 * BP_INTSIZE);
138 #if DO_INVERSE
139     aData[1] = InverseInt (aData[1]);
140     aData[2] = InverseInt (aData[2]);
141 #endif
142     if (theIS && aData[1] > 0 && aData[2] > 0) {
143       mySize += aData[2];
144       // read remaining data
145       Standard_Integer nbRead = BP_HEADSIZE;
146       for (Standard_Integer i=1;
147            theIS && nbRead < mySize;
148            i++) {
149         if (i > myData.Length()) {
150           // grow myData dynamically
151           Standard_Address aPiece = Standard::Allocate (BP_PIECESIZE);
152           myData.Append (aPiece);
153         }
154         Standard_Integer nbToRead = Min (mySize - nbRead, BP_PIECESIZE);
155         char *ptr = (char*)myData(i);
156         if (i == 1) {
157           // 1st piece: reduce the number of bytes by header size
158           ptr += BP_HEADSIZE;
159           if (nbToRead == BP_PIECESIZE) nbToRead -= BP_HEADSIZE;
160         }
161         theIS.read (ptr, nbToRead);
162         nbRead += nbToRead;
163       }
164     }
165     else
166       aData[2] = 0;
167   }
168   return theIS;
169 }
170
171 //=======================================================================
172 //function : Destroy
173 //purpose  : Frees the allocated memory
174 //=======================================================================
175
176 void BinObjMgt_Persistent::Destroy ()
177 {
178   for (Standard_Integer i=1; i <= myData.Length(); i++) {
179     Standard::Free (myData(i));
180   }
181   myData.Clear();
182   myIndex = myOffset = mySize = 0;
183 }
184
185 //=======================================================================
186 //function : incrementData
187 //purpose  : Allocates theNbPieces more pieces
188 //=======================================================================
189
190 void BinObjMgt_Persistent::incrementData
191   (const Standard_Integer theNbPieces)
192 {
193   for (Standard_Integer i=1; i <= theNbPieces; i++) {
194     Standard_Address aPiece = Standard::Allocate (BP_PIECESIZE);
195     myData.Append (aPiece);
196   }
197 }
198
199 //=======================================================================
200 //function : PutCharacter
201 //purpose  : 
202 //=======================================================================
203
204 BinObjMgt_Persistent& BinObjMgt_Persistent::PutCharacter
205   (const Standard_Character theValue)
206 {
207   alignOffset (1);
208   prepareForPut (1);
209   Standard_Character *aData = (Standard_Character*) myData(myIndex) + myOffset;
210   *aData = theValue;
211   myOffset++;
212   return *this;
213 }
214
215 //=======================================================================
216 //function : PutByte
217 //purpose  : 
218 //=======================================================================
219
220 BinObjMgt_Persistent& BinObjMgt_Persistent::PutByte
221   (const Standard_Byte theValue)
222 {
223   alignOffset (1);
224   prepareForPut (1);
225   Standard_Byte *aData = (Standard_Byte*) myData(myIndex) + myOffset;
226   *aData = theValue;
227   myOffset++;
228   return *this;
229 }
230
231 //=======================================================================
232 //function : PutExtCharacter
233 //purpose  : 
234 //=======================================================================
235
236 BinObjMgt_Persistent& BinObjMgt_Persistent::PutExtCharacter
237   (const Standard_ExtCharacter theValue)
238 {
239   alignOffset (BP_EXTCHARSIZE, Standard_True);
240   prepareForPut (BP_EXTCHARSIZE);
241   Standard_ExtCharacter *aData =
242     (Standard_ExtCharacter*) ((char*)myData(myIndex) + myOffset);
243 #if DO_INVERSE
244   *aData = InverseExtChar (theValue);
245 #else
246   *aData = theValue;
247 #endif
248   myOffset += BP_EXTCHARSIZE;
249   return *this;
250 }
251
252 //=======================================================================
253 //function : PutInteger
254 //purpose  : 
255 //=======================================================================
256
257 BinObjMgt_Persistent& BinObjMgt_Persistent::PutInteger
258   (const Standard_Integer theValue)
259 {
260   alignOffset (BP_INTSIZE, Standard_True);
261   prepareForPut (BP_INTSIZE);
262   Standard_Integer *aData = (Standard_Integer*) ((char*)myData(myIndex) + myOffset);
263 #if DO_INVERSE
264   *aData = InverseInt (theValue);
265 #else
266   *aData = theValue;
267 #endif
268   myOffset += BP_INTSIZE;
269   return *this;
270 }
271
272 //=======================================================================
273 //function : PutReal
274 //purpose  : 
275 //=======================================================================
276
277 BinObjMgt_Persistent& BinObjMgt_Persistent::PutReal
278   (const Standard_Real theValue)
279 {
280   alignOffset (BP_INTSIZE, Standard_True);
281   Standard_Integer nbPieces = prepareForPut (BP_REALSIZE);
282   if (nbPieces > 0) {
283     // the value intersects a piece boundary => go a long way
284 #if DO_INVERSE
285     Standard_Integer aStartIndex = myIndex;
286     Standard_Integer aStartOffset = myOffset;
287 #endif
288     putArray ((void*) &theValue, BP_REALSIZE);
289 #if DO_INVERSE
290     inverseRealData (aStartIndex, aStartOffset, BP_REALSIZE);
291 #endif
292   }
293   else {
294     // the value fits in the current piece => put it quickly
295     Standard_Real *aData = (Standard_Real*) ((char*)myData(myIndex) + myOffset);
296 #if DO_INVERSE
297     *aData = InverseReal (theValue);
298 #else
299     *aData = theValue;
300 #endif
301     myOffset += BP_REALSIZE;
302   }
303   return *this;
304 }
305
306 //=======================================================================
307 //function : PutShortReal
308 //purpose  : 
309 //=======================================================================
310
311 BinObjMgt_Persistent& BinObjMgt_Persistent::PutShortReal
312   (const Standard_ShortReal theValue)
313 {
314   alignOffset (BP_INTSIZE, Standard_True);
315   prepareForPut (BP_SHORTREALSIZE);
316   Standard_ShortReal *aData = (Standard_ShortReal*) ((char*)myData(myIndex) + myOffset);
317 #if DO_INVERSE
318   *aData = InverseShortReal (theValue);
319 #else
320   *aData = theValue;
321 #endif
322   myOffset += BP_SHORTREALSIZE;
323   return *this;
324 }
325
326 //=======================================================================
327 //function : PutCString
328 //purpose  : Offset in output buffer is not aligned
329 //=======================================================================
330
331 BinObjMgt_Persistent& BinObjMgt_Persistent::PutCString
332   (const Standard_CString theValue)
333 {
334   alignOffset (1);
335   Standard_Integer aSize = strlen (theValue) + 1;
336   prepareForPut (aSize);
337   putArray ((void* const)theValue, aSize);
338   return *this;
339 }
340
341 //=======================================================================
342 //function : PutAsciiString
343 //purpose  : Offset in output buffer is word-aligned
344 //=======================================================================
345
346 BinObjMgt_Persistent& BinObjMgt_Persistent::PutAsciiString
347   (const TCollection_AsciiString& theValue)
348 {
349   alignOffset (BP_INTSIZE, Standard_True);
350   Standard_Integer aSize = theValue.Length() + 1;
351   prepareForPut (aSize);
352   putArray ((void* const)theValue.ToCString(), aSize);
353   return *this;
354 }
355
356 //=======================================================================
357 //function : PutExtendedString
358 //purpose  : Offset in output buffer is word-aligned
359 //=======================================================================
360
361 BinObjMgt_Persistent& BinObjMgt_Persistent::PutExtendedString
362   (const TCollection_ExtendedString& theValue)
363 {
364   alignOffset (BP_INTSIZE, Standard_True);
365   Standard_Integer aSize = (theValue.Length() + 1) * BP_EXTCHARSIZE;
366   prepareForPut (aSize);
367 #if DO_INVERSE
368   Standard_Integer aStartIndex = myIndex;
369   Standard_Integer aStartOffset = myOffset;
370 #endif
371   putArray ((void* const)theValue.ToExtString(), aSize);
372 #if DO_INVERSE
373   inverseExtCharData (aStartIndex, aStartOffset, aSize - BP_EXTCHARSIZE);
374 #endif
375   return *this;
376 }
377
378 //=======================================================================
379 //function : PutLabel
380 //purpose  : 
381 //=======================================================================
382
383 BinObjMgt_Persistent& BinObjMgt_Persistent::PutLabel
384   (const TDF_Label& theValue)
385 {
386   alignOffset (BP_INTSIZE, Standard_True);
387   Standard_Integer aLen = (theValue.IsNull() ? 0 : theValue.Depth()+1);
388   prepareForPut ((aLen + 1) * BP_INTSIZE);
389   Standard_Integer *aData = (Standard_Integer*) ((char*)myData(myIndex) + myOffset);
390   // store nb of tags
391 #if DO_INVERSE
392   *aData++ = InverseInt (aLen);
393 #else
394   *aData++ = aLen;
395 #endif
396   myOffset += BP_INTSIZE;
397   if (!theValue.IsNull()) {
398     TColStd_ListOfInteger aTagList;
399     TDF_Tool::TagList (theValue, aTagList);
400     TColStd_ListIteratorOfListOfInteger itTag(aTagList);
401     for (; itTag.More(); itTag.Next()) {
402       if (myOffset >= BP_PIECESIZE) {
403         myOffset = 0;
404         myIndex++;
405         aData = (Standard_Integer*) ((char*)myData(myIndex) + myOffset);
406       }
407 #if DO_INVERSE
408       *aData++ = InverseInt (itTag.Value());
409 #else
410       *aData++ = itTag.Value();
411 #endif
412       myOffset += BP_INTSIZE;
413     }
414   }
415   return *this;
416 }
417
418 //=======================================================================
419 //function : PutGUID
420 //purpose  : 
421 //=======================================================================
422
423 BinObjMgt_Persistent& BinObjMgt_Persistent::PutGUID
424   (const Standard_GUID& theValue)
425 {
426   alignOffset (BP_INTSIZE, Standard_True);
427   prepareForPut (BP_UUIDSIZE);
428   const Standard_UUID aStandardUUID = theValue.ToUUID();
429   BinObjMgt_UUID anUUID;
430   anUUID.Data1 = (unsigned int)   aStandardUUID.Data1;
431   anUUID.Data2 = (unsigned short) aStandardUUID.Data2;
432   anUUID.Data3 = (unsigned short) aStandardUUID.Data3;
433   anUUID.Data4[0] = aStandardUUID.Data4[0];
434   anUUID.Data4[1] = aStandardUUID.Data4[1];
435   anUUID.Data4[2] = aStandardUUID.Data4[2];
436   anUUID.Data4[3] = aStandardUUID.Data4[3];
437   anUUID.Data4[4] = aStandardUUID.Data4[4];
438   anUUID.Data4[5] = aStandardUUID.Data4[5];
439   anUUID.Data4[6] = aStandardUUID.Data4[6];
440   anUUID.Data4[7] = aStandardUUID.Data4[7];
441 #if DO_INVERSE
442   anUUID.Data1 = (unsigned int)   InverseInt     (anUUID.Data1);
443   anUUID.Data2 = (unsigned short) InverseExtChar (anUUID.Data2);
444   anUUID.Data3 = (unsigned short) InverseExtChar (anUUID.Data3);
445 #endif
446   putArray (&anUUID, BP_UUIDSIZE);
447   return *this;
448 }
449
450 //=======================================================================
451 //function : PutCharArray
452 //purpose  : Put C array of char, theLength is the number of elements
453 //=======================================================================
454
455 BinObjMgt_Persistent& BinObjMgt_Persistent::PutCharArray
456   (const BinObjMgt_PChar  theArray,
457    const Standard_Integer theLength)
458 {
459   alignOffset (1);
460   prepareForPut (theLength);
461   putArray (theArray, theLength);
462   return *this;
463 }
464
465 //=======================================================================
466 //function : PutByteArray
467 //purpose  : Put C array of byte, theLength is the number of elements
468 //=======================================================================
469
470 BinObjMgt_Persistent& BinObjMgt_Persistent::PutByteArray
471   (const BinObjMgt_PByte  theArray,
472    const Standard_Integer theLength)
473 {
474   alignOffset (1);
475   prepareForPut (theLength);
476   putArray (theArray, theLength);
477   return *this;
478 }
479
480 //=======================================================================
481 //function : PutExtCharArray
482 //purpose  : Put C array of ExtCharacter, theLength is the number of elements
483 //=======================================================================
484
485 BinObjMgt_Persistent& BinObjMgt_Persistent::PutExtCharArray
486   (const BinObjMgt_PExtChar theArray,
487    const Standard_Integer   theLength)
488 {
489   alignOffset (BP_EXTCHARSIZE, Standard_True);
490   Standard_Integer aSize = theLength * BP_EXTCHARSIZE;
491   prepareForPut (aSize);
492 #if DO_INVERSE
493   Standard_Integer aStartIndex = myIndex;
494   Standard_Integer aStartOffset = myOffset;
495 #endif
496   putArray (theArray, aSize);
497 #if DO_INVERSE
498   inverseExtCharData (aStartIndex, aStartOffset, aSize);
499 #endif
500   return *this;
501 }
502
503 //=======================================================================
504 //function : PutIntArray
505 //purpose  : Put C array of int, theLength is the number of elements
506 //=======================================================================
507
508 BinObjMgt_Persistent& BinObjMgt_Persistent::PutIntArray
509   (const BinObjMgt_PInteger theArray,
510    const Standard_Integer   theLength)
511 {
512   alignOffset (BP_INTSIZE, Standard_True);
513   Standard_Integer aSize = theLength * BP_INTSIZE;
514   prepareForPut (aSize);
515 #if DO_INVERSE
516   Standard_Integer aStartIndex = myIndex;
517   Standard_Integer aStartOffset = myOffset;
518 #endif
519   putArray (theArray, aSize);
520 #if DO_INVERSE
521   inverseIntData (aStartIndex, aStartOffset, aSize);
522 #endif
523   return *this;
524 }
525
526 //=======================================================================
527 //function : PutRealArray
528 //purpose  : Put C array of double, theLength is the number of elements
529 //=======================================================================
530
531 BinObjMgt_Persistent& BinObjMgt_Persistent::PutRealArray
532   (const BinObjMgt_PReal  theArray,
533    const Standard_Integer theLength)
534 {
535   alignOffset (BP_INTSIZE, Standard_True);
536   Standard_Integer aSize = theLength * BP_REALSIZE;
537   prepareForPut (aSize);
538 #if DO_INVERSE
539   Standard_Integer aStartIndex = myIndex;
540   Standard_Integer aStartOffset = myOffset;
541 #endif
542   putArray (theArray, aSize);
543 #if DO_INVERSE
544   inverseRealData (aStartIndex, aStartOffset, aSize);
545 #endif
546   return *this;
547 }
548
549 //=======================================================================
550 //function : PutShortRealArray
551 //purpose  : Put C array of float, theLength is the number of elements
552 //=======================================================================
553
554 BinObjMgt_Persistent& BinObjMgt_Persistent::PutShortRealArray
555   (const BinObjMgt_PShortReal theArray,
556    const Standard_Integer     theLength)
557 {
558   alignOffset (BP_INTSIZE, Standard_True);
559   Standard_Integer aSize = theLength * BP_SHORTREALSIZE;
560   prepareForPut (aSize);
561 #if DO_INVERSE
562   Standard_Integer aStartIndex = myIndex;
563   Standard_Integer aStartOffset = myOffset;
564 #endif
565   putArray (theArray, aSize);
566 #if DO_INVERSE
567   inverseShortRealData (aStartIndex, aStartOffset, aSize);
568 #endif
569   return *this;
570 }
571
572 //=======================================================================
573 //function : GetCharacter
574 //purpose  : 
575 //=======================================================================
576
577 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetCharacter
578   (Standard_Character& theValue) const
579 {
580   alignOffset (1);
581   if (noMoreData (1)) return *this;
582   Standard_Character *aData = (Standard_Character*) myData(myIndex) + myOffset;
583   theValue = *aData;
584   ((BinObjMgt_Persistent*)this)->myOffset++;
585   return *this;
586 }
587
588 //=======================================================================
589 //function : GetByte
590 //purpose  : 
591 //=======================================================================
592
593 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetByte
594   (Standard_Byte& theValue) const
595 {
596   alignOffset (1);
597   if (noMoreData (1)) return *this;
598   Standard_Byte *aData = (Standard_Byte*) myData(myIndex) + myOffset;
599   theValue = *aData;
600   ((BinObjMgt_Persistent*)this)->myOffset++;
601   return *this;
602 }
603
604 //=======================================================================
605 //function : GetExtCharacter
606 //purpose  : 
607 //=======================================================================
608
609 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetExtCharacter
610   (Standard_ExtCharacter& theValue) const
611 {
612   alignOffset (BP_EXTCHARSIZE);
613   if (noMoreData (BP_EXTCHARSIZE)) return *this;
614   Standard_ExtCharacter *aData =
615     (Standard_ExtCharacter*) ((char*)myData(myIndex) + myOffset);
616 #if DO_INVERSE
617   theValue = InverseExtChar (*aData);
618 #else
619   theValue = *aData;
620 #endif
621   ((BinObjMgt_Persistent*)this)->myOffset += BP_EXTCHARSIZE;
622   return *this;
623 }
624
625 //=======================================================================
626 //function : GetInteger
627 //purpose  : 
628 //=======================================================================
629
630 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetInteger
631   (Standard_Integer& theValue) const
632 {
633   alignOffset (BP_INTSIZE);
634   if (noMoreData (BP_INTSIZE)) return *this;
635   Standard_Integer *aData = (Standard_Integer*) ((char*)myData(myIndex) + myOffset);
636 #if DO_INVERSE
637   theValue = InverseInt (*aData);
638 #else
639   theValue = *aData;
640 #endif
641   ((BinObjMgt_Persistent*)this)->myOffset += BP_INTSIZE;
642   return *this;
643 }
644
645 //=======================================================================
646 //function : GetReal
647 //purpose  : 
648 //=======================================================================
649
650 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetReal
651   (Standard_Real& theValue) const
652 {
653   alignOffset (BP_INTSIZE);
654   if (noMoreData (BP_REALSIZE)) return *this;
655   Standard_Integer nbPieces = (myOffset + BP_REALSIZE - 1) / BP_PIECESIZE;
656   if (nbPieces > 0) {
657     // the value intersects a piece boundary => go a long way
658     getArray ((void*) &theValue, BP_REALSIZE);
659   }
660   else {
661     // the value fits in the current piece => get it quickly
662     Standard_Real *aData = (Standard_Real*) ((char*)myData(myIndex) + myOffset);
663     theValue = *aData;
664     ((BinObjMgt_Persistent*)this)->myOffset += BP_REALSIZE;
665   }
666 #if DO_INVERSE
667   theValue = InverseReal (theValue);
668 #endif
669   return *this;
670 }
671
672 //=======================================================================
673 //function : GetShortReal
674 //purpose  : 
675 //=======================================================================
676
677 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetShortReal
678   (Standard_ShortReal& theValue) const
679 {
680   alignOffset (BP_INTSIZE);
681   if (noMoreData (BP_SHORTREALSIZE)) return *this;
682   Standard_ShortReal *aData = (Standard_ShortReal*) ((char*)myData(myIndex) + myOffset);
683 #if DO_INVERSE
684   theValue = InverseShortReal (*aData);
685 #else
686   theValue = *aData;
687 #endif
688   ((BinObjMgt_Persistent*)this)->myOffset += BP_SHORTREALSIZE;
689   return *this;
690 }
691
692 //=======================================================================
693 //function : GetAsciiString
694 //purpose  : 
695 //=======================================================================
696
697 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetAsciiString
698   (TCollection_AsciiString& theValue) const
699 {
700   alignOffset (BP_INTSIZE);
701   Standard_Integer aStartIndex = myIndex;
702   Standard_Integer aStartOffset = myOffset;
703   BinObjMgt_Persistent* me = (BinObjMgt_Persistent*)this;
704   char *aData = (char*) myData(myIndex) + myOffset;
705
706   // count the string length
707   while (!noMoreData (1) && *aData++) {
708     me->myOffset++;
709     if (myOffset >= BP_PIECESIZE) {
710       me->myOffset = 0;
711       aData = (char*) myData(++me->myIndex);
712     }
713   }
714   if (IsError()) {
715     me->myIndex = aStartIndex;
716     me->myOffset = aStartOffset;
717     return *this;
718   }
719   me->myOffset++;  // count the end null char
720
721   if (myIndex == aStartIndex) {
722     // all string is in one piece => simply copy
723     theValue = aData - myOffset + aStartOffset;
724   }
725   else {
726     // work through buffer string
727     Standard_Integer aSize = (myIndex - aStartIndex) * BP_PIECESIZE +
728       myOffset - aStartOffset;
729     Standard_Address aString = Standard::Allocate (aSize);
730     me->myIndex = aStartIndex;
731     me->myOffset = aStartOffset;
732     getArray (aString, aSize);
733     theValue = (char*) aString;
734     Standard::Free (aString);
735   }
736
737   return *this;
738 }
739
740 //=======================================================================
741 //function : GetExtendedString
742 //purpose  : 
743 //=======================================================================
744
745 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetExtendedString
746   (TCollection_ExtendedString& theValue) const
747 {
748   alignOffset (BP_INTSIZE);
749   Standard_Integer aStartIndex = myIndex;
750   Standard_Integer aStartOffset = myOffset;
751   BinObjMgt_Persistent* me = (BinObjMgt_Persistent*)this;
752   Standard_ExtCharacter *aData =
753     (Standard_ExtCharacter*) ((char*)myData(myIndex) + myOffset);
754
755   // count the string length
756   while (!noMoreData (1) && *aData++) {
757     me->myOffset += BP_EXTCHARSIZE;
758     if (myOffset >= BP_PIECESIZE) {
759       me->myOffset = 0;
760       aData = (Standard_ExtCharacter*) myData(++me->myIndex);
761     }
762   }
763   if (IsError()) {
764     me->myIndex = aStartIndex;
765     me->myOffset = aStartOffset;
766     return *this;
767   }
768   me->myOffset += BP_EXTCHARSIZE;  // count the end null char
769
770   if (myIndex == aStartIndex) {
771     // all string is in one piece => simply copy
772     theValue = aData - (myOffset - aStartOffset) / BP_EXTCHARSIZE;
773   }
774   else {
775     // work through buffer string
776     Standard_Integer aSize = (myIndex - aStartIndex) * BP_PIECESIZE +
777       (myOffset - aStartOffset);
778     Standard_Address aString = Standard::Allocate (aSize);
779     me->myIndex = aStartIndex;
780     me->myOffset = aStartOffset;
781     getArray (aString, aSize);
782     theValue = (Standard_ExtCharacter*) aString;
783     Standard::Free (aString);
784   }
785 #if DO_INVERSE
786   Standard_PExtCharacter aString = (Standard_PExtCharacter)theValue.ToExtString();
787   for (Standard_Integer i=0; i < theValue.Length(); i++)
788     aString[i] = InverseExtChar (aString[i]);
789 #endif
790
791   return *this;
792 }
793
794 //=======================================================================
795 //function : GetLabel
796 //purpose  : 
797 //=======================================================================
798
799 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetLabel
800   (const Handle(TDF_Data)& theDS,
801    TDF_Label& theValue) const
802 {
803   theValue.Nullify();
804   alignOffset (BP_INTSIZE);
805   if (noMoreData (BP_INTSIZE)) return *this;
806   BinObjMgt_Persistent* me = (BinObjMgt_Persistent*)this;
807   // retrieve nb of tags
808   Standard_Integer *aData = (Standard_Integer*) ((char*)myData(myIndex) + myOffset);
809   Standard_Integer aLen = *aData++;
810 #if DO_INVERSE
811   aLen = InverseInt (aLen);
812 #endif
813   me->myOffset += BP_INTSIZE;
814   if (noMoreData (aLen * BP_INTSIZE)) return *this;
815
816   if (aLen > 0) {
817     // retrieve tag list
818     TColStd_ListOfInteger aTagList;
819     while (aLen > 0) {
820       if (myOffset >= BP_PIECESIZE) {
821         me->myOffset = 0;
822         me->myIndex++;
823         aData = (Standard_Integer*) ((char*)myData(myIndex) + myOffset);
824       }
825 #if DO_INVERSE
826       aTagList.Append (InverseInt (*aData++));
827 #else
828       aTagList.Append (*aData++);
829 #endif
830       me->myOffset += BP_INTSIZE;
831       aLen--;
832     }
833     // find label by entry
834     TDF_Tool::Label (theDS, aTagList, theValue, Standard_True);
835   }
836   return *this;
837 }
838
839 //=======================================================================
840 //function : GetGUID
841 //purpose  : 
842 //=======================================================================
843
844 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetGUID
845   (Standard_GUID& theValue) const
846 {
847   alignOffset (BP_INTSIZE);
848   if (noMoreData (BP_UUIDSIZE))
849     return *this;
850   BinObjMgt_UUID anUUID;
851   getArray (&anUUID, BP_UUIDSIZE);
852 #if DO_INVERSE
853   anUUID.Data1 = (unsigned int)   InverseInt     (anUUID.Data1);
854   anUUID.Data2 = (unsigned short) InverseExtChar (anUUID.Data2);
855   anUUID.Data3 = (unsigned short) InverseExtChar (anUUID.Data3);
856 #endif
857   theValue = Standard_GUID (anUUID.Data1, anUUID.Data2, anUUID.Data3,
858                             ((anUUID.Data4[0] << 8) | (anUUID.Data4[1])),
859                             anUUID.Data4[2], anUUID.Data4[3], anUUID.Data4[4],
860                             anUUID.Data4[5], anUUID.Data4[6], anUUID.Data4[7]);
861   return *this;
862 }
863
864 //=======================================================================
865 //function : GetCharArray
866 //purpose  : Get C array of char, theLength is the number of elements;
867 //           theArray must point to a 
868 //           space enough to place theLength elements
869 //=======================================================================
870
871 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetCharArray
872   (const BinObjMgt_PChar  theArray,
873    const Standard_Integer theLength) const
874 {
875   alignOffset (1);
876   if (noMoreData (theLength)) return *this;
877   getArray (theArray, theLength);
878   return *this;
879 }
880
881 //=======================================================================
882 //function : GetByteArray
883 //purpose  : Get C array of unsigned chars, theLength is the number of elements;
884 //           theArray must point to a 
885 //           space enough to place theLength elements
886 //=======================================================================
887
888 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetByteArray
889   (const BinObjMgt_PByte  theArray,
890    const Standard_Integer theLength) const
891 {
892   alignOffset (1);
893   if (noMoreData (theLength)) return *this;
894   getArray (theArray, theLength);
895   return *this;
896 }
897
898 //=======================================================================
899 //function : GetExtCharArray
900 //purpose  : Get C array of ExtCharacter, theLength is the number of elements;
901 //           theArray must point to a 
902 //           space enough to place theLength elements
903 //=======================================================================
904
905 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetExtCharArray
906   (const BinObjMgt_PExtChar theArray,
907    const Standard_Integer   theLength) const
908 {
909   alignOffset (BP_EXTCHARSIZE, Standard_True);
910   Standard_Integer aSize = theLength * BP_EXTCHARSIZE;
911   if (noMoreData (aSize)) return *this;
912   getArray (theArray, aSize);
913 #if DO_INVERSE
914   for (Standard_Integer i=0; i < theLength; i++)
915     theArray[i] = InverseExtChar (theArray[i]);
916 #endif
917   return *this;
918 }
919
920 //=======================================================================
921 //function : GetIntArray
922 //purpose  : Get C array of int, theLength is the number of elements;
923 //           theArray must point to a 
924 //           space enough to place theLength elements
925 //=======================================================================
926
927 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetIntArray
928   (const BinObjMgt_PInteger theArray,
929    const Standard_Integer   theLength) const
930 {
931   alignOffset (BP_INTSIZE, Standard_True);
932   Standard_Integer aSize = theLength * BP_INTSIZE;
933   if (noMoreData (aSize)) return *this;
934   getArray (theArray, aSize);
935 #if DO_INVERSE
936   for (Standard_Integer i=0; i < theLength; i++)
937     theArray[i] = InverseInt (theArray[i]);
938 #endif
939   return *this;
940 }
941
942 //=======================================================================
943 //function : GetRealArray
944 //purpose  : Get C array of double, theLength is the number of elements;
945 //           theArray must point to a 
946 //           space enough to place theLength elements
947 //=======================================================================
948
949 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetRealArray
950   (const BinObjMgt_PReal  theArray,
951    const Standard_Integer theLength) const
952 {
953   alignOffset (BP_INTSIZE, Standard_True);
954   Standard_Integer aSize = theLength * BP_REALSIZE;
955   if (noMoreData (aSize)) return *this;
956   getArray (theArray, aSize);
957 #if DO_INVERSE
958   for (Standard_Integer i=0; i < theLength; i++)
959     theArray[i] = InverseReal (theArray[i]);
960 #endif
961   return *this;
962 }
963
964 //=======================================================================
965 //function : GetShortRealArray
966 //purpose  : Get C array of float, theLength is the number of elements;
967 //           theArray must point to a 
968 //           space enough to place theLength elements
969 //=======================================================================
970
971 const BinObjMgt_Persistent& BinObjMgt_Persistent::GetShortRealArray
972   (const BinObjMgt_PShortReal theArray,
973    const Standard_Integer     theLength) const
974 {
975   alignOffset (BP_INTSIZE, Standard_True);
976   Standard_Integer aSize = theLength * BP_SHORTREALSIZE;
977   if (noMoreData (aSize)) return *this;
978   getArray (theArray, aSize);
979 #if DO_INVERSE
980   for (Standard_Integer i=0; i < theLength; i++)
981     theArray[i] = InverseShortReal (theArray[i]);
982 #endif
983   return *this;
984 }
985
986 //=======================================================================
987 //function : putArray
988 //purpose  : Puts theSize bytes from theArray
989 //=======================================================================
990
991 void BinObjMgt_Persistent::putArray
992   (const Standard_Address theArray,
993    const Standard_Integer theSize)
994 {
995   char *aPtr = (char*) theArray;
996   Standard_Integer aLen = theSize;
997   while (aLen > 0) {
998     if (myOffset >= BP_PIECESIZE) {
999       myIndex++;
1000       myOffset = 0;
1001     }
1002     Standard_Integer aLenInPiece = Min (aLen, BP_PIECESIZE - myOffset);
1003     char *aData = (char*) myData(myIndex) + myOffset;
1004     memcpy (aData, aPtr, aLenInPiece);
1005     aLen -= aLenInPiece;
1006     aPtr += aLenInPiece;
1007     myOffset += aLenInPiece;
1008   }
1009 }
1010
1011 //=======================================================================
1012 //function : getArray
1013 //purpose  : Gets theLength bytes into theArray
1014 //=======================================================================
1015
1016 void BinObjMgt_Persistent::getArray
1017   (const Standard_Address theArray,
1018    const Standard_Integer theSize) const
1019 {
1020   char *aPtr = (char*) theArray;
1021   Standard_Integer aLen = theSize;
1022   BinObjMgt_Persistent *me = (BinObjMgt_Persistent*) this;
1023   while (aLen > 0) {
1024     if (myOffset >= BP_PIECESIZE) {
1025       me->myIndex++;
1026       me->myOffset = 0;
1027     }
1028     Standard_Integer aLenInPiece = Min (aLen, BP_PIECESIZE - myOffset);
1029     char *aData = (char*) myData(myIndex) + myOffset;
1030     memcpy (aPtr, aData, aLenInPiece);
1031     aLen -= aLenInPiece;
1032     aPtr += aLenInPiece;
1033     me->myOffset += aLenInPiece;
1034   }
1035 }
1036
1037 //=======================================================================
1038 //function : inverseExtCharData
1039 //purpose  : Inverses bytes in the data addressed by the given values
1040 //=======================================================================
1041
1042 void BinObjMgt_Persistent::inverseExtCharData
1043   (const Standard_Integer theIndex,
1044    const Standard_Integer theOffset,
1045    const Standard_Integer theSize)
1046 {
1047   Standard_Integer anIndex = theIndex;
1048   Standard_Integer anOffset = theOffset;
1049   Standard_Integer aLen = theSize;
1050   while (aLen > 0) {
1051     Standard_Integer aLenInPiece = Min (aLen, BP_PIECESIZE - anOffset);
1052     Standard_ExtCharacter *aData = (Standard_ExtCharacter*)
1053       ( (char*) myData(anIndex) + anOffset);
1054     for (Standard_Integer i=0; i < aLenInPiece / BP_EXTCHARSIZE; i++)
1055       aData[i] = InverseExtChar (aData[i]);
1056     aLen -= aLenInPiece;
1057     anOffset += aLenInPiece;
1058     if (anOffset >= BP_PIECESIZE) {
1059       anIndex++;
1060       anOffset = 0;
1061     }
1062   }
1063 }
1064
1065 //=======================================================================
1066 //function : inverseIntData
1067 //purpose  : Inverses bytes in the data addressed by the given values
1068 //=======================================================================
1069
1070 void BinObjMgt_Persistent::inverseIntData
1071   (const Standard_Integer theIndex,
1072    const Standard_Integer theOffset,
1073    const Standard_Integer theSize)
1074 {
1075   Standard_Integer anIndex = theIndex;
1076   Standard_Integer anOffset = theOffset;
1077   Standard_Integer aLen = theSize;
1078   while (aLen > 0) {
1079     Standard_Integer aLenInPiece = Min (aLen, BP_PIECESIZE - anOffset);
1080     Standard_Integer *aData = (Standard_Integer*) ((char*)myData(anIndex) + anOffset);
1081     for (Standard_Integer i=0; i < aLenInPiece / BP_INTSIZE; i++)
1082       aData[i] = InverseInt (aData[i]);
1083     aLen -= aLenInPiece;
1084     anOffset += aLenInPiece;
1085     if (anOffset >= BP_PIECESIZE) {
1086       anIndex++;
1087       anOffset = 0;
1088     }
1089   }
1090 }
1091
1092 //=======================================================================
1093 //function : inverseRealData
1094 //purpose  : Inverses bytes in the data addressed by the given values
1095 //=======================================================================
1096
1097 void BinObjMgt_Persistent::inverseRealData
1098   (const Standard_Integer theIndex,
1099    const Standard_Integer theOffset,
1100    const Standard_Integer theSize)
1101 {
1102   Standard_Integer anIndex = theIndex;
1103   Standard_Integer anOffset = theOffset;
1104   Standard_Integer aLen = theSize;
1105   void *aPrevPtr = 0;
1106   while (aLen > 0) {
1107     Standard_Integer aLenInPiece = Min (aLen, BP_PIECESIZE - anOffset);
1108     Standard_Real *aData = (Standard_Real*) ((char*)myData(anIndex) + anOffset);
1109     if (aPrevPtr) {
1110       Standard_Integer aTmp;
1111       aTmp = InverseInt (*(Standard_Integer*)aPrevPtr);
1112       *(Standard_Integer*)aPrevPtr = InverseInt (*(Standard_Integer*)aData);
1113       *(Standard_Integer*)aData = aTmp;
1114       ((Standard_Integer*&)aData)++;
1115       aPrevPtr = 0;
1116     }
1117     for (Standard_Integer i=0; i < aLenInPiece / BP_REALSIZE; i++)
1118       aData[i] = InverseReal (aData[i]);
1119     if (aLenInPiece % BP_REALSIZE)
1120       aPrevPtr = &aData[aLenInPiece / BP_REALSIZE];
1121     aLen -= aLenInPiece;
1122     anOffset += aLenInPiece;
1123     if (anOffset >= BP_PIECESIZE) {
1124       anIndex++;
1125       anOffset = 0;
1126     }
1127   }
1128 }
1129
1130 //=======================================================================
1131 //function : inverseShortRealData
1132 //purpose  : Inverses bytes in the data addressed by the given values
1133 //=======================================================================
1134
1135 void BinObjMgt_Persistent::inverseShortRealData
1136   (const Standard_Integer theIndex,
1137    const Standard_Integer theOffset,
1138    const Standard_Integer theSize)
1139 {
1140   Standard_Integer anIndex = theIndex;
1141   Standard_Integer anOffset = theOffset;
1142   Standard_Integer aLen = theSize;
1143   while (aLen > 0) {
1144     Standard_Integer aLenInPiece = Min (aLen, BP_PIECESIZE - anOffset);
1145     Standard_ShortReal *aData =
1146       (Standard_ShortReal *) ((char *)myData(anIndex) + anOffset);
1147     for (Standard_Integer i=0; i < aLenInPiece / BP_INTSIZE; i++)
1148       aData[i] = InverseShortReal (aData[i]);
1149     aLen -= aLenInPiece;
1150     anOffset += aLenInPiece;
1151     if (anOffset >= BP_PIECESIZE) {
1152       anIndex++;
1153       anOffset = 0;
1154     }
1155   }
1156 }