File indexing completed on 2025-02-21 09:30:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #pragma once
0045 #ifndef AI_MEMORYIOSTREAM_H_INC
0046 #define AI_MEMORYIOSTREAM_H_INC
0047
0048 #ifdef __GNUC__
0049 # pragma GCC system_header
0050 #endif
0051
0052 #include <assimp/IOStream.hpp>
0053 #include <assimp/IOSystem.hpp>
0054 #include <assimp/ai_assert.h>
0055
0056 #include <stdint.h>
0057
0058 namespace Assimp {
0059
0060 #define AI_MEMORYIO_MAGIC_FILENAME "$$$___magic___$$$"
0061 #define AI_MEMORYIO_MAGIC_FILENAME_LENGTH 17
0062
0063
0064
0065
0066 class MemoryIOStream : public IOStream {
0067 public:
0068 MemoryIOStream (const uint8_t* buff, size_t len, bool own = false) :
0069 buffer (buff),
0070 length(len),
0071 pos(static_cast<size_t>(0)),
0072 own(own) {
0073
0074 }
0075
0076 ~MemoryIOStream() override {
0077 if(own) {
0078 delete[] buffer;
0079 }
0080 }
0081
0082 size_t Read(void* pvBuffer, size_t pSize, size_t pCount) override {
0083 ai_assert(nullptr != pvBuffer);
0084 ai_assert(0 != pSize);
0085
0086 const size_t cnt = std::min( pCount, (length-pos) / pSize);
0087 const size_t ofs = pSize * cnt;
0088
0089 ::memcpy(pvBuffer,buffer+pos,ofs);
0090 pos += ofs;
0091
0092 return cnt;
0093 }
0094
0095 size_t Write(const void*, size_t, size_t ) override {
0096 ai_assert(false);
0097 return 0;
0098 }
0099
0100 aiReturn Seek(size_t pOffset, aiOrigin pOrigin) override {
0101 if (aiOrigin_SET == pOrigin) {
0102 if (pOffset > length) {
0103 return AI_FAILURE;
0104 }
0105 pos = pOffset;
0106 } else if (aiOrigin_END == pOrigin) {
0107 if (pOffset > length) {
0108 return AI_FAILURE;
0109 }
0110 pos = length-pOffset;
0111 } else {
0112 if (pOffset+pos > length) {
0113 return AI_FAILURE;
0114 }
0115 pos += pOffset;
0116 }
0117 return AI_SUCCESS;
0118 }
0119
0120 size_t Tell() const override {
0121 return pos;
0122 }
0123
0124 size_t FileSize() const override {
0125 return length;
0126 }
0127
0128 void Flush() override{
0129 ai_assert(false);
0130 }
0131
0132 private:
0133 const uint8_t* buffer;
0134 size_t length,pos;
0135 bool own;
0136 };
0137
0138
0139
0140 class MemoryIOSystem : public IOSystem {
0141 public:
0142
0143 MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io) : buffer(buff), length(len), existing_io(io) {
0144
0145 }
0146
0147
0148 ~MemoryIOSystem() override = default;
0149
0150
0151
0152 bool Exists(const char* pFile) const override {
0153 if (0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
0154 return true;
0155 }
0156 return existing_io ? existing_io->Exists(pFile) : false;
0157 }
0158
0159
0160
0161 char getOsSeparator() const override {
0162 return existing_io ? existing_io->getOsSeparator()
0163 : '/';
0164 }
0165
0166
0167
0168 IOStream* Open(const char* pFile, const char* pMode = "rb") override {
0169 if ( 0 == strncmp( pFile, AI_MEMORYIO_MAGIC_FILENAME, AI_MEMORYIO_MAGIC_FILENAME_LENGTH ) ) {
0170 created_streams.emplace_back(new MemoryIOStream(buffer, length));
0171 return created_streams.back();
0172 }
0173 return existing_io ? existing_io->Open(pFile, pMode) : nullptr;
0174 }
0175
0176
0177
0178 void Close( IOStream* pFile) override {
0179 auto it = std::find(created_streams.begin(), created_streams.end(), pFile);
0180 if (it != created_streams.end()) {
0181 delete pFile;
0182 created_streams.erase(it);
0183 } else if (existing_io) {
0184 existing_io->Close(pFile);
0185 }
0186 }
0187
0188
0189
0190 bool ComparePaths(const char* one, const char* second) const override {
0191 return existing_io ? existing_io->ComparePaths(one, second) : false;
0192 }
0193
0194
0195 bool PushDirectory( const std::string &path ) override {
0196 return existing_io ? existing_io->PushDirectory(path) : false;
0197 }
0198
0199
0200 const std::string &CurrentDirectory() const override {
0201 static std::string empty;
0202 return existing_io ? existing_io->CurrentDirectory() : empty;
0203 }
0204
0205
0206 size_t StackSize() const override {
0207 return existing_io ? existing_io->StackSize() : 0;
0208 }
0209
0210
0211 bool PopDirectory() override {
0212 return existing_io ? existing_io->PopDirectory() : false;
0213 }
0214
0215
0216 bool CreateDirectory( const std::string &path ) override {
0217 return existing_io ? existing_io->CreateDirectory(path) : false;
0218 }
0219
0220
0221 bool ChangeDirectory( const std::string &path ) override {
0222 return existing_io ? existing_io->ChangeDirectory(path) : false;
0223 }
0224
0225
0226 bool DeleteFile( const std::string &file ) override {
0227 return existing_io ? existing_io->DeleteFile(file) : false;
0228 }
0229
0230 private:
0231 const uint8_t* buffer;
0232 size_t length;
0233 IOSystem* existing_io;
0234 std::vector<IOStream*> created_streams;
0235 };
0236
0237 }
0238
0239 #endif