# HG changeset patch # User Sebastien Jodogne # Date 1574251830 -3600 # Node ID ba08f2b0a77936a4d3e1d5c64144020b0823e5ed # Parent 1644de437a7b16a9c962c9971ae88ac05c644a57# Parent 5594d8d4a70fa478ac0229dce825470593e5a67c integration mainline->broker diff -r 1644de437a7b -r ba08f2b0a779 Applications/Samples/CMakeLists.txt --- a/Applications/Samples/CMakeLists.txt Wed Nov 20 13:09:15 2019 +0100 +++ b/Applications/Samples/CMakeLists.txt Wed Nov 20 13:10:30 2019 +0100 @@ -88,6 +88,10 @@ set(ENABLE_GOOGLE_TEST ON) set(ENABLE_WEB_CLIENT ON) +else() + set(ENABLE_NATIVE ON) + set(ENABLE_OPENGL OFF) + endif() @@ -182,16 +186,19 @@ target_link_libraries(${Target} OrthancStone) endmacro() -#BuildSingleFileSample(OrthancStoneEmpty EmptyApplication.h 1) -#BuildSingleFileSample(OrthancStoneTestPattern TestPatternApplication.h 2) -BuildSingleFileSample(OrthancStoneSingleFrame SingleFrameApplication.h 3) -#BuildSingleFileSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4) -#BuildSingleFileSample(OrthancStoneBasicPetCtFusion 5) -#BuildSingleFileSample(OrthancStoneSynchronizedSeries 6) -#BuildSingleFileSample(OrthancStoneLayoutPetCtFusion 7) -BuildSingleFileSample(OrthancStoneSimpleViewerSingleFile SimpleViewerApplicationSingleFile.h 8) # we keep that one just as a sample before we convert another sample to this pattern -BuildSingleFileSample(OrthancStoneSingleFrameEditor SingleFrameEditorApplication.h 9) +if (ENABLE_SDL) + #BuildSingleFileSample(OrthancStoneEmpty EmptyApplication.h 1) + #BuildSingleFileSample(OrthancStoneTestPattern TestPatternApplication.h 2) + BuildSingleFileSample(OrthancStoneSingleFrame SingleFrameApplication.h 3) + #BuildSingleFileSample(OrthancStoneSingleVolume SingleVolumeApplication.h 4) + #BuildSingleFileSample(OrthancStoneBasicPetCtFusion 5) + #BuildSingleFileSample(OrthancStoneSynchronizedSeries 6) + #BuildSingleFileSample(OrthancStoneLayoutPetCtFusion 7) + BuildSingleFileSample(OrthancStoneSimpleViewerSingleFile SimpleViewerApplicationSingleFile.h 8) # we keep that one just as a sample before we convert another sample to this pattern + BuildSingleFileSample(OrthancStoneSingleFrameEditor SingleFrameEditorApplication.h 9) +endif() + ##### SimpleViewer sample (Qt and WASM only) ####### if (ENABLE_QT OR ENABLE_WASM) diff -r 1644de437a7b -r ba08f2b0a779 Framework/Toolbox/GenericToolbox.h --- a/Framework/Toolbox/GenericToolbox.h Wed Nov 20 13:09:15 2019 +0100 +++ b/Framework/Toolbox/GenericToolbox.h Wed Nov 20 13:10:30 2019 +0100 @@ -22,6 +22,8 @@ #include #include +#include + namespace OrthancStone { @@ -45,8 +47,25 @@ period++; ++p; } + else if (*p == 'e' || *p == 'E') + { + ++p; + if (*p == '-' || *p == '+') + ++p; + // "e+"/"E+" "e-"/"E-" or "e"/"E" must be followed by a number + if (!(*p >= '0' && *p <= '9')) + return false; + + // these must be the last in the string + while(*p >= '0' && *p <= '9') + ++p; + + return (*p == 0); + } else + { return false; + } } return true; } @@ -128,10 +147,62 @@ r += f; } r *= neg; - if (*p == 0 || (*p >= '0' && *p <= '9') ) + + // skip the remaining numbers until we reach not-a-digit (either the + // end of the string OR the scientific notation symbol) + while ((*p >= '0' && *p <= '9')) + ++p; + + if (*p == 0 ) + { return true; + } + else if ((*p == 'e') || (*p == 'E')) + { + // process the scientific notation + double sign; // no init is safe (read below) + ++p; + if (*p == '-') + { + sign = -1.0; + // point to first number + ++p; + } + else if (*p == '+') + { + sign = 1.0; + // point to first number + ++p; + } + else if (*p >= '0' && *p <= '9') + { + sign = 1.0; + } + else + { + // only a sign char or a number is allowed + return false; + } + // now p points to the absolute value of the exponent + double exp = 0; + while (*p >= '0' && *p <= '9') + { + exp = (exp * 10.0) + static_cast(*p - '0'); // 1 12 123 123 12345 + ++p; + } + // now we have our exponent. put a sign on it. + exp *= sign; + double scFac = ::pow(10.0, exp); + r *= scFac; + + // only allowed symbol here is EOS + return (*p == 0); + } else + { + // not allowed return false; + } } inline bool StringToDouble(double& r, const std::string& text) diff -r 1644de437a7b -r ba08f2b0a779 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Wed Nov 20 13:09:15 2019 +0100 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Wed Nov 20 13:10:30 2019 +0100 @@ -56,6 +56,12 @@ endif() endif() +if (ENABLE_OPENGL) + if (NOT ENABLE_QT AND NOT ENABLE_SDL AND NOT ENABLE_WASM) + message(FATAL_ERROR "Cannot enable OpenGL if WebAssembly, SDL and Qt are all disabled") + endif() +endif() + if (ENABLE_WASM) if (NOT ORTHANC_SANDBOXED) message(FATAL_ERROR "WebAssembly target must me configured as sandboxed") diff -r 1644de437a7b -r ba08f2b0a779 UnitTestsSources/GenericToolboxTests.cpp --- a/UnitTestsSources/GenericToolboxTests.cpp Wed Nov 20 13:09:15 2019 +0100 +++ b/UnitTestsSources/GenericToolboxTests.cpp Wed Nov 20 13:10:30 2019 +0100 @@ -24,6 +24,8 @@ #include "stdint.h" +#include + TEST(GenericToolbox, TestLegitDoubleString) { using OrthancStone::GenericToolbox::LegitDoubleString; @@ -47,14 +49,16 @@ EXPECT_TRUE(LegitDoubleString("0.")); EXPECT_TRUE(LegitDoubleString(".0")); + EXPECT_TRUE(LegitDoubleString("1e-15")); + EXPECT_TRUE(LegitDoubleString("1E-15")); + EXPECT_TRUE(LegitDoubleString("0.31E-15")); + EXPECT_TRUE(LegitDoubleString(".0031E-15")); + EXPECT_TRUE(LegitDoubleString("1e-15")); + EXPECT_TRUE(LegitDoubleString("1E015")); + EXPECT_TRUE(LegitDoubleString("0.31E015")); + + EXPECT_FALSE(LegitDoubleString(".5f")); - EXPECT_FALSE(LegitDoubleString("1e-15")); - EXPECT_FALSE(LegitDoubleString("1E-15")); - EXPECT_FALSE(LegitDoubleString("0.31E-15")); - EXPECT_FALSE(LegitDoubleString(".0031E-15")); - EXPECT_FALSE(LegitDoubleString("1e-15")); - EXPECT_FALSE(LegitDoubleString("1E015")); - EXPECT_FALSE(LegitDoubleString("0.31E015")); EXPECT_FALSE(LegitDoubleString("\n.0031E015")); EXPECT_FALSE(LegitDoubleString(".05f")); EXPECT_FALSE(LegitDoubleString(" 1 2 ")); @@ -3838,6 +3842,119 @@ } } + +TEST(GenericToolbox, TestStringToDoubleHardScientific) +{ + using OrthancStone::GenericToolbox::StringToDouble; + const double TOLERANCE = 0.00000000000001; + + size_t i = 0; + const size_t COUNT = 125; + //const double FACTOR = 1.000000000171271211; + const double FACTOR = 1.71271211; + for (double b = DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) + { + + // the tolerance must be adapted depending on the exponent + double exponent = (b == 0) ? 0 : 1.0 + std::floor(std::log10(std::fabs(b))); + double actualTolerance = TOLERANCE * pow(10.0, exponent); + + char txt[1024]; +#if defined(_MSC_VER) + sprintf_s(txt, "%.17e", b); +#else + snprintf(txt, sizeof(txt) - 1, "%.17e", b); +#endif + double r = 0.0; + bool ok = StringToDouble(r, txt); + +#if 0 + if (ok) + { + printf("OK for txt = \"%s\" and r = %.17e\n", txt, r); + } + else + { + printf("Not ok for txt = \"%s\" and r = %.17e\n", txt, r); + ok = StringToDouble(r, txt); + } +#endif + + EXPECT_TRUE(ok); + +#if 0 + if (fabs(b - r) > actualTolerance) + { + printf("NOK fabs(b (%.17f) - r (%.17f)) ((%.17f)) > actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); + printf("NOK fabs(b (%.17e) - r (%.17e)) ((%.17e)) > actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); + ok = StringToDouble(r, txt); + } + else + { + printf("OK fabs(b (%.17f) - r (%.17f)) ((%.17f)) <= actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); + printf("OK fabs(b (%.17e) - r (%.17e)) ((%.17e)) <= actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); + } +#endif + EXPECT_NEAR(b, r, actualTolerance); + } +} + +TEST(GenericToolbox, TestStringToDoubleHardNegScientific) +{ + using OrthancStone::GenericToolbox::StringToDouble; + const double TOLERANCE = 0.00000000000001; + + size_t i = 0; + const size_t COUNT = 125; + //const double FACTOR = 1.000000000171271211; + const double FACTOR = 1.71271211; + for (double b = -1.0 * DBL_EPSILON; b < DBL_MAX && i < COUNT; ++i, b *= FACTOR) + { + // the tolerance must be adapted depending on the exponent + double exponent = (b == 0) ? 0 : 1.0 + std::floor(std::log10(std::fabs(b))); + double actualTolerance = TOLERANCE * pow(10.0, exponent); + + char txt[1024]; +#if defined(_MSC_VER) + sprintf_s(txt, "%.17e", b); +#else + snprintf(txt, sizeof(txt) - 1, "%.17e", b); +#endif + double r = 0.0; + bool ok = StringToDouble(r, txt); + +#if 0 + if (ok) + { + printf("OK for txt = \"%s\" and r = %.17e\n", txt, r); + } + else + { + printf("Not ok for txt = \"%s\" and r = %.17e\n", txt, r); + ok = StringToDouble(r, txt); + } +#endif + + EXPECT_TRUE(ok); + +#if 0 + if (fabs(b - r) > actualTolerance) + { + printf("NOK fabs(b (%.17f) - r (%.17f)) ((%.17f)) > actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); + printf("NOK fabs(b (%.17e) - r (%.17e)) ((%.17e)) > actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); + ok = StringToDouble(r, txt); + } + else + { + printf("OK fabs(b (%.17f) - r (%.17f)) ((%.17f)) <= actualTolerance (%.17f)\n", b, r, fabs(b - r), actualTolerance); + printf("OK fabs(b (%.17e) - r (%.17e)) ((%.17e)) <= actualTolerance (%.17e)\n", b, r, fabs(b - r), actualTolerance); + } +#endif + EXPECT_NEAR(b, r, actualTolerance); + } +} + + TEST(GenericToolbox, TestStringToIntegerHard) { using OrthancStone::GenericToolbox::StringToInteger; diff -r 1644de437a7b -r ba08f2b0a779 UnitTestsSources/TestStructureSet.cpp