0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / BinTools / BinTools_OStream.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_OStream.hxx>
15 #include <Storage_StreamTypeMismatchError.hxx>
16
17 #if DO_INVERSE
18 #include <FSD_BinaryFile.hxx>
19 #endif
20
21 //=======================================================================
22 //function : BinTools_OStream
23 //purpose  : 
24 //=======================================================================
25 BinTools_OStream::BinTools_OStream (Standard_OStream& theStream)
26   : myStream (&theStream), myPosition (theStream.tellp())
27 {}
28
29 //=======================================================================
30 //function : WriteReference
31 //purpose  : 
32 //=======================================================================
33 void BinTools_OStream::WriteReference (const uint64_t& thePosition)
34 {
35   uint64_t aDelta = myPosition - thePosition;
36   if (aDelta <= 0xFF)
37   {
38     *myStream << (Standard_Byte)BinTools_ObjectType_Reference8;
39     *myStream << (Standard_Byte)aDelta;
40     myPosition += sizeof (Standard_Byte) * 2;
41   }
42   else if (aDelta <= 0xFFFF)
43   {
44     *myStream << (Standard_Byte)BinTools_ObjectType_Reference16;
45     uint16_t aDelta16 = uint16_t (aDelta);
46 #if DO_INVERSE
47     aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
48       | ((aDelta16 & 0xFF00) >> 8));
49 #endif
50     myStream->write ((char*)&aDelta16, sizeof (uint16_t));
51     myPosition += sizeof (Standard_Byte)  + sizeof (uint16_t);
52   }
53   else if (aDelta <= 0xFFFFFFFF)
54   {
55     *myStream << (Standard_Byte)BinTools_ObjectType_Reference32;
56     uint32_t aDelta32 = uint32_t (aDelta);
57 #if DO_INVERSE
58     aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
59       | ((aDelta32 & 0x0000ff00) << 8)
60       | ((aDelta32 & 0x00ff0000) >> 8)
61       | ((aDelta32 >> 24) & 0x000000ff) );
62 #endif
63     myStream->write ((char*)&aDelta32, sizeof (uint32_t));
64     myPosition += sizeof (Standard_Byte)  + sizeof (uint32_t);
65   }
66   else
67   {
68     *myStream << (Standard_Byte)BinTools_ObjectType_Reference64;
69 #if DO_INVERSE
70     aDelta = FSD_BinaryFile::InverseUint64 (aDelta);
71 #endif
72     myStream->write ((char*)&aDelta, sizeof (uint64_t));
73     myPosition += sizeof (Standard_Byte)  + sizeof (uint64_t);
74   }
75 }
76
77 //=======================================================================
78 //function : WriteShape
79 //purpose  : 
80 //=======================================================================
81 void BinTools_OStream::WriteShape (const TopAbs_ShapeEnum& theType, const TopAbs_Orientation& theOrientation)
82 {
83   Standard_Byte aType = Standard_Byte (BinTools_ObjectType_EndShape) + 1 +   // taking into account that orientation <= 3
84     (Standard_Byte (theType) << 2) + Standard_Byte (theOrientation); // and type <= 8
85   myStream->put ((Standard_Byte)aType);
86   myPosition += sizeof (Standard_Byte);
87 }
88
89 //=======================================================================
90 //function : operator <<
91 //purpose  : 
92 //=======================================================================
93 BinTools_OStream& BinTools_OStream::operator << (const BinTools_ObjectType& theType)
94 {
95   myStream->put ((Standard_Byte)theType);
96   myPosition += sizeof (Standard_Byte);
97   return *this;
98 }
99
100 //=======================================================================
101 //function : operator <<
102 //purpose  : 
103 //=======================================================================
104 BinTools_OStream& BinTools_OStream::operator << (const Standard_Byte& theValue)
105 {
106   myStream->put (theValue);
107   myPosition += sizeof (Standard_Byte);
108   return *this;
109 }
110
111 //=======================================================================
112 //function : operator <<
113 //purpose  : 
114 //=======================================================================
115 BinTools_OStream& BinTools_OStream::operator << (const Standard_Real& theValue)
116 {
117 #if DO_INVERSE
118   const Standard_Real aRValue = FSD_BinaryFile::InverseReal (theValue);
119   myStream->write ((char*)&aRValue, sizeof (Standard_Real));
120 #else
121   myStream->write ((char*)&theValue, sizeof (Standard_Real));
122 #endif
123   myPosition += sizeof (Standard_Real);
124   return *this;
125 }
126
127 //=======================================================================
128 //function : operator <<
129 //purpose  : 
130 //=======================================================================
131 BinTools_OStream& BinTools_OStream::operator << (const Standard_Boolean& theValue)
132 {
133   myStream->put ((Standard_Byte)(theValue ? 1 : 0));
134   myPosition += sizeof (Standard_Byte);
135   return *this;
136 }
137
138 //=======================================================================
139 //function : operator <<
140 //purpose  : 
141 //=======================================================================
142 BinTools_OStream& BinTools_OStream::operator << (const Standard_Integer& theValue)
143 {
144 #if DO_INVERSE
145   const Standard_Integer aRValue = FSD_BinaryFile::InverseInt (theValue);
146   myStream->write ((char*)&aRValue, sizeof (Standard_Integer));
147 #else
148   myStream->write ((char*)&theValue, sizeof (Standard_Integer));
149 #endif
150   myPosition += sizeof (Standard_Integer);
151   return *this;
152 }
153
154 //=======================================================================
155 //function : operator <<
156 //purpose  : 
157 //=======================================================================
158 BinTools_OStream& BinTools_OStream::operator << (const Standard_ExtCharacter& theValue)
159 {
160 #if DO_INVERSE
161   const Standard_ExtCharacter aRValue = FSD_BinaryFile::InverseExtChar (theValue);
162   myStream->write ((char*)&aRValue, sizeof (Standard_ExtCharacter));
163 #else
164   myStream->write ((char*)&theValue, sizeof (Standard_ExtCharacter));
165 #endif
166   myPosition += sizeof (Standard_ExtCharacter);
167   return *this;
168 }
169
170 //=======================================================================
171 //function : operator <<
172 //purpose  : 
173 //=======================================================================
174 BinTools_OStream& BinTools_OStream::operator << (const gp_Pnt& theValue)
175 {
176 #if DO_INVERSE
177   myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
178   myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
179   myRealBuf[2] = FSD_BinaryFile::InverseReal (theValue.Z());
180 #else
181   myRealBuf[0] = theValue.X();
182   myRealBuf[1] = theValue.Y();
183   myRealBuf[2] = theValue.Z();
184 #endif
185   myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 3);
186   myPosition += sizeof (Standard_Real) * 3;
187   return *this;
188 }
189
190 //=======================================================================
191 //function : operator <<
192 //purpose  : 
193 //=======================================================================
194 BinTools_OStream& BinTools_OStream::operator << (const gp_Dir& theValue)
195 {
196 #if DO_INVERSE
197   myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
198   myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
199   myRealBuf[2] = FSD_BinaryFile::InverseReal (theValue.Z());
200 #else
201   myRealBuf[0] = theValue.X();
202   myRealBuf[1] = theValue.Y();
203   myRealBuf[2] = theValue.Z();
204 #endif
205   myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 3);
206   myPosition += sizeof (Standard_Real) * 3;
207   return *this;
208 }
209
210 //=======================================================================
211 //function : operator <<
212 //purpose  : 
213 //=======================================================================
214 BinTools_OStream& BinTools_OStream::operator << (const gp_Pnt2d& theValue)
215 {
216 #if DO_INVERSE
217   myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
218   myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
219 #else
220   myRealBuf[0] = theValue.X();
221   myRealBuf[1] = theValue.Y();
222 #endif
223   myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 2);
224   myPosition += sizeof (Standard_Real) * 2;
225   return *this;
226 }
227
228 //=======================================================================
229 //function : operator <<
230 //purpose  : 
231 //=======================================================================
232 BinTools_OStream& BinTools_OStream::operator << (const gp_Dir2d& theValue)
233 {
234 #if DO_INVERSE
235   myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
236   myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
237 #else
238   myRealBuf[0] = theValue.X();
239   myRealBuf[1] = theValue.Y();
240 #endif
241   myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 2);
242   myPosition += sizeof (Standard_Real) * 2;
243   return *this;
244 }
245
246 //=======================================================================
247 //function : operator <<
248 //purpose  : 
249 //=======================================================================
250 BinTools_OStream& BinTools_OStream::operator << (const gp_Trsf& theValue)
251 {
252   gp_XYZ aTr = theValue.TranslationPart();
253   gp_Mat aMat = theValue.VectorialPart();
254 #if DO_INVERSE
255   myRealBuf[0] = FSD_BinaryFile::InverseReal (aMat (1, 1));
256   myRealBuf[1] = FSD_BinaryFile::InverseReal (aMat (1, 2));
257   myRealBuf[2] = FSD_BinaryFile::InverseReal (aMat (1, 3));
258   myRealBuf[3] = FSD_BinaryFile::InverseReal (aTr.Coord (1));
259   myRealBuf[4] = FSD_BinaryFile::InverseReal (aMat (2, 1));
260   myRealBuf[5] = FSD_BinaryFile::InverseReal (aMat (2, 2));
261   myRealBuf[6] = FSD_BinaryFile::InverseReal (aMat (2, 3));
262   myRealBuf[7] = FSD_BinaryFile::InverseReal (aTr.Coord (2));
263   myRealBuf[8] = FSD_BinaryFile::InverseReal (aMat (3, 1));
264   myRealBuf[9] = FSD_BinaryFile::InverseReal (aMat (3, 2));
265   myRealBuf[10] = FSD_BinaryFile::InverseReal (aMat (3, 3));
266   myRealBuf[11] = FSD_BinaryFile::InverseReal (aTr.Coord (3));
267 #else
268   myRealBuf[0] = aMat (1, 1);
269   myRealBuf[1] = aMat (1, 2);
270   myRealBuf[2] = aMat (1, 3);
271   myRealBuf[3] = aTr.Coord (1);
272   myRealBuf[4] = aMat (2, 1);
273   myRealBuf[5] = aMat (2, 2);
274   myRealBuf[6] = aMat (2, 3);
275   myRealBuf[7] = aTr.Coord (2);
276   myRealBuf[8] = aMat (3, 1);
277   myRealBuf[9] = aMat (3, 2);
278   myRealBuf[10] = aMat (3, 3);
279   myRealBuf[11] = aTr.Coord (3);
280 #endif
281   myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 12);
282   myPosition += sizeof (Standard_Real) * 12;
283   return *this;
284 }
285
286 //=======================================================================
287 //function : operator <<
288 //purpose  : 
289 //=======================================================================
290 BinTools_OStream& BinTools_OStream::operator << (const Poly_Triangle& theValue)
291 {
292   theValue.Value(1);
293 #if DO_INVERSE
294   myIntBuf[0] = FSD_BinaryFile::InverseInt (theValue.Value(1));
295   myIntBuf[1] = FSD_BinaryFile::InverseInt (theValue.Value(2));
296   myIntBuf[2] = FSD_BinaryFile::InverseInt (theValue.Value(3));
297 #else
298   myIntBuf[0] = theValue.Value(1);
299   myIntBuf[1] = theValue.Value(2);
300   myIntBuf[2] = theValue.Value(3);
301 #endif
302   myStream->write ((char*)myIntBuf, sizeof (Standard_Integer) * 3);
303   myPosition += sizeof (Standard_Integer) * 3;
304   return *this;
305 }
306
307 //=======================================================================
308 //function : operator <<
309 //purpose  : 
310 //=======================================================================
311 BinTools_OStream& BinTools_OStream::operator << (const gp_Vec3f& theValue)
312 {
313 #if DO_INVERSE
314   myFloatBuf[0] = FSD_BinaryFile::InverseShortReal (theValue.x());
315   myFloatBuf[1] = FSD_BinaryFile::InverseShortReal (theValue.y());
316   myFloatBuf[2] = FSD_BinaryFile::InverseShortReal (theValue.z());
317 #else
318   myFloatBuf[0] = theValue.x();
319   myFloatBuf[1] = theValue.y();
320   myFloatBuf[2] = theValue.z();
321 #endif
322   myStream->write ((char*)myFloatBuf, sizeof (float) * 3);
323   myPosition += sizeof (float) * 3;
324   return *this;
325 }
326
327 //=======================================================================
328 //function : PutBools
329 //purpose  : 
330 //=======================================================================
331 void BinTools_OStream::PutBools (
332   const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3)
333 {
334   Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0);
335   myStream->write((char*)&aValue, sizeof(Standard_Byte));
336   myPosition += sizeof(Standard_Byte);
337 }
338
339 //=======================================================================
340 //function : PutBools
341 //purpose  : 
342 //=======================================================================
343 void BinTools_OStream::PutBools (
344   const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3,
345   const Standard_Boolean theValue4, const Standard_Boolean theValue5, const Standard_Boolean theValue6,
346   const Standard_Boolean theValue7)
347 {
348   Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0) | (theValue4 ? 8 : 0) |
349     (theValue5 ? 16 : 0) | (theValue6 ? 32 : 0) | (theValue7 ? 64 : 0);
350   myStream->write((char*)&aValue, sizeof(Standard_Byte));
351   myPosition += sizeof(Standard_Byte);
352 }