0031918: Application Framework - New binary format for fast reading part of OCAF...
[occt.git] / src / BinTools / BinTools_IStream.cxx
diff --git a/src/BinTools/BinTools_IStream.cxx b/src/BinTools/BinTools_IStream.cxx
new file mode 100644 (file)
index 0000000..5d5175c
--- /dev/null
@@ -0,0 +1,257 @@
+// 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_IStream.hxx>
+#include <Storage_StreamTypeMismatchError.hxx>
+
+//=======================================================================
+//function : BinTools_IStream
+//purpose  : 
+//=======================================================================
+BinTools_IStream::BinTools_IStream (Standard_IStream& theStream)
+  : myStream (&theStream), myPosition (theStream.tellg()), myLastType (BinTools_ObjectType_Unknown)
+{}
+
+//=======================================================================
+//function : ReadType
+//purpose  : 
+//=======================================================================
+BinTools_ObjectType BinTools_IStream::ReadType()
+{
+  myLastType = BinTools_ObjectType (myStream->get());
+  myPosition++;
+  return myLastType;
+}
+
+//=======================================================================
+//function : IsReference
+//purpose  : 
+//=======================================================================
+Standard_Boolean BinTools_IStream::IsReference()
+{
+  return myLastType == BinTools_ObjectType_Reference8 || myLastType == BinTools_ObjectType_Reference16 ||
+         myLastType == BinTools_ObjectType_Reference32 || myLastType == BinTools_ObjectType_Reference64;
+}
+
+//=======================================================================
+//function : ReadReference
+//purpose  : 
+//=======================================================================
+uint64_t BinTools_IStream::ReadReference()
+{
+  uint64_t aDelta = 0;
+  uint64_t aCurrentPos = uint64_t (myStream->tellg());
+  switch (myLastType)
+  {
+  case BinTools_ObjectType_Reference8:
+    aDelta = uint64_t (myStream->get());
+    myPosition++;
+    break;
+  case BinTools_ObjectType_Reference16:
+  {
+    uint16_t aDelta16 = 0;
+    myStream->read ((char*)&aDelta16, sizeof (uint16_t));
+    myPosition += 2;
+#if DO_INVERSE
+    aDelta16 = (0 | ((aDelta16 & 0x00FF) << 8)
+      | ((aDelta16 & 0xFF00) >> 8));
+#endif
+    aDelta = uint64_t (aDelta16);
+    break;
+  }
+  case BinTools_ObjectType_Reference32:
+  {
+    uint32_t aDelta32 = 0;
+    myStream->read ((char*)&aDelta32, sizeof (uint32_t));
+    myPosition += 4;
+#if DO_INVERSE
+    aDelta32 = (0 | ((aDelta32 & 0x000000ff) << 24)
+      | ((aDelta32 & 0x0000ff00) << 8)
+      | ((aDelta32 & 0x00ff0000) >> 8)
+      | ((aDelta32 >> 24) & 0x000000ff));
+#endif
+    aDelta = uint64_t (aDelta32);
+    break;
+  }
+  case BinTools_ObjectType_Reference64:
+    myStream->read ((char*)&aDelta, sizeof (uint64_t));
+    myPosition += 8;
+#if DO_INVERSE
+    aDelta = InverseUint64 (aDelta);
+#endif
+    break;
+  default:
+    break;
+  }
+  if (aDelta == 0)
+  {
+    Standard_SStream aMsg;
+    aMsg << "BinTools_IStream::ReadReference: invalid reference " << (char)myLastType << std::endl;
+    throw Standard_Failure (aMsg.str().c_str());
+  }
+  return aCurrentPos - aDelta - 1; // add a type-byte
+}
+
+//=======================================================================
+//function : GoTo
+//purpose  : 
+//=======================================================================
+void BinTools_IStream::GoTo (const uint64_t& thePosition)
+{
+  myStream->seekg (std::streampos (thePosition));
+  myPosition = thePosition;
+}
+
+//=======================================================================
+//function : ShapeType
+//purpose  : 
+//=======================================================================
+TopAbs_ShapeEnum BinTools_IStream::ShapeType()
+{
+  return TopAbs_ShapeEnum ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) >> 2);
+}
+
+//=======================================================================
+//function : ShapeOrientation
+//purpose  : 
+//=======================================================================
+TopAbs_Orientation BinTools_IStream::ShapeOrientation()
+{
+  return TopAbs_Orientation ((Standard_Byte (myLastType) - Standard_Byte (BinTools_ObjectType_EndShape) - 1) & 3);
+}
+
+//=======================================================================
+//function : operator bool
+//purpose  : 
+//=======================================================================
+BinTools_IStream::operator bool() const
+{
+  return *myStream ? Standard_True : Standard_False;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Real& theValue)
+{
+  if (!myStream->read ((char*)&theValue, sizeof (Standard_Real)))
+    throw Storage_StreamTypeMismatchError();
+  myPosition += sizeof (Standard_Real);
+#if DO_INVERSE
+  theValue = InverseReal (theValue);
+#endif
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Integer& theValue)
+{
+  if (!myStream->read ((char*)&theValue, sizeof (Standard_Integer)))
+    throw Storage_StreamTypeMismatchError();
+  myPosition += sizeof (Standard_Integer);
+#if DO_INVERSE
+  theValue = InverseInt (theValue);
+#endif
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (gp_Pnt& theValue)
+{
+  Standard_Real aValue;
+  for (int aCoord = 1; aCoord <= 3; aCoord++)
+  {
+    if (!myStream->read ((char*)&aValue, sizeof (Standard_Real)))
+      throw Storage_StreamTypeMismatchError();
+#if DO_INVERSE
+    aValue = InverseReal (aValue);
+#endif
+    theValue.SetCoord (aCoord, aValue);
+  }
+  myPosition += 3 * sizeof (Standard_Real);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_Byte& theValue)
+{
+  myStream->read ((char*)&theValue, sizeof (Standard_Byte));
+  myPosition += sizeof (Standard_Byte);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (Standard_ShortReal& theValue)
+{
+  myStream->read ((char*)&theValue, sizeof (Standard_ShortReal));
+  myPosition += sizeof (Standard_ShortReal);
+  return *this;
+}
+
+//=======================================================================
+//function : operator <<
+//purpose  : 
+//=======================================================================
+BinTools_IStream& BinTools_IStream::operator >> (gp_Trsf& theValue)
+{
+  Standard_Real aV1[3], aV2[3], aV3[3], aV[3];
+  *this >> aV1[0] >> aV1[1] >> aV1[2] >> aV[0];
+  *this >> aV2[0] >> aV2[1] >> aV2[2] >> aV[1];
+  *this >> aV3[0] >> aV3[1] >> aV3[2] >> aV[2];
+  theValue.SetValues (aV1[0], aV1[1], aV1[2], aV[0],
+                      aV2[0], aV2[1], aV2[2], aV[1],
+                      aV3[0], aV3[1], aV3[2], aV[2]);
+  return *this;
+}
+
+//=======================================================================
+//function : ReadBools
+//purpose  : 
+//=======================================================================
+void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3)
+{
+  Standard_Byte aByte = ReadByte();
+  theBool1 = (aByte & 1) == 1;
+  theBool2 = (aByte & 2) == 2;
+  theBool3 = (aByte & 4) == 4;
+}
+
+//=======================================================================
+//function : ReadBools
+//purpose  : 
+//=======================================================================
+void BinTools_IStream::ReadBools (Standard_Boolean& theBool1, Standard_Boolean& theBool2, Standard_Boolean& theBool3,
+  Standard_Boolean& theBool4, Standard_Boolean& theBool5, Standard_Boolean& theBool6, Standard_Boolean& theBool7)
+{
+  Standard_Byte aByte = ReadByte();
+  theBool1 = (aByte & 1) == 1;
+  theBool2 = (aByte & 2) == 2;
+  theBool3 = (aByte & 4) == 4;
+  theBool4 = (aByte & 8) == 8;
+  theBool5 = (aByte & 16) == 16;
+  theBool6 = (aByte & 32) == 32;
+  theBool7 = (aByte & 64) == 64;
+}