]> OCCT Git - occt.git/commitdiff
0028887: TKJT - add option to cache file content
authorkgv <kgv@opencascade.com>
Mon, 3 Jul 2017 17:22:56 +0000 (20:22 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 13 Jul 2017 14:29:50 +0000 (17:29 +0300)
Added new auxiliary class Standard_ArrayStreamBuffer implementing
std::streambuf interface for defining std::istream from allocated memory.

src/QABugs/QABugs_20.cxx
src/Standard/FILES
src/Standard/Standard_ArrayStreamBuffer.cxx [new file with mode: 0644]
src/Standard/Standard_ArrayStreamBuffer.hxx [new file with mode: 0644]
tests/bugs/xde/bug28887_1 [new file with mode: 0644]
tests/bugs/xde/bug28887_2 [new file with mode: 0644]

index e5db0780fab281ef2e29e69dd92dd949dce1ab51..e6a6a960d55df8f3f8e9db23d4858f5cdd309a6a 100644 (file)
@@ -59,6 +59,8 @@
 #include <HLRBRep_PolyHLRToShape.hxx>
 #include <HLRBRep_PolyAlgo.hxx>
 
+#include <limits>
+
 //=======================================================================
 //function : SurfaceGenOCC26675_1 
 //purpose  : Generates a surface for intersect (in corresponding
@@ -2340,6 +2342,99 @@ static Standard_Integer OCC28829 (Draw_Interpretor&, Standard_Integer, const cha
   return 0;
 }
 
+#include <NCollection_Buffer.hxx>
+#include <DDocStd_DrawDocument.hxx>
+#include <OSD_OpenFile.hxx>
+#include <Standard_ArrayStreamBuffer.hxx>
+#include <TDataStd_Name.hxx>
+#include <TDocStd_Application.hxx>
+
+#ifdef max
+  #undef max
+#endif
+
+static Standard_Integer OCC28887 (Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec)
+{
+  if (theNbArgs < 3)
+  {
+    std::cout << "Syntax error: wrong number of arguments!\n";
+    return 1;
+  }
+
+  const TCollection_AsciiString aFilePath (theArgVec[1]);
+  const TCollection_AsciiString aName     (theArgVec[2]);
+  Handle(NCollection_Buffer) aBuffer;
+  {
+    std::ifstream aFile;
+    OSD_OpenStream (aFile, aFilePath.ToCString(), std::ios::binary | std::ios::in);
+    if (!aFile.is_open())
+    {
+      std::cout << "Error: input file '" << aFilePath << "' cannot be read\n";
+      return 1;
+    }
+    aFile.seekg (0, std::ios_base::end);
+    const int64_t aFileLength = int64_t (aFile.tellg());
+    if (aFileLength > int64_t (std::numeric_limits<ptrdiff_t>::max())
+     || aFileLength < 1)
+    {
+      std::cout << "Error: input file '" << aFilePath << "' is too large\n";
+      return 1;
+    }
+    aFile.seekg (0, std::ios_base::beg);
+
+    aBuffer = new NCollection_Buffer (NCollection_BaseAllocator::CommonBaseAllocator());
+    if (!aBuffer->Allocate (size_t(aFileLength)))
+    {
+      std::cout << "Error: memory allocation (" << aFileLength << ") has failed\n";
+      return 1;
+    }
+
+    aFile.read ((char* )aBuffer->ChangeData(), aBuffer->Size());
+    if (!aFile.good())
+    {
+      std::cout << "Error: input file '" << aFilePath << "' reading failure\n";
+      return 1;
+    }
+  }
+
+  Standard_ArrayStreamBuffer aStreamBuffer ((const char* )aBuffer->ChangeData(), aBuffer->Size());
+  std::istream aStream (&aStreamBuffer);
+  // just play with seeking
+  aStream.seekg (0, std::ios_base::end);
+  aStream.seekg (0, std::ios_base::beg);
+  if (aFilePath.EndsWith (".brep")
+   || aFilePath.EndsWith (".rle"))
+  {
+    TopoDS_Shape aShape;
+    BRep_Builder aBuilder;
+    BRepTools::Read (aShape, aStream, aBuilder);
+    DBRep::Set (aName.ToCString(), aShape);
+  }
+  else
+  {
+    Handle(TDocStd_Document) aDoc;
+    Handle(TDocStd_Application) anApp = DDocStd::GetApplication();
+    Standard_CString aNameVar = aName.ToCString();
+    if (DDocStd::GetDocument (aNameVar, aDoc, Standard_False))
+    {
+      std::cout << "Error: document with name " << aName << " already exists\n";
+      return 1;
+    }
+
+    if (anApp->Open (aStream, aDoc) != PCDM_RS_OK)
+    {
+      std::cout << "Error: cannot open XDE document\n";
+      return 1;
+    }
+
+    Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc);
+    TDataStd_Name::Set (aDoc->GetData()->Root(), aName.ToCString());
+    Draw::Set (aName.ToCString(), aDrawDoc);
+  }
+
+  return 0;
+}
+
 void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   const char *group = "QABugs";
 
@@ -2363,6 +2458,10 @@ void QABugs::Commands_20(Draw_Interpretor& theCommands) {
   theCommands.Add("OCC28594", "OCC28594", __FILE__, OCC28594, group);
   theCommands.Add("OCC28784", "OCC28784 result shape", __FILE__, OCC28784, group);
   theCommands.Add("OCC28829", "OCC28829: perform invalid FPE operation", __FILE__, OCC28829, group);
+  theCommands.Add("OCC28887",
+                  "OCC28887 filePath result"
+                  "\n\t\t: Check interface for reading BRep from memory.",
+                  __FILE__, OCC28887, group);
 
   return;
 }
index 3ebe4f93df7bf0885fa2fdeb4c534f0ea8cdef6d..da33f5a0e9408c7934543ddc6bde45d371d381ef 100755 (executable)
@@ -2,6 +2,8 @@ Standard.cxx
 Standard.hxx
 Standard_AbortiveTransaction.hxx
 Standard_Address.hxx
+Standard_ArrayStreamBuffer.hxx
+Standard_ArrayStreamBuffer.cxx
 Standard_Assert.hxx
 Standard_Atomic.hxx
 Standard_Boolean.hxx
diff --git a/src/Standard/Standard_ArrayStreamBuffer.cxx b/src/Standard/Standard_ArrayStreamBuffer.cxx
new file mode 100644 (file)
index 0000000..803e334
--- /dev/null
@@ -0,0 +1,183 @@
+// Copyright (c) 2016 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 <Standard_ArrayStreamBuffer.hxx>
+
+// =======================================================================
+// function : Standard_ArrayStreamBuffer
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::Standard_ArrayStreamBuffer (const char*  theBegin,
+                                                        const size_t theSize)
+: myBegin  (theBegin),
+  myEnd    (theBegin + theSize),
+  myCurrent(theBegin)
+{
+  //
+}
+
+// =======================================================================
+// function : ~Standard_ArrayStreamBuffer
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::~Standard_ArrayStreamBuffer()
+{
+  //
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void Standard_ArrayStreamBuffer::Init (const char*  theBegin,
+                                       const size_t theSize)
+{
+  myBegin   = theBegin;
+  myEnd     = theBegin + theSize;
+  myCurrent = theBegin;
+}
+
+// =======================================================================
+// function : underflow
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::int_type Standard_ArrayStreamBuffer::underflow()
+{
+  if (myCurrent == myEnd)
+  {
+    return traits_type::eof();
+  }
+
+  return traits_type::to_int_type(*myCurrent);
+}
+
+// =======================================================================
+// function : uflow
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::int_type Standard_ArrayStreamBuffer::uflow()
+{
+  if (myCurrent == myEnd)
+  {
+    return traits_type::eof();
+  }
+
+  return traits_type::to_int_type(*myCurrent++);
+}
+
+// =======================================================================
+// function : pbackfail
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::int_type Standard_ArrayStreamBuffer::pbackfail (int_type ch)
+{
+  if (myCurrent == myBegin
+    || (ch != traits_type::eof()
+    && ch != myCurrent[-1]))
+  {
+    return traits_type::eof();
+  }
+
+  return traits_type::to_int_type(*--myCurrent);
+}
+
+// =======================================================================
+// function : showmanyc
+// purpose  :
+// =======================================================================
+std::streamsize Standard_ArrayStreamBuffer::showmanyc()
+{
+  if (myCurrent > myEnd)
+  {
+    // assert
+  }
+  return myEnd - myCurrent;
+}
+
+// =======================================================================
+// function : seekoff
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::pos_type Standard_ArrayStreamBuffer::seekoff (off_type theOff,
+                                                                          std::ios_base::seekdir theWay,
+                                                                          std::ios_base::openmode theWhich)
+{
+  switch (theWay)
+  {
+    case std::ios_base::beg:
+    {
+      myCurrent = myBegin + theOff;
+      if (myCurrent >= myEnd)
+      {
+        myCurrent = myEnd;
+      }
+      break;
+    }
+    case std::ios_base::cur:
+    {
+      myCurrent += theOff;
+      if (myCurrent >= myEnd)
+      {
+        myCurrent = myEnd;
+      }
+      break;
+    }
+    case std::ios_base::end:
+    {
+      myCurrent = myEnd - theOff;
+      if (myCurrent < myBegin)
+      {
+        myCurrent = myBegin;
+      }
+      break;
+    }
+    default:
+    {
+      break;
+    }
+  }
+  (void )theWhich;
+  return myCurrent - myBegin;
+}
+
+// =======================================================================
+// function : seekpos
+// purpose  :
+// =======================================================================
+Standard_ArrayStreamBuffer::pos_type Standard_ArrayStreamBuffer::seekpos (pos_type thePosition,
+                                                                          std::ios_base::openmode theWhich)
+{
+  return seekoff (off_type(thePosition), std::ios_base::beg, theWhich);
+}
+
+// =======================================================================
+// function : xsgetn
+// purpose  :
+// =======================================================================
+std::streamsize Standard_ArrayStreamBuffer::xsgetn (char* thePtr,
+                                                    std::streamsize theCount)
+{
+  const char* aCurrent = myCurrent + theCount;
+  if (aCurrent >= myEnd)
+  {
+    aCurrent = myEnd;
+  }
+  size_t aCopied = aCurrent - myCurrent;
+  if (aCopied == 0)
+  {
+    return 0;
+  }
+  memcpy (thePtr, myCurrent, aCopied);
+  myCurrent = aCurrent;
+  return aCopied;
+}
diff --git a/src/Standard/Standard_ArrayStreamBuffer.hxx b/src/Standard/Standard_ArrayStreamBuffer.hxx
new file mode 100644 (file)
index 0000000..6e5973b
--- /dev/null
@@ -0,0 +1,113 @@
+// Copyright (c) 2016 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.
+
+#ifndef _Standard_ArrayStreamBuffer_HeaderFile
+#define _Standard_ArrayStreamBuffer_HeaderFile
+
+#include <Standard_Type.hxx>
+
+#include <fstream>
+
+//! Custom buffer object implementing STL interface std::streambuf for streamed reading from allocated memory block.
+//! Implements minimal sub-set of methods for passing buffer to std::istream, including seek support.
+//!
+//! This class can be used for creating a seekable input stream in cases,
+//! when the source data does not satisfies Reader requirements (non-seekable stream, compressed data)
+//! or represents an in-memory resource.
+//!
+//! The memory itself is NOT managed by this class - it is up to the caller to ensure that passed memory pointer
+//! is not released during Standard_ArrayStreamBuffer lifetime.
+//!
+//! Usage example:
+//! @code
+//!   const char*  theBuffer;
+//!   const size_t theBufferLength;
+//!   Standard_ArrayStreamBuffer aStreamBuffer (theBuffer, theBufferLength);
+//!   std::istream aStream (&aStreamBuffer);
+//!   TopoDS_Shape aShape;
+//!   BRep_Builder aBuilder;
+//!   BRepTools::Read (aShape, aStream, aBuilder);
+//! @endcode
+class Standard_ArrayStreamBuffer : public std::streambuf
+{
+public:
+
+  //! Main constructor.
+  //! Passed pointer is stored as is (memory is NOT copied nor released with destructor).
+  //! @param theBegin pointer to the beggining of pre-allocated buffer
+  //! @param theSize  length of pre-allocated buffer
+  Standard_EXPORT Standard_ArrayStreamBuffer (const char*  theBegin,
+                                              const size_t theSize);
+
+  //! Destructor.
+  Standard_EXPORT virtual ~Standard_ArrayStreamBuffer();
+
+  //! (Re)-initialize the stream.
+  //! Passed pointer is stored as is (memory is NOT copied nor released with destructor).
+  //! @param theBegin pointer to the beggining of pre-allocated buffer
+  //! @param theSize  length of pre-allocated buffer
+  Standard_EXPORT virtual void Init (const char*  theBegin,
+                                     const size_t theSize);
+
+protected:
+
+  //! Get character on underflow.
+  //! Virtual function called by other member functions to get the current character
+  //! in the controlled input sequence without changing the current position.
+  Standard_EXPORT virtual int_type underflow() Standard_OVERRIDE;
+
+  //! Get character on underflow and advance position.
+  //! Virtual function called by other member functions to get the current character
+  //! in the controlled input sequence and then advance the position indicator to the next character.
+  Standard_EXPORT virtual int_type uflow() Standard_OVERRIDE;
+
+  //! Put character back in the case of backup underflow.
+  //! Virtual function called by other member functions to put a character back
+  //! into the controlled input sequence and decrease the position indicator.
+  Standard_EXPORT virtual int_type pbackfail (int_type ch) Standard_OVERRIDE;
+
+  //! Get number of characters available.
+  //! Virtual function (to be read s-how-many-c) called by other member functions
+  //! to get an estimate on the number of characters available in the associated input sequence.
+  Standard_EXPORT virtual std::streamsize showmanyc() Standard_OVERRIDE;
+
+  //! Seek to specified position.
+  Standard_EXPORT virtual pos_type seekoff (off_type theOff,
+                                            std::ios_base::seekdir theWay,
+                                            std::ios_base::openmode theWhich) Standard_OVERRIDE;
+
+  //! Change to specified position, according to mode.
+  Standard_EXPORT virtual pos_type seekpos (pos_type thePosition,
+                                            std::ios_base::openmode theWhich) Standard_OVERRIDE;
+
+public:
+
+  //! Read a bunch of bytes at once.
+  Standard_EXPORT virtual std::streamsize xsgetn (char* thePtr,
+                                                  std::streamsize theCount) Standard_OVERRIDE;
+
+private:
+
+  // copying is not allowed
+  Standard_ArrayStreamBuffer            (const Standard_ArrayStreamBuffer& );
+  Standard_ArrayStreamBuffer& operator= (const Standard_ArrayStreamBuffer& );
+
+protected:
+
+  const char* myBegin;
+  const char* myEnd;
+  const char* myCurrent;
+
+};
+
+#endif // _Standard_ArrayStreamBuffer_HeaderFile
diff --git a/tests/bugs/xde/bug28887_1 b/tests/bugs/xde/bug28887_1
new file mode 100644 (file)
index 0000000..77516f5
--- /dev/null
@@ -0,0 +1,15 @@
+puts "=========="
+puts "OCC28887 Test case for Standard_ArrayStreamBuffer class - streaming interface for reading from allocated memory block"
+puts "=========="
+puts ""
+
+pload QAcommands VISUALIZATION
+OCC28887 [locate_data_file face.brep] f
+
+vclear
+vclose ALL
+vinit View1
+vaxo
+vdisplay -dispMode 1 f
+vfit
+vdump $::imagedir/${::casename}.png
diff --git a/tests/bugs/xde/bug28887_2 b/tests/bugs/xde/bug28887_2
new file mode 100644 (file)
index 0000000..26a628b
--- /dev/null
@@ -0,0 +1,16 @@
+puts "=========="
+puts "OCC28887 Test case for Standard_ArrayStreamBuffer class - streaming interface for reading from allocated memory block"
+puts "=========="
+puts ""
+
+pload QAcommands VISUALIZATION DCAF
+catch { Close doc }
+OCC28887 [locate_data_file bug23384-doc_subshapes.xbf] doc
+
+vclear
+vclose ALL
+XShow doc
+vaxo
+vfit
+vsetdispmode 1
+vdump $::imagedir/${::casename}.png