Compare commits

..

10 Commits

Author SHA1 Message Date
Kim Kulling
e73a537081 Merge branch 'master' into feature/rust_bindings 2026-04-06 16:20:25 +02:00
Kim Kulling
48515a4aa1 Merge branch 'master' into feature/rust_bindings 2026-02-26 15:33:51 +01:00
Kim Kulling
1ed019b869 Remove generated file 2026-02-26 15:29:58 +01:00
Kim Kulling
7c7a1233f5 Fix formatting in Cargo.toml 2026-02-26 15:28:14 +01:00
Kim Kulling
3e6482bca0 Update build.rs 2026-02-23 21:28:49 +01:00
Kim Kulling
c0d273cb3b Apply suggestion from @coderabbitai[bot]
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-02-23 21:28:00 +01:00
Kim Kulling
e730b7803c Add missing includes for the rust bindings. 2026-02-23 16:20:04 +01:00
Kim Kulling
cedc5a8d10 Merge branch 'master' into feature/rust_bindings 2026-02-04 11:38:57 +01:00
Kim Kulling
4d3a694807 Fix bindgen usage. 2026-02-03 21:06:25 +01:00
Kim Kulling
517fb1b242 Add files for assimp rust wrapper 2026-01-27 21:33:02 +01:00
17 changed files with 109 additions and 193 deletions

View File

@@ -182,7 +182,7 @@ jobs:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: softprops/action-gh-release@v3
- uses: softprops/action-gh-release@v2
with:
name: create-release
- id: upload-url
@@ -197,4 +197,4 @@ jobs:
with:
files: |
*.zip

View File

@@ -45,7 +45,7 @@ jobs:
filename: ${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
directory: build/bin/
- uses: softprops/action-gh-release@v3
- uses: softprops/action-gh-release@v2
with:
files: build/bin/${{ matrix.name }}-${{ github.event.release.tag_name }}.zip
append_body: true

View File

@@ -149,18 +149,11 @@ aiQuaternion Read<aiQuaternion>(IOStream *stream) {
template <>
aiString Read<aiString>(IOStream *stream) {
aiString s;
uint32_t len;
if (stream->Read(&len, 4, 1) != 1) {
throw DeadlyImportError("ASSBIN: Unexpected EOF reading string length");
stream->Read(&s.length, 4, 1);
if (s.length) {
stream->Read(s.data, s.length, 1);
}
if (len >= AI_MAXLEN) {
throw DeadlyImportError("ASSBIN: String length too large, potential buffer overflow attempt");
}
s.length = len;
if ((s.length > 0) && (stream->Read(s.data, s.length, 1) != 1)) {
throw DeadlyImportError("ASSBIN: Unexpected EOF reading string data");
}
s.data[s.length] = '\0';
s.data[s.length] = 0;
return s;
}

View File

@@ -507,20 +507,16 @@ void ColladaLoader::BuildMeshesForNode(const ColladaParser &pParser, const Node
}
if (table && !table->mMap.empty()) {
if (matIdx < newMats.size()) {
std::pair<Collada::Effect *, aiMaterial *> &mat = newMats[matIdx];
std::pair<Collada::Effect *, aiMaterial *> &mat = newMats[matIdx];
// Iterate through all texture channels assigned to the effect and
// check whether we have mapping information for it.
ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table);
} else {
ASSIMP_LOG_WARN("Collada: Ignoring material mapping for mesh \"", mid.mMeshOrController, "\". Material index ", matIdx, " is out of bounds (newMats.size()=", newMats.size(), ").");
}
// Iterate through all texture channels assigned to the effect and
// check whether we have mapping information for it.
ApplyVertexToEffectSemanticMapping(mat.first->mTexDiffuse, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexAmbient, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexSpecular, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexEmissive, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexTransparent, *table);
ApplyVertexToEffectSemanticMapping(mat.first->mTexBump, *table);
}
// built lookup index of the Mesh-Submesh-Material combination

View File

@@ -45,8 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include <algorithm>
#include "FBXParser.h"
#include "FBXDocument.h"
#include "FBXMeshGeometry.h"
@@ -146,10 +144,8 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
for (const Connection* con : conns) {
const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
if (bspc) {
// Only add a channel if it doesn't exist already
if (std::find(blendShapeChannels.begin(), blendShapeChannels.end(), bspc) == blendShapeChannels.end()) {
blendShapeChannels.push_back(bspc);
} else {
auto pr = blendShapeChannels.insert(bspc);
if (!pr.second) {
FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
}
}
@@ -174,10 +170,8 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
for (const Connection* con : conns) {
const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
if (sg) {
// Only add a geometry if it doesn't exist already
if (std::find(shapeGeometries.begin(), shapeGeometries.end(), sg) == shapeGeometries.end()) {
shapeGeometries.push_back(sg);
} else {
auto pr = shapeGeometries.insert(sg);
if (!pr.second) {
FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
}
}

View File

@@ -865,14 +865,14 @@ public:
return fullWeights;
}
const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
return shapeGeometries;
}
private:
float percent;
WeightArray fullWeights;
std::vector<const ShapeGeometry*> shapeGeometries;
std::unordered_set<const ShapeGeometry*> shapeGeometries;
};
/** DOM class for BlendShape deformers */
@@ -882,12 +882,12 @@ public:
virtual ~BlendShape() = default;
const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
return blendShapeChannels;
}
private:
std::vector<const BlendShapeChannel*> blendShapeChannels;
std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
};
/** DOM class for skin deformer clusters (aka sub-deformers) */

View File

@@ -90,7 +90,7 @@ namespace {
// Returns whether the class can handle the format of the given file.
bool FBXImporter::CanRead(const std::string & pFile, IOSystem * pIOHandler, bool /*checkSig*/) const {
// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
static const char *tokens[] = { " \n\r\n ", "fbx" };
static const char *tokens[] = { " \n\r\n " };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
}

View File

@@ -45,7 +45,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#include <algorithm>
#include <functional>
#include "FBXMeshGeometry.h"
@@ -70,10 +69,8 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
}
const BlendShape* const bsp = ProcessSimpleConnection<BlendShape>(*con, false, "BlendShape -> Geometry", element);
if (bsp) {
// Only add a blendshape if it doesn't exist already
if (std::find(blendShapes.begin(), blendShapes.end(), bsp) == blendShapes.end()) {
blendShapes.push_back(bsp);
} else {
auto pr = blendShapes.insert(bsp);
if (!pr.second) {
FBXImporter::LogWarn("there is the same blendShape id ", bsp->ID());
}
}
@@ -81,7 +78,7 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
}
// ------------------------------------------------------------------------------------------------
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
const std::unordered_set<const BlendShape*>& Geometry::GetBlendShapes() const {
return blendShapes;
}

View File

@@ -72,11 +72,11 @@ public:
/// @brief Get the BlendShape attached to this geometry or nullptr
/// @return The blendshape arrays.
const std::vector<const BlendShape*>& GetBlendShapes() const;
const std::unordered_set<const BlendShape*>& GetBlendShapes() const;
private:
const Skin* skin;
std::vector<const BlendShape*> blendShapes;
std::unordered_set<const BlendShape*> blendShapes;
};

View File

@@ -36,6 +36,7 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#if !defined ASSIMP_BUILD_NO_M3D_IMPORTER || !(defined ASSIMP_BUILD_NO_EXPORT || defined ASSIMP_BUILD_NO_M3D_EXPORTER)
@@ -102,68 +103,15 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
ai_assert(nullptr != pIOHandler);
}
// Security fix: Validate buffer size and content before processing
if (buffer.empty()) {
ASSIMP_LOG_ERROR("M3D: Empty buffer provided");
m3d_ = nullptr;
return;
}
// Check for minimum valid M3D file size (header + basic structure)
const size_t MIN_VALID_M3D_SIZE = 100; // Minimum reasonable size for a valid M3D file
if (buffer.size() < MIN_VALID_M3D_SIZE) {
ASSIMP_LOG_ERROR("M3D: Buffer too small to be a valid M3D file");
m3d_ = nullptr;
return;
}
// Validate M3D magic signature to ensure this is actually an M3D file
// M3D files should start with "3DMO" or "3dmo" magic signature
if (buffer.size() >= 4) {
bool valid_signature = false;
// Check for "3DMO" (uppercase)
if (buffer[0] == '3' && buffer[1] == 'D' && buffer[2] == 'M' && buffer[3] == 'O') {
valid_signature = true;
}
// Check for "3dmo" (lowercase)
else if (buffer[0] == '3' && buffer[1] == 'd' && buffer[2] == 'm' && buffer[3] == 'o') {
valid_signature = true;
}
if (!valid_signature) {
ASSIMP_LOG_ERROR("M3D: Invalid file signature - not a valid M3D file");
m3d_ = nullptr;
return;
}
}
// Create a safe copy of the buffer with guard pages/validation
// This helps prevent buffer overflows from affecting the main process
std::vector<unsigned char> safe_buffer = buffer;
// Add a guard page at the end to catch any overflow attempts
// Note: This is a defensive measure, not a complete fix for the underlying issue
safe_buffer.resize(safe_buffer.size() + 1);
safe_buffer.back() = 0xFF; // Guard byte
#ifdef ASSIMP_USE_M3D_READFILECB
// pass this IOHandler to the C callback in a thread-local pointer
m3dimporter_pIOHandler = pIOHandler;
m3d_ = m3d_load(const_cast<unsigned char *>(safe_buffer.data()), m3dimporter_readfile, free, nullptr);
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
// Clear the C callback
m3dimporter_pIOHandler = nullptr;
#else
m3d_ = m3d_load(const_cast<unsigned char *>(safe_buffer.data()), nullptr, nullptr, nullptr);
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
#endif
// Verify the guard byte wasn't overwritten (indicating potential buffer overflow)
if (safe_buffer.empty() || safe_buffer.back() != 0xFF) {
ASSIMP_LOG_ERROR("M3D: Potential buffer overflow detected during loading");
if (m3d_) {
m3d_free(m3d_);
m3d_ = nullptr;
}
}
}
M3DWrapper::~M3DWrapper() {
@@ -199,4 +147,4 @@ void M3DWrapper::ClearSave() {
}
} // namespace Assimp
#endif
#endif

View File

@@ -72,7 +72,7 @@ public:
/// Construct an M3D model from provided buffer
/// @note The m3d.h SDK function does not mark the data as const. Have assumed it does not write.
/// SECURITY: Buffer size validation and guard pages added to mitigate potential overflows
/// BUG: SECURITY: The m3d.h SDK cannot be informed of the buffer size. BUFFER OVERFLOW IS CERTAIN
explicit M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer);
/// Theclasss destructor.

View File

@@ -1038,27 +1038,21 @@ size_t Accessor::ExtractData(T *&outData, const std::vector<unsigned int> *remap
const size_t maxSize = GetMaxByteSize();
if (elemSize > maxSize) {
throw DeadlyImportError("GLTF: elemSize ", elemSize, " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
const size_t maxCount = (maxSize - elemSize) / stride + 1;
if (count > maxCount) {
throw DeadlyImportError("GLTF: count ", count, " > maxCount ", maxCount, " in ", getContextForErrorMessages(id, name));
}
outData = new T[usedCount];
if (remappingIndices != nullptr) {
const unsigned int maxIndexCount = static_cast<unsigned int>(maxSize / stride);
for (size_t i = 0; i < usedCount; ++i) {
size_t srcIdx = (*remappingIndices)[i];
if (srcIdx >= count) {
throw DeadlyImportError("GLTF: index ", srcIdx, " >= count ", count, " in ", getContextForErrorMessages(id, name));
if (srcIdx >= maxIndexCount) {
throw DeadlyImportError("GLTF: index*stride ", (srcIdx * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
memcpy(outData + i, data + srcIdx * stride, elemSize);
}
} else { // non-indexed cases
if (usedCount * stride > maxSize) {
throw DeadlyImportError("GLTF: count*stride ", (usedCount * stride), " > maxSize ", maxSize, " in ", getContextForErrorMessages(id, name));
}
if (stride == elemSize && targetElemSize == elemSize) {
memcpy(outData, data, totalSize);
} else {

View File

@@ -556,6 +556,12 @@ void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, unsigned int &prop, con
mat.Get(textureKey.c_str(), tt, slot, prop);
}
void glTF2Exporter::GetMatTexProp(const aiMaterial &mat, float &prop, const char *propName, aiTextureType tt, unsigned int slot) {
std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
mat.Get(textureKey.c_str(), tt, slot, prop);
}
void glTF2Exporter::GetMatTex(const aiMaterial &mat, Ref<Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0) {
if (mat.GetTextureCount(tt) == 0) {
return;
@@ -646,7 +652,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, NormalTextureInfo &prop, ai
if (texture) {
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
mat.Get(AI_MATKEY_GLTF_TEXTURE_SCALE(tt, slot), prop.scale);
GetMatTexProp(mat, prop.scale, "scale", tt, slot);
}
}
@@ -657,7 +663,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial &mat, OcclusionTextureInfo &prop,
if (texture) {
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
mat.Get(AI_MATKEY_GLTF_TEXTURE_STRENGTH(tt, slot), prop.strength);
GetMatTexProp(mat, prop.strength, "strength", tt, slot);
}
}

View File

@@ -110,6 +110,7 @@ protected:
void WriteBinaryData(IOStream *outfile, std::size_t sceneLength);
void GetTexSampler(const aiMaterial &mat, glTFCommon::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
void GetMatTexProp(const aiMaterial &mat, unsigned int &prop, const char *propName, aiTextureType tt, unsigned int idx);
void GetMatTexProp(const aiMaterial &mat, float &prop, const char *propName, aiTextureType tt, unsigned int idx);
void GetMatTex(const aiMaterial &mat, glTFCommon::Ref<glTF2::Texture> &texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial &mat, glTF2::TextureInfo &prop, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial &mat, glTF2::NormalTextureInfo &prop, aiTextureType tt, unsigned int slot);

View File

@@ -237,7 +237,8 @@ static void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
SetMaterialTextureProperty(embeddedTexIdxs, r, static_cast<TextureInfo>(prop), mat, texType, texSlot);
if (prop.texture && prop.texture->source) {
mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot));
std::string textureStrengthKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + "strength";
mat->AddProperty(&prop.strength, 1, textureStrengthKey.c_str(), texType, texSlot);
}
}

View File

@@ -58,55 +58,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stack>
namespace Assimp {
namespace {
ai_real calculateInputACMR(aiMesh *pMesh, const aiFace *const pcEnd,
unsigned int configCacheDepth, unsigned int meshNum) {
ai_real fACMR = 0.0f;
unsigned int *piFIFOStack = new unsigned int[configCacheDepth];
memset(piFIFOStack, 0xff, configCacheDepth * sizeof(unsigned int));
unsigned int *piCur = piFIFOStack;
const unsigned int *const piCurEnd = piFIFOStack + configCacheDepth;
// count the number of cache misses
unsigned int iCacheMisses = 0;
for (const aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
for (unsigned int qq = 0; qq < 3; ++qq) {
bool bInCache = false;
for (unsigned int *pp = piFIFOStack; pp < piCurEnd; ++pp) {
if (*pp == pcFace->mIndices[qq]) {
// the vertex is in cache
bInCache = true;
break;
}
}
if (!bInCache) {
++iCacheMisses;
if (piCurEnd == piCur) {
piCur = piFIFOStack;
}
*piCur++ = pcFace->mIndices[qq];
}
}
}
delete[] piFIFOStack;
fACMR = (ai_real)iCacheMisses / pMesh->mNumFaces;
if (3.0 == fACMR) {
char szBuff[128]; // should be sufficiently large in every case
// the JoinIdenticalVertices process has not been executed on this
// mesh, otherwise this value would normally be at least minimally
// smaller than 3.0 ...
ai_snprintf(szBuff, 128, "Mesh %u: Not suitable for vcache optimization", meshNum);
ASSIMP_LOG_WARN(szBuff);
return static_cast<ai_real>(0.f);
}
return fACMR;
}
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() : mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
ImproveCacheLocalityProcess::ImproveCacheLocalityProcess() :
mConfigCacheDepth(PP_ICL_PTCACHE_SIZE) {
// empty
}
@@ -151,6 +107,51 @@ void ImproveCacheLocalityProcess::Execute(aiScene *pScene) {
}
}
// ------------------------------------------------------------------------------------------------
static ai_real calculateInputACMR(aiMesh *pMesh, const aiFace *const pcEnd,
unsigned int configCacheDepth, unsigned int meshNum) {
ai_real fACMR = 0.0f;
unsigned int *piFIFOStack = new unsigned int[configCacheDepth];
memset(piFIFOStack, 0xff, configCacheDepth * sizeof(unsigned int));
unsigned int *piCur = piFIFOStack;
const unsigned int *const piCurEnd = piFIFOStack + configCacheDepth;
// count the number of cache misses
unsigned int iCacheMisses = 0;
for (const aiFace *pcFace = pMesh->mFaces; pcFace != pcEnd; ++pcFace) {
for (unsigned int qq = 0; qq < 3; ++qq) {
bool bInCache = false;
for (unsigned int *pp = piFIFOStack; pp < piCurEnd; ++pp) {
if (*pp == pcFace->mIndices[qq]) {
// the vertex is in cache
bInCache = true;
break;
}
}
if (!bInCache) {
++iCacheMisses;
if (piCurEnd == piCur) {
piCur = piFIFOStack;
}
*piCur++ = pcFace->mIndices[qq];
}
}
}
delete[] piFIFOStack;
fACMR = (ai_real)iCacheMisses / pMesh->mNumFaces;
if (3.0 == fACMR) {
char szBuff[128]; // should be sufficiently large in every case
// the JoinIdenticalVertices process has not been executed on this
// mesh, otherwise this value would normally be at least minimally
// smaller than 3.0 ...
ai_snprintf(szBuff, 128, "Mesh %u: Not suitable for vcache optimization", meshNum);
ASSIMP_LOG_WARN(szBuff);
return static_cast<ai_real>(0.f);
}
return fACMR;
}
// ------------------------------------------------------------------------------------------------
// Improves the cache coherency of a specific mesh
ai_real ImproveCacheLocalityProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshNum) {

View File

@@ -182,7 +182,7 @@ public:
// ---------------------------------------------------------------------
/// Get the remaining stream size (to the end of the stream)
size_t GetRemainingSize() const {
return static_cast<size_t>(mEnd - mCurrent);
return (unsigned int)(mEnd - mCurrent);
}
// ---------------------------------------------------------------------
@@ -190,29 +190,16 @@ public:
* return value is the remaining size of the stream if no custom
* read limit has been set. */
size_t GetRemainingSizeToLimit() const {
return static_cast<size_t>(mLimit - mCurrent);
return (unsigned int)(mLimit - mCurrent);
}
// ---------------------------------------------------------------------
/** Increase the file pointer (relative seeking) */
void IncPtr(intptr_t plus) {
// Ensure internal pointer invariants hold
if (mCurrent < mBuffer || mCurrent > mLimit) {
throw DeadlyImportError("StreamReader: Invalid internal pointer state");
}
if (plus < 0) {
const size_t absPlus = static_cast<size_t>(-(plus + 1)) + 1;
if (absPlus > static_cast<size_t>(mCurrent - mBuffer)) {
throw DeadlyImportError("StreamReader: Attempted to seek outside buffer bounds");
}
} else if (plus > 0) {
if (static_cast<size_t>(plus) > static_cast<size_t>(mLimit - mCurrent)) {
throw DeadlyImportError("StreamReader: Attempted to seek outside buffer bounds");
}
}
mCurrent += plus;
if (mCurrent > mLimit) {
throw DeadlyImportError("End of file or read limit was reached");
}
}
// ---------------------------------------------------------------------
@@ -246,9 +233,8 @@ public:
}
/// @brief Get the current offset from the beginning of the file
/// @return The current offset from the beginning of the file.
int GetCurrentPos() const {
return static_cast<int>(mCurrent - mBuffer);
return (unsigned int)(mCurrent - mBuffer);
}
void SetCurrentPos(size_t pos) {
@@ -258,10 +244,10 @@ public:
// ---------------------------------------------------------------------
/** Setup a temporary read limit
*
* @param _limit Maximum number of bytes to be read from
* @param limit Maximum number of bytes to be read from
* the beginning of the file. Specifying UINT_MAX
* resets the limit to the original end of the stream.
* @return The previously set limit. */
* Returns the previously set limit. */
unsigned int SetReadLimit(unsigned int _limit) {
unsigned int prev = GetReadLimit();
if (UINT_MAX == _limit) {
@@ -278,10 +264,9 @@ public:
// ---------------------------------------------------------------------
/** Get the current read limit in bytes. Reading over this limit
* accidentally raises an exception.
* @return The current limit. */
* accidentally raises an exception. */
unsigned int GetReadLimit() const {
return static_cast<unsigned int>(mLimit - mBuffer);
return (unsigned int)(mLimit - mBuffer);
}
// ---------------------------------------------------------------------