diff options
author | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-25 01:19:26 +0100 |
---|---|---|
committer | Benjamin Paassen <bpaassen@techfak.uni-bielefeld.de> | 2015-01-25 01:19:26 +0100 |
commit | c36f476f434c16a52ada15bdfcc5f92bcad1b8db (patch) | |
tree | a65cc3ce1e2ca5f7a75c2917a4dadaec4fcd5d5e /src | |
parent | ea2ff3388513949ddb5d3e3c2dca89bceb3d52bc (diff) |
Some bugfixes in cardinality conversion and further Variant conversion tests
Diffstat (limited to 'src')
-rw-r--r-- | src/core/common/VariantConverter.cpp | 27 | ||||
-rw-r--r-- | src/core/common/VariantConverter.hpp | 19 | ||||
-rw-r--r-- | src/core/common/VariantReader.cpp | 20 |
3 files changed, 39 insertions, 27 deletions
diff --git a/src/core/common/VariantConverter.cpp b/src/core/common/VariantConverter.cpp index 03eb2e8..ff7c5a1 100644 --- a/src/core/common/VariantConverter.cpp +++ b/src/core/common/VariantConverter.cpp @@ -22,12 +22,14 @@ #include <string> #include <sstream> +#include "CharReader.hpp" #include "Function.hpp" #include "Logger.hpp" #include "Number.hpp" #include "Rtti.hpp" #include "Variant.hpp" #include "VariantConverter.hpp" +#include "VariantReader.hpp" #include "VariantWriter.hpp" namespace ousia { @@ -389,9 +391,11 @@ bool VariantConverter::toMap(Variant &var, const Rtti &innerType, bool VariantConverter::toCardinality(Variant &var, Logger &logger, Mode mode) { + if (var.isCardinality()) { + return true; + } // Perform safe conversions (all these operations are considered "lossless") - const VariantType type = var.getType(); - if (type == VariantType::INT) { + if (var.isInt()) { int value = var.asInt(); var.setCardinality(Variant::cardinalityType{}); Variant::cardinalityType &card = var.asCardinality(); @@ -406,6 +410,7 @@ bool VariantConverter::toCardinality(Variant &var, Logger &logger, Mode mode) // Perform lossy conversions if (mode == Mode::ALL) { + const VariantType type = var.getType(); switch (type) { case VariantType::NULLPTR: var.setCardinality(Variant::cardinalityType{}); @@ -465,11 +470,11 @@ bool VariantConverter::toCardinality(Variant &var, Logger &logger, Mode mode) return false; } int end = endVar.asInt(); - if (end <= start) { + if (end < start) { logger.error( std::string("The supposed start value ") + std::to_string(start) + - " was bigger or equal to the supposed end value " + + " was bigger than the supposed end value " + std::to_string(end) + " of the Range."); return false; } @@ -479,11 +484,15 @@ bool VariantConverter::toCardinality(Variant &var, Logger &logger, Mode mode) return true; } case VariantType::STRING: { - var.setCardinality(Variant::cardinalityType{}); - // Variant::cardinalityType &card = - // var.asCardinality(); - // TODO: Implement! - return false; + CharReader reader{var.asString().c_str()}; + auto res = VariantReader::parseCardinality(reader, logger); + if (res.first) { + var.setCardinality(res.second); + return true; + } else { + var.setCardinality(Variant::cardinalityType{}); + return false; + } } default: break; diff --git a/src/core/common/VariantConverter.hpp b/src/core/common/VariantConverter.hpp index 7e317a2..92cc40a 100644 --- a/src/core/common/VariantConverter.hpp +++ b/src/core/common/VariantConverter.hpp @@ -84,10 +84,10 @@ public: * to Mode::SAFE, only integers can be converted to integers. For all other * types the conversion fails. If "mode" is set to Mode::ALL, booleans are * converted to 0, 1, nullptr is converted to 0, doubles are truncated, - * strings are parsed and truncated, arrays with one element are converted - * to an integer. Conversion fails for objects, functions, maps and arrays - * with zero or more than one entry. If the conversion fails, 0 is returned - * as default value. + * strings are parsed and truncated, arrays and cardinalities with one + * element are converted to an integer. Conversion fails for objects, + * functions, maps and arrays with zero or more than one entry. If the + * conversion fails, 0 is returned as default value. * * @param var is instance of the Variant class that should be converted to * the requested type. @@ -105,7 +105,8 @@ public: * to Mode::SAFE, only integers and doubles can be converted to doubles. For * all other types the conversion fails. If "mode" is set to Mode::ALL, * booleans are converted to 0.0, 1.0, nullptr is converted to 0.0, strings - * are parsed, arrays with one element are converted to a double. + * are parsed, arrays and cardinalities with one element are converted to a + * double. * Conversion fails for objects, functions, maps and arrays with zero or * more than one entry. If the conversion fails, 0.0 is returned as default * value. @@ -125,10 +126,10 @@ public: * Converts the given variant to a string. If the "mode" parameter is set * to Mode::SAFE, all primitive types can be converted to strings. For * all other types the conversion fails. If "mode" is set to Mode::ALL, - * maps and arrays are converted to a JSON representation, objects and - * functions are converted to an informative string containing their pointer - * and type. If the conversion fails, an empty string is returned as default - * value. + * maps and arrays are converted to a JSON representation, cardinalities + * to their parsing syntax and objects and functions are converted to an + * informative string containing their pointer and type. If the conversion + * fails, an empty string is returned as default value. * * @param var is instance of the Variant class that should be converted to * the requested type. diff --git a/src/core/common/VariantReader.cpp b/src/core/common/VariantReader.cpp index bbceac5..7320973 100644 --- a/src/core/common/VariantReader.cpp +++ b/src/core/common/VariantReader.cpp @@ -518,7 +518,7 @@ std::pair<bool, Variant::mapType> VariantReader::parseObject(CharReader &reader, return std::make_pair(res.first, res.second.asMap()); } -static const std::unordered_set<char> cardDelims{' ', ',', '}'}; +static const std::unordered_set<char> cardDelims{' ', ',', '}', '-'}; std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( CharReader &reader, Logger &logger) @@ -533,6 +533,7 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( Variant::cardinalityType card{}; + reader.consumePeek(); reader.consumeWhitespace(); // which should in turn be followed by ranges. @@ -541,14 +542,15 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( // in case of a numeric character we want to read an integer. reader.resetPeek(); Number n; - n.parse(reader, logger, cardDelims); - if (!n.isInt() || n.intValue() < 0) { + if (!n.parse(reader, logger, cardDelims) || !n.isInt() || + n.intValue() < 0) { return error(reader, logger, "Invalid number for cardinality!", Variant::cardinalityType{}); } unsigned int start = (unsigned int)n.intValue(); // if we have that we might either find a } or , making this a // range or a - leading us to expect another integer. + reader.consumePeek(); reader.consumeWhitespace(); if (!reader.peek(c)) { error(reader, logger, ERR_UNEXPECTED_END, @@ -560,16 +562,16 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( reader.resetPeek(); break; case '-': { - reader.consumePeek(); // get another integer. + reader.consumePeek(); reader.consumeWhitespace(); if (!reader.peek(c)) { error(reader, logger, ERR_UNEXPECTED_END, Variant::cardinalityType{}); } Number n2; - n2.parse(reader, logger, cardDelims); - if (!n2.isInt() || n2.intValue() < 0) { + if (!n2.parse(reader, logger, cardDelims) || !n2.isInt() || + n2.intValue() < 0) { return error(reader, logger, "Invalid number for cardinality!", Variant::cardinalityType{}); @@ -583,9 +585,6 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( return unexpected(reader, logger, "}, , or -", c, Variant::cardinalityType{}); } - if (c == '{' || c == ',') { - reader.resetPeek(); - } } else { switch (c) { case '*': @@ -596,6 +595,7 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( case '<': case '>': { // in case of an open range we expect a number. + reader.consumePeek(); reader.consumeWhitespace(); Number n; if (!n.parse(reader, logger, cardDelims)) { @@ -625,6 +625,7 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( } } // after we have parsed a range, read all whitespaces. + reader.consumePeek(); reader.consumeWhitespace(); // ... and check if we are at the end. if (!reader.read(c)) { @@ -635,6 +636,7 @@ std::pair<bool, Variant::cardinalityType> VariantReader::parseCardinality( case '}': return std::make_pair(true, card); case ',': + reader.consumePeek(); reader.consumeWhitespace(); break; |