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