Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 09:30:09

0001 /*
0002 Open Asset Import Library (assimp)
0003 ----------------------------------------------------------------------
0004 
0005 Copyright (c) 2006-2024, assimp team
0006 
0007 All rights reserved.
0008 
0009 Redistribution and use of this software in source and binary forms,
0010 with or without modification, are permitted provided that the
0011 following conditions are met:
0012 
0013 * Redistributions of source code must retain the above
0014   copyright notice, this list of conditions and the
0015   following disclaimer.
0016 
0017 * Redistributions in binary form must reproduce the above
0018   copyright notice, this list of conditions and the
0019   following disclaimer in the documentation and/or other
0020   materials provided with the distribution.
0021 
0022 * Neither the name of the assimp team, nor the names of its
0023   contributors may be used to endorse or promote products
0024   derived from this software without specific prior
0025   written permission of the assimp team.
0026 
0027 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0028 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0029 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0030 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0031 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0032 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0033 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0034 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0035 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0036 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0037 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0038 
0039 ----------------------------------------------------------------------
0040 */
0041 
0042 /** @file MemoryIOWrapper.h
0043  *  Handy IOStream/IOSystem implementation to read directly from a memory buffer */
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 /** Implementation of IOStream to read directly from a memory buffer */
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         // empty
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); // won't be needed
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); // won't be needed
0130     }
0131 
0132 private:
0133     const uint8_t* buffer;
0134     size_t length,pos;
0135     bool own;
0136 };
0137 
0138 // ---------------------------------------------------------------------------
0139 /// @brief Dummy IO system to read from a memory buffer.
0140 class MemoryIOSystem : public IOSystem {
0141 public:
0142     /// @brief Constructor.
0143     MemoryIOSystem(const uint8_t* buff, size_t len, IOSystem* io) : buffer(buff), length(len), existing_io(io) {
0144         // empty
0145     }
0146 
0147     /// @brief Destructor.
0148     ~MemoryIOSystem() override = default;
0149 
0150     // -------------------------------------------------------------------
0151     /// @brief Tests for the existence of a file at the given path.
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     /// @brief Returns the directory separator.
0161     char getOsSeparator() const override {
0162         return existing_io ? existing_io->getOsSeparator()
0163                            : '/';  // why not? it doesn't care
0164     }
0165 
0166     // -------------------------------------------------------------------
0167     /// @brief Open a new file with a given path.
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     /// @brief Closes the given file and releases all resources associated with it.
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     /// @brief Compare two paths
0190     bool ComparePaths(const char* one, const char* second) const override {
0191         return existing_io ? existing_io->ComparePaths(one, second) : false;
0192     }
0193 
0194     /// @brief Will push the directory.
0195     bool PushDirectory( const std::string &path ) override {
0196         return existing_io ? existing_io->PushDirectory(path) : false;
0197     }
0198 
0199     /// @brief Will return the current directory from the stack top.
0200     const std::string &CurrentDirectory() const override {
0201         static std::string empty;
0202         return existing_io ? existing_io->CurrentDirectory() : empty;
0203     }
0204 
0205     /// @brief Returns the stack size.
0206     size_t StackSize() const override {
0207         return existing_io ? existing_io->StackSize() : 0;
0208     }
0209 
0210     /// @brief Will pop the upper directory.
0211     bool PopDirectory() override {
0212         return existing_io ? existing_io->PopDirectory() : false;
0213     }
0214 
0215     /// @brief Will create the directory.
0216     bool CreateDirectory( const std::string &path ) override {
0217         return existing_io ? existing_io->CreateDirectory(path) : false;
0218     }
0219 
0220     /// @brief Will change the directory.
0221     bool ChangeDirectory( const std::string &path ) override {
0222         return existing_io ? existing_io->ChangeDirectory(path) : false;
0223     }
0224 
0225     /// @brief Will delete the file.
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 } // end namespace Assimp
0238 
0239 #endif // AI_MEMORYIOSTREAM_H_INC