diff options
author | Kosta <konstantin.baumann@autodesk.com> | 2014-09-04 17:14:18 +0400 |
---|---|---|
committer | Kosta <konstantin.baumann@autodesk.com> | 2014-09-04 17:14:18 +0400 |
commit | 57e1c875534eb2e2c183c62e4421ad1a0bf8bf73 (patch) | |
tree | c4d4c53b3085e8d06c0d0ff107a285d4db407c89 | |
parent | bc9d7866be368e54671243b34f746bdada2afbe1 (diff) |
add `Key()` method to the `Handler` concept
For more details see: https://github.com/miloyip/rapidjson/issues/132
This commit tries to minimize the required code changes and forwards the `Handler::Key()` calls to `Handler::String()` wherever possible in order to not break existing code; or at least not code deriving from `BaseReaderHandler` when implementing a custom `Handler`.
-rw-r--r-- | include/rapidjson/document.h | 4 | ||||
-rw-r--r-- | include/rapidjson/reader.h | 40 |
2 files changed, 34 insertions, 10 deletions
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 13acb381..310fc710 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1386,7 +1386,7 @@ int z = a[0u].GetInt(); // This works too. if (!handler.StartObject())
return false;
for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) {
- if (!handler.String(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0))
+ if (!handler.Key(m->name.GetString(), m->name.GetStringLength(), (m->name.flags_ & kCopyFlag) != 0))
return false;
if (!m->value.Accept(handler))
return false;
@@ -1794,6 +1794,8 @@ private: bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; }
+ bool Key(const Ch* str, SizeType length, bool copy) { return String(str, length, copy); }
+
bool EndObject(SizeType memberCount) {
typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
diff --git a/include/rapidjson/reader.h b/include/rapidjson/reader.h index 701255fa..f02dd161 100644 --- a/include/rapidjson/reader.h +++ b/include/rapidjson/reader.h @@ -152,6 +152,7 @@ concept Handler { bool Double(double d);
bool String(const Ch* str, SizeType length, bool copy);
bool StartObject();
+ bool Key(const Ch* str, SizeType length, bool copy);
bool EndObject(SizeType memberCount);
bool StartArray();
bool EndArray(SizeType elementCount);
@@ -181,6 +182,7 @@ struct BaseReaderHandler { bool Double(double) { return static_cast<Override&>(*this).Default(); }
bool String(const Ch*, SizeType, bool) { return static_cast<Override&>(*this).Default(); }
bool StartObject() { return static_cast<Override&>(*this).Default(); }
+ bool Key(const Ch* str, SizeType len, bool copy) { return String(str, len, copy); }
bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
bool StartArray() { return static_cast<Override&>(*this).Default(); }
bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
@@ -471,7 +473,7 @@ private: if (is.Peek() != '"')
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
- ParseString<parseFlags>(is, handler);
+ ParseKey<parseFlags>(is, handler);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
SkipWhitespace(is);
@@ -576,7 +578,7 @@ private: RAPIDJSON_PARSE_ERROR(kParseErrorValueInvalid, is.Tell() - 1);
}
- // Helper function to parse four hexidecimal digits in \uXXXX in ParseString().
+ // Helper function to parse four hexidecimal digits in \uXXXX in ParseStringOrKey().
template<typename InputStream>
unsigned ParseHex4(InputStream& is) {
unsigned codepoint = 0;
@@ -616,8 +618,8 @@ private: };
// Parse string and generate String event. Different code paths for kParseInsituFlag.
- template<unsigned parseFlags, typename InputStream, typename Handler>
- void ParseString(InputStream& is, Handler& handler) {
+ template<unsigned parseFlags, bool isKey, typename InputStream, typename Handler>
+ void ParseStringOrKey(InputStream& is, Handler& handler) {
internal::StreamLocalCopy<InputStream> copy(is);
InputStream& s(copy.s);
@@ -627,18 +629,38 @@ private: RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
size_t length = s.PutEnd(head) - 1;
RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
- if (!handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
+ if (isKey) {
+ if (!handler.Key((typename TargetEncoding::Ch*)head, SizeType(length), false))
+ RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
+ } else {
+ if (!handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false))
+ RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
+ }
}
else {
StackStream stackStream(stack_);
ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
- if (!handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true))
- RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
+ if (isKey) {
+ if (!handler.Key(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true))
+ RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
+ } else {
+ if (!handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true))
+ RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
+ }
}
}
+ template<unsigned parseFlags, typename InputStream, typename Handler>
+ void ParseKey(InputStream& is, Handler& handler) {
+ return ParseStringOrKey<parseFlags, true>(is, handler);
+ }
+
+ template<unsigned parseFlags, typename InputStream, typename Handler>
+ void ParseString(InputStream& is, Handler& handler) {
+ return ParseStringOrKey<parseFlags, false>(is, handler);
+ }
+
// Parse string to an output is
// This function handles the prefix/suffix double quotes, escaping, and optional encoding validation.
template<unsigned parseFlags, typename SEncoding, typename TEncoding, typename InputStream, typename OutputStream>
@@ -1194,7 +1216,7 @@ private: }
case IterativeParsingMemberKeyState:
- ParseString<parseFlags>(is, handler);
+ ParseKey<parseFlags>(is, handler);
if (HasParseError())
return IterativeParsingErrorState;
else
|