0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / BinTools / BinTools_IStream.cxx
1 // Copyright (c) 2021 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <BinTools_IStream.hxx>
15 #include <Storage_StreamTypeMismatchError.hxx>
16
17 //=======================================================================
18 //function : BinTools_IStream
19 //purpose  : 
20 //=======================================================================
21 BinTools_IStream::BinTools_IStream (Standard_IStream& theStream)
22   : myStream (&theStream), myPosition (theStream.tellg()), myLastType (BinTools_ObjectType_Unknown)
23 {}
24
25 //=======================================================================
26 //function : ReadType
27 //purpose  : 
28 //=======================================================================
29 BinTools_ObjectType BinTools_IStream::ReadType()
30 {
31   myLastType = BinTools_ObjectType (myStream->get());
32   myPosition++;
33   return myLastType;
34 }
35
36 //=======================================================================
37 //function : IsReference
38 //purpose  : 
39 //=======================================================================
40 Standard_Boolean BinTools_IStream::IsReference()
41 {
42   return myLastType == BinTools_ObjectType_Reference8 || myLastType == BinTools_ObjectType_Reference16 ||
43          myLastType == BinTools_ObjectType_Reference32 || myLastType == BinTools_ObjectType_Reference64;
44 }
45
46 //=======================================================================
47 //function : ReadReference
48 //purpose  : 
49 //=======================================================================
50 uint64_t BinTools_IStream::ReadReference()
51 {
52   uint64_t aDelta = 0;
53   uint64_t aCurrentPos = uint64_t (myStream->tellg());
54   switch (myLastType)
55   {
56   case BinTools_ObjectType_Reference8:
57     aDelta = uint64_t (myStream->get());
58     myPosition++;
59     break;
60   case BinTools_ObjectType_Reference16:
61   {
62     uint16_t aDelta16 = 0;
63     myStream->read ((char*)&aDelta16, sizeof (uint16_t));
64     myPosition += 2;
65 #if DO_INVERSE
66     aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
67       | ((aDelta16 & 0xFF00) >> 8));
68 #endif
69     aDelta = uint64_t (aDelta16);
70     break;
71   }
72   case BinTools_ObjectType_Reference32:
73   {
74     uint32_t aDelta32 = 0;
75     myStream->read ((char*)&aDelta32, sizeof (uint32_t));
76     myPosition += 4;
77 #if DO_INVERSE
78     aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
79       | ((aDelta32 & 0x0000ff00) << 8)
80       | ((aDelta32 & 0x00ff0000) >> 8)
81       | ((aDelta32 >> 24) & 0x000000ff));
82 #endif
83     aDelta = uint64_t (aDelta32);
84     break;
85   }
86   case BinTools_ObjectType_Reference64:
87     myStream->read ((char*)&aDelta, sizeof (uint64_t));
88     myPosition += 8;
89 #if DO_INVERSE
90     aDelta = InverseUint64 (aDelta);
91 #endif
92     break;
93   default:
94     break;
95   }
96   if (aDelta == 0)
97   {
98     Standard_SStream aMsg;
99     aMsg << "BinTools_IStream::ReadReference: invalid reference " << (char)myLastType << std::endl;
100     throw Standard_Failure (aMsg.str().c_str());
101   }
102   return aCurrentPos - aDelta - 1; // add a type-byte
103 }
104
105 //=======================================================================
106 //function : GoTo
107 //purpose  : 
108 //=======================================================================
109 void BinTools_IStream::GoTo (const uint64_t& thePosition)
110 {
111   myStream->seekg (std::streampos (thePosition));
112   myPosition = thePosition;
113 }
114
115 //=======================================================================
116 //function : ShapeType
117 //purpose  : 
118 //=======================================================================
119 TopAbs_ShapeEnum BinTools_IStream::ShapeType()
120 {
121   return TopAbs_ShapeEnum ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) >> 2);
122 }
123
124 //=======================================================================
125 //function : ShapeOrientation
126 //purpose  : 
127 //=======================================================================
128 TopAbs_Orientation BinTools_IStream::ShapeOrientation()
129 {
130   return TopAbs_Orientation ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) & 3);
131 }
132
133 //=======================================================================
134 //function : operator bool
135 //purpose  : 
136 //=======================================================================
137 BinTools_IStream::operator bool() const
138 {
139   return *myStream ? Standard_True : Standard_False;
140 }
141
142 //=======================================================================
143 //function : operator <<
144 //purpose  : 
145 //=======================================================================
146 BinTools_IStream& BinTools_IStream::operator >> (Standard_Real& theValue)
147 {
148   if (!myStream->read ((char*)&theValue, sizeof (Standard_Real)))
149     throw Storage_StreamTypeMismatchError();
150   myPosition += sizeof (Standard_Real);
151 #if DO_INVERSE
152   theValue = InverseReal (theValue);
153 #endif
154   return *this;
155 }
156
157 //=======================================================================
158 //function : operator <<
159 //purpose  : 
160 //=======================================================================
161 BinTools_IStream& BinTools_IStream::operator >> (Standard_Integer& theValue)
162 {
163   if (!myStream->read ((char*)&theValue, sizeof (Standard_Integer)))
164     throw Storage_StreamTypeMismatchError();
165   myPosition += sizeof (Standard_Integer);
166 #if DO_INVERSE
167   theValue = InverseInt (theValue);
168 #endif
169   return *this;
170 }
171
172 //=======================================================================
173 //function : operator <<
174 //purpose  : 
175 //=======================================================================
176 BinTools_IStream& BinTools_IStream::operator >> (gp_Pnt& theValue)
177 {
178   Standard_Real aValue;
179   for (int aCoord = 1; aCoord <= 3; aCoord++)
180   {
181     if (!myStream->read ((char*)&aValue, sizeof (Standard_Real)))
182       throw Storage_StreamTypeMismatchError();
183 #if DO_INVERSE
184     aValue = InverseReal (aValue);
185 #endif
186     theValue.SetCoord (aCoord, aValue);
187   }
188   myPosition += 3 * sizeof (Standard_Real);
189   return *this;
190 }
191
192 //=======================================================================
193 //function : operator <<
194 //purpose  : 
195 //=======================================================================
196 BinTools_IStream& BinTools_IStream::operator >> (Standard_Byte& theValue)
197 {
198   myStream->read ((char*)&theValue, sizeof (Standard_Byte));
199   myPosition += sizeof (Standard_Byte);
200   return *this;
201 }
202
203 //=======================================================================
204 //function : operator <<
205 //purpose  : 
206 //=======================================================================
207 BinTools_IStream& BinTools_IStream::operator >> (Standard_ShortReal& theValue)
208 {
209   myStream->read ((char*)&theValue, sizeof (Standard_ShortReal));
210   myPosition += sizeof (Standard_ShortReal);
211   return *this;
212 }
213
214 //=======================================================================
215 //function : operator <<
216 //purpose  : 
217 //=======================================================================
218 BinTools_IStream& BinTools_IStream::operator >> (gp_Trsf& theValue)
219 {
220   Standard_Real aV1[3], aV2[3], aV3[3], aV[3];
221   *this >> aV1[0] >> aV1[1] >> aV1[2] >> aV[0];
222   *this >> aV2[0] >> aV2[1] >> aV2[2] >> aV[1];
223   *this >> aV3[0] >> aV3[1] >> aV3[2] >> aV[2];
224   theValue.SetValues (aV1[0], aV1[1], aV1[2], aV[0],
225                       aV2[0], aV2[1], aV2[2], aV[1],
226                       aV3[0], aV3[1], aV3[2], aV[2]);
227   return *this;
228 }
229
230 //=======================================================================
231 //function : ReadBools
232 //purpose  : 
233 //=======================================================================
234 void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3)
235 {
236   Standard_Byte aByte = ReadByte();
237   theBool1 = (aByte & 1) == 1;
238   theBool2 = (aByte & 2) == 2;
239   theBool3 = (aByte & 4) == 4;
240 }
241
242 //=======================================================================
243 //function : ReadBools
244 //purpose  : 
245 //=======================================================================
246 void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3,
247   Standard_Boolean& theBool4, Standard_Boolean& theBool5, Standard_Boolean& theBool6, Standard_Boolean& theBool7)
248 {
249   Standard_Byte aByte = ReadByte();
250   theBool1 = (aByte & 1) == 1;
251   theBool2 = (aByte & 2) == 2;
252   theBool3 = (aByte & 4) == 4;
253   theBool4 = (aByte & 8) == 8;
254   theBool5 = (aByte & 16) == 16;
255   theBool6 = (aByte & 32) == 32;
256   theBool7 = (aByte & 64) == 64;
257 }