--- /dev/null
+// Copyright (c) 2021 OPEN CASCADE SAS
+//
+// This file is part of Open CASCADE Technology software library.
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
+//
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
+
+#include <BinTools_OStream.hxx>
+#include <Storage_StreamTypeMismatchError.hxx>
+
+#if DO_INVERSE
+#include <FSD_BinaryFile.hxx>
+#endif
+
+//=======================================================================
+//function : BinTools_OStream
+//purpose :
+//=======================================================================
+BinTools_OStream::BinTools_OStream (Standard_OStream& theStream)
+ : myStream (&theStream), myPosition (theStream.tellp())
+{}
+
+//=======================================================================
+//function : WriteReference
+//purpose :
+//=======================================================================
+void BinTools_OStream::WriteReference (const uint64_t& thePosition)
+{
+ uint64_t aDelta = myPosition - thePosition;
+ if (aDelta <= 0xFF)
+ {
+ *myStream << (Standard_Byte)BinTools_ObjectType_Reference8;
+ *myStream << (Standard_Byte)aDelta;
+ myPosition += sizeof (Standard_Byte) * 2;
+ }
+ else if (aDelta <= 0xFFFF)
+ {
+ *myStream << (Standard_Byte)BinTools_ObjectType_Reference16;
+ uint16_t aDelta16 = uint16_t (aDelta);
+#if DO_INVERSE
+ aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
+ | ((aDelta16 & 0xFF00) >> 8));
+#endif
+ myStream->write ((char*)&aDelta16, sizeof (uint16_t));
+ myPosition += sizeof (Standard_Byte) + sizeof (uint16_t);
+ }
+ else if (aDelta <= 0xFFFFFFFF)
+ {
+ *myStream << (Standard_Byte)BinTools_ObjectType_Reference32;
+ uint32_t aDelta32 = uint32_t (aDelta);
+#if DO_INVERSE
+ aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
+ | ((aDelta32 & 0x0000ff00) << 8)
+ | ((aDelta32 & 0x00ff0000) >> 8)
+ | ((aDelta32 >> 24) & 0x000000ff) );
+#endif
+ myStream->write ((char*)&aDelta32, sizeof (uint32_t));
+ myPosition += sizeof (Standard_Byte) + sizeof (uint32_t);
+ }
+ else
+ {
+ *myStream << (Standard_Byte)BinTools_ObjectType_Reference64;
+#if DO_INVERSE
+ aDelta = FSD_BinaryFile::InverseUint64 (aDelta);
+#endif
+ myStream->write ((char*)&aDelta, sizeof (uint64_t));
+ myPosition += sizeof (Standard_Byte) + sizeof (uint64_t);
+ }
+}
+
+//=======================================================================
+//function : WriteShape
+//purpose :
+//=======================================================================
+void BinTools_OStream::WriteShape (const TopAbs_ShapeEnum& theType, const TopAbs_Orientation& theOrientation)
+{
+ Standard_Byte aType = Standard_Byte (BinTools_ObjectType_EndShape) + 1 + // taking into account that orientation <= 3
+ (Standard_Byte (theType) << 2) + Standard_Byte (theOrientation); // and type <= 8
+ myStream->put ((Standard_Byte)aType);
+ myPosition += sizeof (Standard_Byte);
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const BinTools_ObjectType& theType)
+{
+ myStream->put ((Standard_Byte)theType);
+ myPosition += sizeof (Standard_Byte);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Byte& theValue)
+{
+ myStream->put (theValue);
+ myPosition += sizeof (Standard_Byte);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Real& theValue)
+{
+#if DO_INVERSE
+ const Standard_Real aRValue = FSD_BinaryFile::InverseReal (theValue);
+ myStream->write ((char*)&aRValue, sizeof (Standard_Real));
+#else
+ myStream->write ((char*)&theValue, sizeof (Standard_Real));
+#endif
+ myPosition += sizeof (Standard_Real);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Boolean& theValue)
+{
+ myStream->put ((Standard_Byte)(theValue ? 1 : 0));
+ myPosition += sizeof (Standard_Byte);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_Integer& theValue)
+{
+#if DO_INVERSE
+ const Standard_Integer aRValue = FSD_BinaryFile::InverseInt (theValue);
+ myStream->write ((char*)&aRValue, sizeof (Standard_Integer));
+#else
+ myStream->write ((char*)&theValue, sizeof (Standard_Integer));
+#endif
+ myPosition += sizeof (Standard_Integer);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Standard_ExtCharacter& theValue)
+{
+#if DO_INVERSE
+ const Standard_ExtCharacter aRValue = FSD_BinaryFile::InverseExtChar (theValue);
+ myStream->write ((char*)&aRValue, sizeof (Standard_ExtCharacter));
+#else
+ myStream->write ((char*)&theValue, sizeof (Standard_ExtCharacter));
+#endif
+ myPosition += sizeof (Standard_ExtCharacter);
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Pnt& theValue)
+{
+#if DO_INVERSE
+ myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+ myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+ myRealBuf[2] = FSD_BinaryFile::InverseReal (theValue.Z());
+#else
+ myRealBuf[0] = theValue.X();
+ myRealBuf[1] = theValue.Y();
+ myRealBuf[2] = theValue.Z();
+#endif
+ myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 3);
+ myPosition += sizeof (Standard_Real) * 3;
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Dir& theValue)
+{
+#if DO_INVERSE
+ myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+ myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+ myRealBuf[2] = FSD_BinaryFile::InverseReal (theValue.Z());
+#else
+ myRealBuf[0] = theValue.X();
+ myRealBuf[1] = theValue.Y();
+ myRealBuf[2] = theValue.Z();
+#endif
+ myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 3);
+ myPosition += sizeof (Standard_Real) * 3;
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Pnt2d& theValue)
+{
+#if DO_INVERSE
+ myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+ myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+#else
+ myRealBuf[0] = theValue.X();
+ myRealBuf[1] = theValue.Y();
+#endif
+ myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 2);
+ myPosition += sizeof (Standard_Real) * 2;
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Dir2d& theValue)
+{
+#if DO_INVERSE
+ myRealBuf[0] = FSD_BinaryFile::InverseReal (theValue.X());
+ myRealBuf[1] = FSD_BinaryFile::InverseReal (theValue.Y());
+#else
+ myRealBuf[0] = theValue.X();
+ myRealBuf[1] = theValue.Y();
+#endif
+ myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 2);
+ myPosition += sizeof (Standard_Real) * 2;
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Trsf& theValue)
+{
+ gp_XYZ aTr = theValue.TranslationPart();
+ gp_Mat aMat = theValue.VectorialPart();
+#if DO_INVERSE
+ myRealBuf[0] = FSD_BinaryFile::InverseReal (aMat (1, 1));
+ myRealBuf[1] = FSD_BinaryFile::InverseReal (aMat (1, 2));
+ myRealBuf[2] = FSD_BinaryFile::InverseReal (aMat (1, 3));
+ myRealBuf[3] = FSD_BinaryFile::InverseReal (aTr.Coord (1));
+ myRealBuf[4] = FSD_BinaryFile::InverseReal (aMat (2, 1));
+ myRealBuf[5] = FSD_BinaryFile::InverseReal (aMat (2, 2));
+ myRealBuf[6] = FSD_BinaryFile::InverseReal (aMat (2, 3));
+ myRealBuf[7] = FSD_BinaryFile::InverseReal (aTr.Coord (2));
+ myRealBuf[8] = FSD_BinaryFile::InverseReal (aMat (3, 1));
+ myRealBuf[9] = FSD_BinaryFile::InverseReal (aMat (3, 2));
+ myRealBuf[10] = FSD_BinaryFile::InverseReal (aMat (3, 3));
+ myRealBuf[11] = FSD_BinaryFile::InverseReal (aTr.Coord (3));
+#else
+ myRealBuf[0] = aMat (1, 1);
+ myRealBuf[1] = aMat (1, 2);
+ myRealBuf[2] = aMat (1, 3);
+ myRealBuf[3] = aTr.Coord (1);
+ myRealBuf[4] = aMat (2, 1);
+ myRealBuf[5] = aMat (2, 2);
+ myRealBuf[6] = aMat (2, 3);
+ myRealBuf[7] = aTr.Coord (2);
+ myRealBuf[8] = aMat (3, 1);
+ myRealBuf[9] = aMat (3, 2);
+ myRealBuf[10] = aMat (3, 3);
+ myRealBuf[11] = aTr.Coord (3);
+#endif
+ myStream->write ((char*)myRealBuf, sizeof (Standard_Real) * 12);
+ myPosition += sizeof (Standard_Real) * 12;
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const Poly_Triangle& theValue)
+{
+ theValue.Value(1);
+#if DO_INVERSE
+ myIntBuf[0] = FSD_BinaryFile::InverseInt (theValue.Value(1));
+ myIntBuf[1] = FSD_BinaryFile::InverseInt (theValue.Value(2));
+ myIntBuf[2] = FSD_BinaryFile::InverseInt (theValue.Value(3));
+#else
+ myIntBuf[0] = theValue.Value(1);
+ myIntBuf[1] = theValue.Value(2);
+ myIntBuf[2] = theValue.Value(3);
+#endif
+ myStream->write ((char*)myIntBuf, sizeof (Standard_Integer) * 3);
+ myPosition += sizeof (Standard_Integer) * 3;
+ return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose :
+//=======================================================================
+BinTools_OStream& BinTools_OStream::operator << (const gp_Vec3f& theValue)
+{
+#if DO_INVERSE
+ myFloatBuf[0] = FSD_BinaryFile::InverseShortReal (theValue.x());
+ myFloatBuf[1] = FSD_BinaryFile::InverseShortReal (theValue.y());
+ myFloatBuf[2] = FSD_BinaryFile::InverseShortReal (theValue.z());
+#else
+ myFloatBuf[0] = theValue.x();
+ myFloatBuf[1] = theValue.y();
+ myFloatBuf[2] = theValue.z();
+#endif
+ myStream->write ((char*)myFloatBuf, sizeof (float) * 3);
+ myPosition += sizeof (float) * 3;
+ return *this;
+}
+
+//=======================================================================
+//function : PutBools
+//purpose :
+//=======================================================================
+void BinTools_OStream::PutBools (
+ const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3)
+{
+ Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0);
+ myStream->write((char*)&aValue, sizeof(Standard_Byte));
+ myPosition += sizeof(Standard_Byte);
+}
+
+//=======================================================================
+//function : PutBools
+//purpose :
+//=======================================================================
+void BinTools_OStream::PutBools (
+ const Standard_Boolean theValue1, const Standard_Boolean theValue2, const Standard_Boolean theValue3,
+ const Standard_Boolean theValue4, const Standard_Boolean theValue5, const Standard_Boolean theValue6,
+ const Standard_Boolean theValue7)
+{
+ Standard_Byte aValue = (theValue1 ? 1 : 0) | (theValue2 ? 2 : 0) | (theValue3 ? 4 : 0) | (theValue4 ? 8 : 0) |
+ (theValue5 ? 16 : 0) | (theValue6 ? 32 : 0) | (theValue7 ? 64 : 0);
+ myStream->write((char*)&aValue, sizeof(Standard_Byte));
+ myPosition += sizeof(Standard_Byte);
+}