summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/common/VariantReader.cpp84
-rw-r--r--src/core/common/VariantReader.hpp36
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);
};
}