From 9590f723883b319d4a2ce2d9f4dd695d5ba22be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 16 Oct 2016 00:56:59 +0200 Subject: [PATCH] ObjImporter: properly implement string-to-number on Android. The string stream solution that was used in case of NaCl and Android wasn't working at all, thus I discarded it in favor of less overhead-y C functions. While strtoul() and others *are* defined in the std:: namespace, strtof() isn't. What a pile of crap. I also had to emulate C++ exception behavior in order to match the std::stoul() and std::stof() behavior. This plugin needs a zero-copy rewrite anyway, but at least the test is green now on all platforms. I discarded the NaCl version because currently there's no toolchain for it and I'm not going to guess whether stof() and friends are even there. If they are, then it's just a matter of enabling the Android code path also for NaCl. --- src/MagnumPlugins/ObjImporter/ObjImporter.cpp | 81 +++++++++++-------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/src/MagnumPlugins/ObjImporter/ObjImporter.cpp b/src/MagnumPlugins/ObjImporter/ObjImporter.cpp index 7ccee5ed4..d2059cb16 100644 --- a/src/MagnumPlugins/ObjImporter/ObjImporter.cpp +++ b/src/MagnumPlugins/ObjImporter/ObjImporter.cpp @@ -38,10 +38,6 @@ #include "Magnum/Math/Vector3.h" #include "Magnum/Trade/MeshData3D.h" -#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(CORRADE_TARGET_ANDROID) -#include -#endif - namespace Magnum { namespace Trade { struct ObjImporter::File { @@ -66,16 +62,16 @@ template Math::Vector extractFloatData(std::strin Math::Vector output; - #if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(CORRADE_TARGET_ANDROID) - std::istringstream in; - #endif - for(std::size_t i = 0; i != size; ++i) { - #if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) + #ifndef CORRADE_TARGET_ANDROID output[i] = std::stof(data[i]); #else - in.str(data[i]); - in >> output[i]; + /* CRAPPY ANDROID GODDAMIT! It's also not exposed in std:: namespace, + unlike std::strtoul() and others. WTF! */ + char* end{}; + output[i] = strtof(data[i].data(), &end); + if(end == data[i].data() || output[i] == HUGE_VALF) + throw std::exception{}; #endif } @@ -84,11 +80,15 @@ template Math::Vector extractFloatData(std::strin Clang Analyzer happy */ CORRADE_INTERNAL_ASSERT(extra); - #if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) + #ifndef CORRADE_TARGET_ANDROID *extra = std::stof(data.back()); #else - in.str(data.back()); - in >> *extra; + /* CRAPPY ANDROID GODDAMIT! It's also not exposed in std:: namespace, + unlike std::strtoul() and others. WTF! */ + char* end{}; + *extra = strtof(data.back().data(), &end); + if(end == data.back().data() || *extra == HUGE_VALF) + throw std::exception{}; #endif } @@ -370,35 +370,50 @@ std::optional ObjImporter::doMesh3D(UnsignedInt id) { return std::nullopt; } + #ifdef CORRADE_TARGET_ANDROID + char* end{}; + #endif + /* Position indices */ - #if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) - positionIndices.push_back(std::stoul(indices[0]) - positionIndexOffset); - #else - std::istringstream in(indices[0]); - UnsignedInt index; - in >> index; - positionIndices.push_back(index - positionIndexOffset); + positionIndices.push_back( + #ifndef CORRADE_TARGET_ANDROID + std::stoul(indices[0]) + #else + std::strtoul(indices[0].data(), &end, 10) + #endif + - positionIndexOffset); + + #ifdef CORRADE_TARGET_ANDROID + if(end == indices[0].data()) throw std::exception{}; #endif /* Texture coordinates */ if(indices.size() == 2 || (indices.size() == 3 && !indices[1].empty())) { - #if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) - textureCoordinateIndices.push_back(std::stoul(indices[1]) - textureCoordinateIndexOffset); - #else - in.str(indices[1]); - in >> index; - textureCoordinateIndices.push_back(index - textureCoordinateIndexOffset); + textureCoordinateIndices.push_back( + #ifndef CORRADE_TARGET_ANDROID + std::stoul(indices[1]) + #else + std::strtoul(indices[1].data(), &end, 10) + #endif + - textureCoordinateIndexOffset); + + #ifdef CORRADE_TARGET_ANDROID + if(end == indices[1].data()) throw std::exception{}; #endif } /* Normal indices */ if(indices.size() == 3) { - #if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) - normalIndices.push_back(std::stoul(indices[2]) - normalIndexOffset); - #else - in.str(indices[2]); - in >> index; - normalIndices.push_back(index - normalIndexOffset); + normalIndices.push_back( + #ifndef CORRADE_TARGET_ANDROID + std::stoul(indices[2]) + #else + std::strtoul(indices[2].data(), &end, 10) + #endif + - normalIndexOffset); + + #ifdef CORRADE_TARGET_ANDROID + if(end == indices[2].data()) throw std::exception{}; #endif } }