Browse Source

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.
pull/187/head^2
Vladimír Vondruš 10 years ago
parent
commit
9590f72388
  1. 81
      src/MagnumPlugins/ObjImporter/ObjImporter.cpp

81
src/MagnumPlugins/ObjImporter/ObjImporter.cpp

@ -38,10 +38,6 @@
#include "Magnum/Math/Vector3.h" #include "Magnum/Math/Vector3.h"
#include "Magnum/Trade/MeshData3D.h" #include "Magnum/Trade/MeshData3D.h"
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(CORRADE_TARGET_ANDROID)
#include <sstream>
#endif
namespace Magnum { namespace Trade { namespace Magnum { namespace Trade {
struct ObjImporter::File { struct ObjImporter::File {
@ -66,16 +62,16 @@ template<std::size_t size> Math::Vector<size, Float> extractFloatData(std::strin
Math::Vector<size, Float> output; Math::Vector<size, Float> output;
#if defined(CORRADE_TARGET_NACL_NEWLIB) || defined(CORRADE_TARGET_ANDROID)
std::istringstream in;
#endif
for(std::size_t i = 0; i != size; ++i) { 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]); output[i] = std::stof(data[i]);
#else #else
in.str(data[i]); /* CRAPPY ANDROID GODDAMIT! It's also not exposed in std:: namespace,
in >> output[i]; 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 #endif
} }
@ -84,11 +80,15 @@ template<std::size_t size> Math::Vector<size, Float> extractFloatData(std::strin
Clang Analyzer happy */ Clang Analyzer happy */
CORRADE_INTERNAL_ASSERT(extra); CORRADE_INTERNAL_ASSERT(extra);
#if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) #ifndef CORRADE_TARGET_ANDROID
*extra = std::stof(data.back()); *extra = std::stof(data.back());
#else #else
in.str(data.back()); /* CRAPPY ANDROID GODDAMIT! It's also not exposed in std:: namespace,
in >> *extra; 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 #endif
} }
@ -370,35 +370,50 @@ std::optional<MeshData3D> ObjImporter::doMesh3D(UnsignedInt id) {
return std::nullopt; return std::nullopt;
} }
#ifdef CORRADE_TARGET_ANDROID
char* end{};
#endif
/* Position indices */ /* Position indices */
#if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) positionIndices.push_back(
positionIndices.push_back(std::stoul(indices[0]) - positionIndexOffset); #ifndef CORRADE_TARGET_ANDROID
#else std::stoul(indices[0])
std::istringstream in(indices[0]); #else
UnsignedInt index; std::strtoul(indices[0].data(), &end, 10)
in >> index; #endif
positionIndices.push_back(index - positionIndexOffset); - positionIndexOffset);
#ifdef CORRADE_TARGET_ANDROID
if(end == indices[0].data()) throw std::exception{};
#endif #endif
/* Texture coordinates */ /* Texture coordinates */
if(indices.size() == 2 || (indices.size() == 3 && !indices[1].empty())) { if(indices.size() == 2 || (indices.size() == 3 && !indices[1].empty())) {
#if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) textureCoordinateIndices.push_back(
textureCoordinateIndices.push_back(std::stoul(indices[1]) - textureCoordinateIndexOffset); #ifndef CORRADE_TARGET_ANDROID
#else std::stoul(indices[1])
in.str(indices[1]); #else
in >> index; std::strtoul(indices[1].data(), &end, 10)
textureCoordinateIndices.push_back(index - textureCoordinateIndexOffset); #endif
- textureCoordinateIndexOffset);
#ifdef CORRADE_TARGET_ANDROID
if(end == indices[1].data()) throw std::exception{};
#endif #endif
} }
/* Normal indices */ /* Normal indices */
if(indices.size() == 3) { if(indices.size() == 3) {
#if !defined(CORRADE_TARGET_NACL_NEWLIB) && !defined(CORRADE_TARGET_ANDROID) normalIndices.push_back(
normalIndices.push_back(std::stoul(indices[2]) - normalIndexOffset); #ifndef CORRADE_TARGET_ANDROID
#else std::stoul(indices[2])
in.str(indices[2]); #else
in >> index; std::strtoul(indices[2].data(), &end, 10)
normalIndices.push_back(index - normalIndexOffset); #endif
- normalIndexOffset);
#ifdef CORRADE_TARGET_ANDROID
if(end == indices[2].data()) throw std::exception{};
#endif #endif
} }
} }

Loading…
Cancel
Save