From c670850ceb259f79384f4159c50435062b9178af Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 27 Jun 2016 09:18:27 +0100 Subject: Add default conversions and throw if conversion solution can't be found --- slicer/slicer/modelParts.cpp | 3 +++ slicer/slicer/modelParts.h | 5 +++++ slicer/slicer/parser.cpp | 22 ++++++++++++++++++++++ slicer/test/preprocessor.cpp | 4 ++-- slicer/test/serializers.cpp | 26 ++++++++++++++++++++++++++ slicer/test/types.ice | 11 +++++++++++ 6 files changed, 69 insertions(+), 2 deletions(-) diff --git a/slicer/slicer/modelParts.cpp b/slicer/slicer/modelParts.cpp index 12df3af..2e144fa 100644 --- a/slicer/slicer/modelParts.cpp +++ b/slicer/slicer/modelParts.cpp @@ -19,6 +19,9 @@ namespace Slicer { InvalidEnumerationValue::InvalidEnumerationValue(::Ice::Int n, const std::string & e) : std::invalid_argument("Invalid value " + boost::lexical_cast(n) + " in " + e) { } + NoConversionFound::NoConversionFound(const std::string & n) : + std::runtime_error("Could not convert to/from model for type " + n) { } + ClassNameMap * & classNameMap() { diff --git a/slicer/slicer/modelParts.h b/slicer/slicer/modelParts.h index 58aa3c8..ea563c1 100644 --- a/slicer/slicer/modelParts.h +++ b/slicer/slicer/modelParts.h @@ -38,6 +38,11 @@ namespace Slicer { InvalidEnumerationValue(::Ice::Int n, const std::string & e); }; + class DLL_PUBLIC NoConversionFound : public std::runtime_error { + public: + NoConversionFound(const std::string & n); + }; + template class TValueTarget { public: diff --git a/slicer/slicer/parser.cpp b/slicer/slicer/parser.cpp index 15c6afd..1159fee 100644 --- a/slicer/slicer/parser.cpp +++ b/slicer/slicer/parser.cpp @@ -68,6 +68,17 @@ namespace Slicer { fprintbf(cpp, "\t\treturn;\n"); fprintbf(cpp, "\t}\n"); } + // Default conversion + if (!dm->hasMetaData("slicer:nodefaultconversion")) { + fprintbf(cpp, "\tif (auto vspt = dynamic_cast *>(vsp.get())) {\n", + Slice::typeToString(type)); + fprintbf(cpp, "\t\tvspt->set(Member);\n"); + fprintbf(cpp, "\t\treturn;\n"); + fprintbf(cpp, "\t}\n"); + } + // Failed to convert + fprintbf(cpp, "\tthrow NoConversionFound(\"%s\");\n", + Slice::typeToString(type)); fprintbf(cpp, "}\n\n"); fprintbf(cpp, "template<>\nvoid\n"); @@ -85,6 +96,17 @@ namespace Slicer { fprintbf(cpp, "\t\treturn;\n"); fprintbf(cpp, "\t}\n"); } + // Default conversion + if (!dm->hasMetaData("slicer:nodefaultconversion")) { + fprintbf(cpp, "\tif (auto vtpt = dynamic_cast *>(vtp.get())) {\n", + Slice::typeToString(type)); + fprintbf(cpp, "\t\tvtpt->get(Member);\n"); + fprintbf(cpp, "\t\treturn;\n"); + fprintbf(cpp, "\t}\n"); + } + // Failed to convert + fprintbf(cpp, "\tthrow NoConversionFound(\"%s\");\n", + Slice::typeToString(type)); fprintbf(cpp, "}\n\n"); } } diff --git a/slicer/test/preprocessor.cpp b/slicer/test/preprocessor.cpp index 43a04fd..18fad39 100644 --- a/slicer/test/preprocessor.cpp +++ b/slicer/test/preprocessor.cpp @@ -13,7 +13,7 @@ namespace fs = boost::filesystem; -const unsigned int COMPONENTS_IN_TEST_ICE = 35; +const unsigned int COMPONENTS_IN_TEST_ICE = 37; BOOST_FIXTURE_TEST_SUITE ( preprocessor, FileStructure ); @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE( slicer_test_ice ) const fs::path so = fs::change_extension(tmp / ("libslicer" + slice.filename().string()), ".so"); const std::string link = stringbf( - "g++ -shared -Wl,--strip-all,--gc-sections -lIce -lIceUtil %s/lib%s.so %s/lib%s.so %s -o %s", + "g++ -shared -Wl,--strip-all,--gc-sections -lboost_date_time -lIce -lIceUtil %s/lib%s.so %s/lib%s.so %s -o %s", root / bjamout, base, included / bjamout, included.leaf(), obj, so); diff --git a/slicer/test/serializers.cpp b/slicer/test/serializers.cpp index f2adced..d23bd2f 100644 --- a/slicer/test/serializers.cpp +++ b/slicer/test/serializers.cpp @@ -478,6 +478,32 @@ BOOST_AUTO_TEST_CASE( optionals_areset_xml ) verifyByHelper("optionals-areset.xml", readXml, writeXml, freeXml, checkOptionals_areset); } +BOOST_AUTO_TEST_CASE( missingConversion ) +{ + auto in = json::parseValue("{\"conv\": \"2016-06-30 12:34:56\"}"); + BOOST_REQUIRE_THROW(( + Slicer::DeserializeAny(in) + ), Slicer::NoConversionFound); + + TestModule2::MissingConvPtr obj = new TestModule2::MissingConv("2016-06-30 12:34:56"); + json::Value v; + BOOST_REQUIRE_THROW( + Slicer::SerializeAny(obj, v), + Slicer::NoConversionFound); +} + +BOOST_AUTO_TEST_CASE( conversion ) +{ + auto in = json::parseValue("{\"conv\": \"2016-06-30 12:34:56\"}"); + auto obj = Slicer::DeserializeAny(in); + BOOST_REQUIRE_EQUAL("2016-06-30 12:34:56", obj->conv); + + json::Value v; + Slicer::SerializeAny(obj, v); + BOOST_REQUIRE_EQUAL("2016-06-30 12:34:56", + boost::get(*boost::get(v)["conv"])); +} + BOOST_FIXTURE_TEST_SUITE ( compatWrapper, FileBased ); BOOST_AUTO_TEST_CASE( any ) diff --git a/slicer/test/types.ice b/slicer/test/types.ice index 562099b..97df71b 100644 --- a/slicer/test/types.ice +++ b/slicer/test/types.ice @@ -1,4 +1,6 @@ [["cpp:include:boost/date_time/posix_time/posix_time_types.hpp"]] +[["cpp:include:boost/date_time/posix_time/time_formatters.hpp"]] +[["cpp:include:boost/date_time/posix_time/time_parsers.hpp"]] [["cpp:include:conversions.h"]] #include @@ -137,6 +139,15 @@ module TestModule2 { [ "slicer:xml:text" ] string Name; }; + class Conv { + [ "slicer:conversion:boost.posix_time.ptime:boost.posix_time.to_iso_extended_string:boost.posix_time.time_from_string:nodeclare" ] + string conv; + }; + class MissingConv { + [ "slicer:conversion:boost.posix_time.ptime:boost.posix_time.to_iso_extended_string:boost.posix_time.time_from_string:nodeclare", + "slicer:nodefaultconversion" ] + string conv; + }; }; module DB { -- cgit v1.2.3