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