// Copyright (C) 2020 Jérôme Leclercq // This file is part of the "Nazara Engine - Assimp Plugin" // For conditions of distribution and use, see copyright notice in Plugin.cpp #include #include #include #include #include #include #include #include #include using namespace Nz; void StreamFlush(aiFile* file) { Stream* stream = reinterpret_cast(file->UserData); stream->Flush(); } size_t StreamRead(aiFile* file, char* buffer, size_t size, size_t count) { Stream* stream = reinterpret_cast(file->UserData); return stream->Read(buffer, size * count) / size; } aiReturn StreamSeek(aiFile* file, size_t offset, aiOrigin origin) { Stream* stream = reinterpret_cast(file->UserData); switch (origin) { case aiOrigin_CUR: return (stream->SetCursorPos(stream->GetCursorPos() + offset)) ? aiReturn_SUCCESS : aiReturn_FAILURE; case aiOrigin_END: return (stream->SetCursorPos(stream->GetSize() - offset)) ? aiReturn_SUCCESS : aiReturn_FAILURE; case aiOrigin_SET: return (stream->SetCursorPos(offset)) ? aiReturn_SUCCESS : aiReturn_FAILURE; case _AI_ORIGIN_ENFORCE_ENUM_SIZE: // To prevent a warning break; } NazaraWarning("Unhandled aiOrigin enum (value: 0x" + std::string(origin, 16) + ')'); return aiReturn_FAILURE; } size_t StreamSize(aiFile* file) { Stream* stream = reinterpret_cast(file->UserData); return static_cast(stream->GetSize()); } size_t StreamTell(aiFile* file) { Stream* stream = reinterpret_cast(file->UserData); return static_cast(stream->GetCursorPos()); } size_t StreamWrite(aiFile* file, const char* buffer, size_t size, size_t count) { Stream* stream = reinterpret_cast(file->UserData); return stream->Write(buffer, size * count); } aiFile* StreamOpener(aiFileIO* fileIO, const char* filePath, const char* openMode) { FileIOUserdata* fileIOUserdata = reinterpret_cast(fileIO->UserData); bool isOriginalStream = (std::strcmp(filePath, fileIOUserdata->originalFilePath) == 0); if (!isOriginalStream && strstr(filePath, StreamPath) != nullptr) return nullptr; aiUserData stream; if (isOriginalStream) { stream = reinterpret_cast(fileIOUserdata->originalStream); fileIOUserdata->originalStream->SetCursorPos(0); } else { ErrorFlags errFlags({}, ErrorMode::ThrowException); Result openModes = File::DecodeOpenMode(openMode); if (openModes.IsErr()) { NazaraErrorFmt("{0} for file {1}", openModes.GetError(), filePath); return nullptr; } std::unique_ptr file = std::make_unique(); if (!file->Open(filePath, openModes.GetValue())) return nullptr; stream = reinterpret_cast(file.release()); } std::unique_ptr file = std::make_unique(); file->FileSizeProc = StreamSize; file->FlushProc = StreamFlush; file->ReadProc = StreamRead; file->SeekProc = StreamSeek; file->TellProc = StreamTell; file->WriteProc = StreamWrite; file->UserData = stream; return file.release(); } void StreamCloser(aiFileIO* fileIO, aiFile* file) { FileIOUserdata* fileIOUserdata = reinterpret_cast(fileIO->UserData); Stream* fileUserdata = reinterpret_cast(file->UserData); if (fileUserdata != fileIOUserdata->originalStream) delete reinterpret_cast(file->UserData); delete file; }