Browse Source

Merge branch 'master' into ETC_Inc

Kim Kulling 6 years ago
parent
commit
3aa5a61516
2 changed files with 78 additions and 35 deletions
  1. 1 1
      code/Importer.cpp
  2. 77 34
      include/assimp/MemoryIOWrapper.h

+ 1 - 1
code/Importer.cpp

@@ -483,7 +483,7 @@ const aiScene* Importer::ReadFileFromMemory( const void* pBuffer,
     IOSystem* io = pimpl->mIOHandler;
     pimpl->mIOHandler = NULL;
 
-    SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength));
+    SetIOHandler(new MemoryIOSystem((const uint8_t*)pBuffer,pLength,io));
 
     // read the file and recover the previous IOSystem
     static const size_t BufSize(Importer::MaxLenHint + 28);

+ 77 - 34
include/assimp/MemoryIOWrapper.h

@@ -51,26 +51,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stdint.h>
 
 namespace Assimp    {
+    
 #define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
 #define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
 
 // ----------------------------------------------------------------------------------
 /** Implementation of IOStream to read directly from a memory buffer */
 // ----------------------------------------------------------------------------------
-class MemoryIOStream : public IOStream
-{
-    //friend class MemoryIOSystem;
+class MemoryIOStream : public IOStream {
 public:
     MemoryIOStream (const uint8_t* buff, size_t len, bool own = false)
-        : buffer (buff)
-        , length(len)
-        , pos((size_t)0)
-        , own(own)
-    {
+    : buffer (buff)
+    , length(len)
+    , pos((size_t)0)
+    , own(own) {
+        // empty
     }
 
-public:
-
     ~MemoryIOStream ()  {
         if(own) {
             delete[] buffer;
@@ -80,11 +77,13 @@ public:
     // -------------------------------------------------------------------
     // Read from stream
     size_t Read(void* pvBuffer, size_t pSize, size_t pCount)    {
-        ai_assert(pvBuffer);
-        ai_assert(pSize);
-        const size_t cnt = std::min(pCount,(length-pos)/pSize), ofs = pSize*cnt;
+        ai_assert(nullptr != pvBuffer);
+        ai_assert(0 != pSize);
+        
+        const size_t cnt = std::min( pCount, (length-pos) / pSize);
+        const size_t ofs = pSize * cnt;
 
-        memcpy(pvBuffer,buffer+pos,ofs);
+        ::memcpy(pvBuffer,buffer+pos,ofs);
         pos += ofs;
 
         return cnt;
@@ -105,14 +104,12 @@ public:
                 return AI_FAILURE;
             }
             pos = pOffset;
-        }
-        else if (aiOrigin_END == pOrigin) {
+        } else if (aiOrigin_END == pOrigin) {
             if (pOffset > length) {
                 return AI_FAILURE;
             }
             pos = length-pOffset;
-        }
-        else {
+        } else {
             if (pOffset+pos > length) {
                 return AI_FAILURE;
             }
@@ -147,12 +144,15 @@ private:
 
 // ---------------------------------------------------------------------------
 /** Dummy IO system to read from a memory buffer */
-class MemoryIOSystem : public IOSystem
-{
+class MemoryIOSystem : public IOSystem {
 public:
     /** Constructor. */
-    MemoryIOSystem (const uint8_t* buff, size_t len)
-        : buffer (buff), length(len) {
+    MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io)
+    : buffer(buff)
+    , length(len)
+    , existing_io(io)
+    , created_streams() {
+        // empty
     }
 
     /** Destructor. */
@@ -161,41 +161,84 @@ public:
 
     // -------------------------------------------------------------------
     /** Tests for the existence of a file at the given path. */
-    bool Exists( const char* pFile) const {
-        return !strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH);
+    bool Exists(const char* pFile) const override {
+        if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
+            return true;
+        }
+        return existing_io ? existing_io->Exists(pFile) : false;
     }
 
     // -------------------------------------------------------------------
     /** Returns the directory separator. */
-    char getOsSeparator() const {
-        return '/'; // why not? it doesn't care
+    char getOsSeparator() const override {
+        return existing_io ? existing_io->getOsSeparator()
+                           : '/';  // why not? it doesn't care
     }
 
     // -------------------------------------------------------------------
     /** Open a new file with a given path. */
-    IOStream* Open( const char* pFile, const char* /*pMode*/ = "rb") {
-        if (strncmp(pFile,AI_MEMORYIO_MAGIC_FILENAME,AI_MEMORYIO_MAGIC_FILENAME_LENGTH)) {
-            return NULL;
+    IOStream* Open(const char* pFile, const char* pMode = "rb") override {
+        if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
+            created_streams.emplace_back(new MemoryIOStream(buffer, length));
+            return created_streams.back();
         }
-        return new MemoryIOStream(buffer,length);
+        return existing_io ? existing_io->Open(pFile, pMode) : NULL;
     }
 
     // -------------------------------------------------------------------
     /** Closes the given file and releases all resources associated with it. */
-    void Close( IOStream* pFile) {
-    	delete pFile;
+    void Close( IOStream* pFile) override {
+        auto it = std::find(created_streams.begin(), created_streams.end(), pFile);
+        if (it != created_streams.end()) {
+            delete pFile;
+            created_streams.erase(it);
+        } else if (existing_io) {
+            existing_io->Close(pFile);
+        }
     }
 
     // -------------------------------------------------------------------
     /** Compare two paths */
-    bool ComparePaths (const char* /*one*/, const char* /*second*/) const {
-        return false;
+    bool ComparePaths(const char* one, const char* second) const override {
+        return existing_io ? existing_io->ComparePaths(one, second) : false;
+    }
+
+    bool PushDirectory( const std::string &path ) override { 
+        return existing_io ? existing_io->PushDirectory(path) : false;
+    }
+
+    const std::string &CurrentDirectory() const override {
+        static std::string empty;
+        return existing_io ? existing_io->CurrentDirectory() : empty;
+    }
+
+    size_t StackSize() const override {
+        return existing_io ? existing_io->StackSize() : 0;
+    }
+
+    bool PopDirectory() override {
+        return existing_io ? existing_io->PopDirectory() : false;
+    }
+
+    bool CreateDirectory( const std::string &path ) override {
+        return existing_io ? existing_io->CreateDirectory(path) : false;
+    }
+
+    bool ChangeDirectory( const std::string &path ) override {
+        return existing_io ? existing_io->ChangeDirectory(path) : false;
+    }
+
+    bool DeleteFile( const std::string &file ) override {
+        return existing_io ? existing_io->DeleteFile(file) : false;
     }
 
 private:
     const uint8_t* buffer;
     size_t length;
+    IOSystem* existing_io;
+    std::vector<IOStream*> created_streams;
 };
+
 } // end namespace Assimp
 
 #endif