diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/common/VariantReader.cpp | 84 | ||||
-rw-r--r-- | src/core/common/VariantReader.hpp | 36 |
2 files changed, 116 insertions, 4 deletions
diff --git a/src/core/common/VariantReader.cpp b/src/core/common/VariantReader.cpp index cac29b9..3f02226 100644 --- a/src/core/common/VariantReader.cpp +++ b/src/core/common/VariantReader.cpp @@ -484,8 +484,8 @@ std::pair<bool, std::string> VariantReader::parseUnescapedString( return std::make_pair(true, res.str()); } -std::pair<bool, Variant::boolType> VariantReader::parseBool( - CharReader &reader, Logger &logger) +std::pair<bool, Variant::boolType> VariantReader::parseBool(CharReader &reader, + Logger &logger) { // first we consume all whitespaces. reader.consumePeek(); @@ -867,5 +867,85 @@ std::pair<bool, Variant> VariantReader::parseGenericString( v.setLocation({sourceId, offs, offs + str.size()}); return std::make_pair(true, v); } + +std::pair<bool, Variant> VariantReader::parseTyped( + VariantType type, CharReader &reader, Logger &logger, + const std::unordered_set<char> &delims) +{ + switch (type) { + case VariantType::BOOL: { + auto res = parseBool(reader, logger); + return std::make_pair(res.first, Variant{res.second}); + } + case VariantType::INT: { + auto res = parseInteger(reader, logger, delims); + if (res.second < std::numeric_limits<Variant::intType>::min() || + res.second > std::numeric_limits<Variant::intType>::max()) { + logger.error("Number exceeds type limits.", reader); + return std::make_pair(false, Variant{}); + } + return std::make_pair( + res.first, Variant{static_cast<Variant::intType>(res.second)}); + } + case VariantType::DOUBLE: { + auto res = parseDouble(reader, logger, delims); + return std::make_pair(res.first, Variant{res.second}); + } + case VariantType::STRING: { + auto res = parseString(reader, logger, delims); + return std::make_pair(res.first, Variant::fromString(res.second)); + } + case VariantType::ARRAY: { + char delim = 0; + if (delims.size() == 1) { + delim = *delims.begin(); + } + auto res = parseArray(reader, logger, delim); + return std::make_pair(res.first, Variant{res.second}); + } + + case VariantType::MAP: + case VariantType::OBJECT: { + char delim = 0; + if (delims.size() == 1) { + delim = *delims.begin(); + } + auto res = parseObject(reader, logger, delim); + return std::make_pair(res.first, Variant{res.second}); + } + case VariantType::CARDINALITY: { + auto res = parseCardinality(reader, logger); + return std::make_pair(res.first, Variant{res.second}); + } + default: + break; + } + + return std::make_pair(false, Variant{}); +} + +std::pair<bool, Variant> VariantReader::parseTyped(VariantType type, + const std::string &str, + Logger &logger, + SourceId sourceId, + size_t offs) +{ + // create a char reader and forward the method. + CharReader reader{str, sourceId, offs}; + LoggerFork loggerFork = logger.fork(); + std::pair<bool, Variant> res = + parseTyped(type, reader, loggerFork, std::unordered_set<char>{}); + + // If all content could be parsed, commit the result. + if (reader.atEnd()) { + loggerFork.commit(); + return res; + } + + // otherwise do not. + logger.error("Not all input could be processed", + {sourceId, offs, offs + str.size()}); + return std::make_pair(false, Variant{}); +} } diff --git a/src/core/common/VariantReader.hpp b/src/core/common/VariantReader.hpp index 6a87723..1232f6e 100644 --- a/src/core/common/VariantReader.hpp +++ b/src/core/common/VariantReader.hpp @@ -182,7 +182,7 @@ public: * * @param reader is a reference to the CharReader instance which is * the source for the character data. The reader will be positioned after - * the number or at the terminating delimiting character. + * the array or at the terminating delimiting character. * @param logger is the logger instance that should be used to log error * messages and warnings. * @param delim is the terminating character. If nonzero, the parse function @@ -198,7 +198,7 @@ public: * * @param reader is a reference to the CharReader instance which is * the source for the character data. The reader will be positioned after - * the number or at the terminating delimiting character. + * the object or at the terminating delimiting character. * @param logger is the logger instance that should be used to log error * messages and warnings. * @param delim is the terminating character. If nonzero, the parse function @@ -306,6 +306,38 @@ public: static std::pair<bool, Variant> parseGenericString( const std::string &str, Logger &logger, SourceId sourceId = InvalidSourceId, size_t offs = 0); + + /** + * Tries to parse an instance of the given type from the given stream. The + * called method is one of the parse methods defined here and adheres to the + * specifications defined there. + * + * @param type is the VariantType for which an instance shall be parsed. + * @param reader is a reference to the CharReader instance which is + * the source for the character data. The reader will be positioned + * at the end of the type instance (or the delimiting character). + * @param delims is a set of characters which will terminate the typed + * instance if the according parser uses delimiting characters. + * These characters are not included in the result. May not be nullptr. + */ + static std::pair<bool, Variant> parseTyped( + VariantType type, CharReader &reader, Logger &logger, + const std::unordered_set<char> &delims = {}); + /** + * Tries to parse an instance of the given type from the given string. The + * called method is one of the parse methods defined here and adheres to the + * specifications defined there. + * + * @param type is the VariantType for which an instance shall be parsed. + * @param str is the string from which the value should be read. + * @param sourceId is an optional descriptor of the source file from which + * the element is being read. + * @param offs is the by offset in the source file at which the string + * starts. + */ + static std::pair<bool, Variant> parseTyped( + VariantType type, const std::string &str, Logger &logger, + SourceId sourceId = InvalidSourceId, size_t offs = 0); }; } |