|
@@ -51,26 +51,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
namespace Assimp {
|
|
namespace Assimp {
|
|
|
|
+
|
|
#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
|
|
#define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
|
|
#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
|
|
#define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
|
|
|
|
|
|
// ----------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------
|
|
/** Implementation of IOStream to read directly from a memory buffer */
|
|
/** Implementation of IOStream to read directly from a memory buffer */
|
|
// ----------------------------------------------------------------------------------
|
|
// ----------------------------------------------------------------------------------
|
|
-class MemoryIOStream : public IOStream
|
|
|
|
-{
|
|
|
|
- //friend class MemoryIOSystem;
|
|
|
|
|
|
+class MemoryIOStream : public IOStream {
|
|
public:
|
|
public:
|
|
MemoryIOStream (const uint8_t* buff, size_t len, bool own = false)
|
|
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 () {
|
|
~MemoryIOStream () {
|
|
if(own) {
|
|
if(own) {
|
|
delete[] buffer;
|
|
delete[] buffer;
|
|
@@ -80,11 +77,13 @@ public:
|
|
// -------------------------------------------------------------------
|
|
// -------------------------------------------------------------------
|
|
// Read from stream
|
|
// Read from stream
|
|
size_t Read(void* pvBuffer, size_t pSize, size_t pCount) {
|
|
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;
|
|
pos += ofs;
|
|
|
|
|
|
return cnt;
|
|
return cnt;
|
|
@@ -105,14 +104,12 @@ public:
|
|
return AI_FAILURE;
|
|
return AI_FAILURE;
|
|
}
|
|
}
|
|
pos = pOffset;
|
|
pos = pOffset;
|
|
- }
|
|
|
|
- else if (aiOrigin_END == pOrigin) {
|
|
|
|
|
|
+ } else if (aiOrigin_END == pOrigin) {
|
|
if (pOffset > length) {
|
|
if (pOffset > length) {
|
|
return AI_FAILURE;
|
|
return AI_FAILURE;
|
|
}
|
|
}
|
|
pos = length-pOffset;
|
|
pos = length-pOffset;
|
|
- }
|
|
|
|
- else {
|
|
|
|
|
|
+ } else {
|
|
if (pOffset+pos > length) {
|
|
if (pOffset+pos > length) {
|
|
return AI_FAILURE;
|
|
return AI_FAILURE;
|
|
}
|
|
}
|
|
@@ -147,12 +144,15 @@ private:
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// ---------------------------------------------------------------------------
|
|
/** Dummy IO system to read from a memory buffer */
|
|
/** Dummy IO system to read from a memory buffer */
|
|
-class MemoryIOSystem : public IOSystem
|
|
|
|
-{
|
|
|
|
|
|
+class MemoryIOSystem : public IOSystem {
|
|
public:
|
|
public:
|
|
/** Constructor. */
|
|
/** 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. */
|
|
/** Destructor. */
|
|
@@ -161,41 +161,84 @@ public:
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
// -------------------------------------------------------------------
|
|
/** Tests for the existence of a file at the given path. */
|
|
/** 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. */
|
|
/** 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. */
|
|
/** 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. */
|
|
/** 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 */
|
|
/** 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:
|
|
private:
|
|
const uint8_t* buffer;
|
|
const uint8_t* buffer;
|
|
size_t length;
|
|
size_t length;
|
|
|
|
+ IOSystem* existing_io;
|
|
|
|
+ std::vector<IOStream*> created_streams;
|
|
};
|
|
};
|
|
|
|
+
|
|
} // end namespace Assimp
|
|
} // end namespace Assimp
|
|
|
|
|
|
#endif
|
|
#endif
|