Commit 5e03cbf1 authored by Milo Yip's avatar Milo Yip

Merge pull request #134 from Kosta-Github/Kosta/add_key_method

add `Key()` method to the `Handler` concept
parents bc9d7866 f0d9ab4e
...@@ -31,6 +31,7 @@ struct CapitalizeFilter { ...@@ -31,6 +31,7 @@ struct CapitalizeFilter {
return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string return out_.String(&buffer_.front(), length, true); // true = output handler need to copy the string
} }
bool StartObject() { return out_.StartObject(); } bool StartObject() { return out_.StartObject(); }
bool Key(const char* str, SizeType length, bool copy) { return String(str, length, copy); }
bool EndObject(SizeType memberCount) { return out_.EndObject(memberCount); } bool EndObject(SizeType memberCount) { return out_.EndObject(memberCount); }
bool StartArray() { return out_.StartArray(); } bool StartArray() { return out_.StartArray(); }
bool EndArray(SizeType elementCount) { return out_.EndArray(elementCount); } bool EndArray(SizeType elementCount) { return out_.EndArray(elementCount); }
......
...@@ -17,6 +17,10 @@ struct MyHandler { ...@@ -17,6 +17,10 @@ struct MyHandler {
return true; return true;
} }
bool StartObject() { cout << "StartObject()" << endl; return true; } bool StartObject() { cout << "StartObject()" << endl; return true; }
bool Key(const char* str, SizeType length, bool copy) {
cout << "Key(" << str << ", " << length << ", " << boolalpha << copy << ")" << endl;
return true;
}
bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl; return true; } bool EndObject(SizeType memberCount) { cout << "EndObject(" << memberCount << ")" << endl; return true; }
bool StartArray() { cout << "StartArray()" << endl; return true; } bool StartArray() { cout << "StartArray()" << endl; return true; }
bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl; return true; } bool EndArray(SizeType elementCount) { cout << "EndArray(" << elementCount << ")" << endl; return true; }
......
...@@ -1386,7 +1386,7 @@ int z = a[0u].GetInt(); // This works too. ...@@ -1386,7 +1386,7 @@ int z = a[0u].GetInt(); // This works too.
if (!handler.StartObject()) if (!handler.StartObject())
return false; return false;
for (ConstMemberIterator m = MemberBegin(); m != MemberEnd(); ++m) { 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; return false;
if (!m->value.Accept(handler)) if (!m->value.Accept(handler))
return false; return false;
...@@ -1794,6 +1794,8 @@ private: ...@@ -1794,6 +1794,8 @@ private:
bool StartObject() { new (stack_.template Push<ValueType>()) ValueType(kObjectType); return true; } 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) { bool EndObject(SizeType memberCount) {
typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount); typename ValueType::Member* members = stack_.template Pop<typename ValueType::Member>(memberCount);
stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator()); stack_.template Top<ValueType>()->SetObjectRaw(members, (SizeType)memberCount, GetAllocator());
......
...@@ -88,6 +88,8 @@ public: ...@@ -88,6 +88,8 @@ public:
return Base::WriteStartObject(); return Base::WriteStartObject();
} }
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
bool EndObject(SizeType memberCount = 0) { bool EndObject(SizeType memberCount = 0) {
(void)memberCount; (void)memberCount;
RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level)); RAPIDJSON_ASSERT(Base::level_stack_.GetSize() >= sizeof(typename Base::Level));
...@@ -135,6 +137,7 @@ public: ...@@ -135,6 +137,7 @@ public:
//! Simpler but slower overload. //! Simpler but slower overload.
bool String(const Ch* str) { return String(str, internal::StrLen(str)); } bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
//@} //@}
protected: protected:
......
...@@ -152,6 +152,7 @@ concept Handler { ...@@ -152,6 +152,7 @@ concept Handler {
bool Double(double d); bool Double(double d);
bool String(const Ch* str, SizeType length, bool copy); bool String(const Ch* str, SizeType length, bool copy);
bool StartObject(); bool StartObject();
bool Key(const Ch* str, SizeType length, bool copy);
bool EndObject(SizeType memberCount); bool EndObject(SizeType memberCount);
bool StartArray(); bool StartArray();
bool EndArray(SizeType elementCount); bool EndArray(SizeType elementCount);
...@@ -181,6 +182,7 @@ struct BaseReaderHandler { ...@@ -181,6 +182,7 @@ struct BaseReaderHandler {
bool Double(double) { return static_cast<Override&>(*this).Default(); } bool Double(double) { return static_cast<Override&>(*this).Default(); }
bool String(const Ch*, SizeType, bool) { 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 StartObject() { return static_cast<Override&>(*this).Default(); }
bool Key(const Ch* str, SizeType len, bool copy) { return static_cast<Override&>(*this).String(str, len, copy); }
bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); } bool EndObject(SizeType) { return static_cast<Override&>(*this).Default(); }
bool StartArray() { return static_cast<Override&>(*this).Default(); } bool StartArray() { return static_cast<Override&>(*this).Default(); }
bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); } bool EndArray(SizeType) { return static_cast<Override&>(*this).Default(); }
...@@ -471,7 +473,7 @@ private: ...@@ -471,7 +473,7 @@ private:
if (is.Peek() != '"') if (is.Peek() != '"')
RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell()); RAPIDJSON_PARSE_ERROR(kParseErrorObjectMissName, is.Tell());
ParseString<parseFlags>(is, handler); ParseString<parseFlags>(is, handler, true);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
SkipWhitespace(is); SkipWhitespace(is);
...@@ -617,26 +619,29 @@ private: ...@@ -617,26 +619,29 @@ private:
// Parse string and generate String event. Different code paths for kParseInsituFlag. // Parse string and generate String event. Different code paths for kParseInsituFlag.
template<unsigned parseFlags, typename InputStream, typename Handler> template<unsigned parseFlags, typename InputStream, typename Handler>
void ParseString(InputStream& is, Handler& handler) { void ParseString(InputStream& is, Handler& handler, bool isKey = false) {
internal::StreamLocalCopy<InputStream> copy(is); internal::StreamLocalCopy<InputStream> copy(is);
InputStream& s(copy.s); InputStream& s(copy.s);
bool success = false;
if (parseFlags & kParseInsituFlag) { if (parseFlags & kParseInsituFlag) {
typename InputStream::Ch *head = s.PutBegin(); typename InputStream::Ch *head = s.PutBegin();
ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s); ParseStringToStream<parseFlags, SourceEncoding, SourceEncoding>(s, s);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
size_t length = s.PutEnd(head) - 1; size_t length = s.PutEnd(head) - 1;
RAPIDJSON_ASSERT(length <= 0xFFFFFFFF); RAPIDJSON_ASSERT(length <= 0xFFFFFFFF);
if (!handler.String((typename TargetEncoding::Ch*)head, SizeType(length), false)) const typename TargetEncoding::Ch* const str = (typename TargetEncoding::Ch*)head;
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); success = (isKey ? handler.Key(str, SizeType(length), false) : handler.String(str, SizeType(length), false));
} }
else { else {
StackStream stackStream(stack_); StackStream stackStream(stack_);
ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream); ParseStringToStream<parseFlags, SourceEncoding, TargetEncoding>(s, stackStream);
RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID; RAPIDJSON_PARSE_ERROR_EARLY_RETURN_VOID;
if (!handler.String(stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_), stackStream.length_ - 1, true)) const typename TargetEncoding::Ch* const str = stack_.template Pop<typename TargetEncoding::Ch>(stackStream.length_);
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell()); success = (isKey ? handler.Key(str, stackStream.length_ - 1, true) : handler.String(str, stackStream.length_ - 1, true));
} }
if (!success)
RAPIDJSON_PARSE_ERROR(kParseErrorTermination, s.Tell());
} }
// Parse string to an output is // Parse string to an output is
...@@ -1194,7 +1199,7 @@ private: ...@@ -1194,7 +1199,7 @@ private:
} }
case IterativeParsingMemberKeyState: case IterativeParsingMemberKeyState:
ParseString<parseFlags>(is, handler); ParseString<parseFlags>(is, handler, true);
if (HasParseError()) if (HasParseError())
return IterativeParsingErrorState; return IterativeParsingErrorState;
else else
......
...@@ -131,6 +131,8 @@ public: ...@@ -131,6 +131,8 @@ public:
return WriteStartObject(); return WriteStartObject();
} }
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); }
bool EndObject(SizeType memberCount = 0) { bool EndObject(SizeType memberCount = 0) {
(void)memberCount; (void)memberCount;
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level));
...@@ -165,6 +167,7 @@ public: ...@@ -165,6 +167,7 @@ public:
//! Simpler but slower overload. //! Simpler but slower overload.
bool String(const Ch* str) { return String(str, internal::StrLen(str)); } bool String(const Ch* str) { return String(str, internal::StrLen(str)); }
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); }
//@} //@}
......
...@@ -819,9 +819,10 @@ struct IterativeParsingReaderHandler { ...@@ -819,9 +819,10 @@ struct IterativeParsingReaderHandler {
const static int LOG_DOUBLE = -7; const static int LOG_DOUBLE = -7;
const static int LOG_STRING = -8; const static int LOG_STRING = -8;
const static int LOG_STARTOBJECT = -9; const static int LOG_STARTOBJECT = -9;
const static int LOG_ENDOBJECT = -10; const static int LOG_KEY = -10;
const static int LOG_STARTARRAY = -11; const static int LOG_ENDOBJECT = -11;
const static int LOG_ENDARRAY = -12; const static int LOG_STARTARRAY = -12;
const static int LOG_ENDARRAY = -13;
const static size_t LogCapacity = 256; const static size_t LogCapacity = 256;
int Logs[LogCapacity]; int Logs[LogCapacity];
...@@ -848,6 +849,8 @@ struct IterativeParsingReaderHandler { ...@@ -848,6 +849,8 @@ struct IterativeParsingReaderHandler {
bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; } bool StartObject() { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_STARTOBJECT; return true; }
bool Key (const Ch*, SizeType, bool) { RAPIDJSON_ASSERT(LogCount < LogCapacity); Logs[LogCount++] = LOG_KEY; return true; }
bool EndObject(SizeType c) { bool EndObject(SizeType c) {
RAPIDJSON_ASSERT(LogCount < LogCapacity); RAPIDJSON_ASSERT(LogCount < LogCapacity);
Logs[LogCount++] = LOG_ENDOBJECT; Logs[LogCount++] = LOG_ENDOBJECT;
...@@ -880,7 +883,7 @@ TEST(Reader, IterativeParsing_General) { ...@@ -880,7 +883,7 @@ TEST(Reader, IterativeParsing_General) {
handler.LOG_STARTARRAY, handler.LOG_STARTARRAY,
handler.LOG_INT, handler.LOG_INT,
handler.LOG_STARTOBJECT, handler.LOG_STARTOBJECT,
handler.LOG_STRING, handler.LOG_KEY,
handler.LOG_STARTARRAY, handler.LOG_STARTARRAY,
handler.LOG_INT, handler.LOG_INT,
handler.LOG_INT, handler.LOG_INT,
...@@ -918,7 +921,7 @@ TEST(Reader, IterativeParsing_Count) { ...@@ -918,7 +921,7 @@ TEST(Reader, IterativeParsing_Count) {
handler.LOG_STARTOBJECT, handler.LOG_STARTOBJECT,
handler.LOG_ENDOBJECT, 0, handler.LOG_ENDOBJECT, 0,
handler.LOG_STARTOBJECT, handler.LOG_STARTOBJECT,
handler.LOG_STRING, handler.LOG_KEY,
handler.LOG_INT, handler.LOG_INT,
handler.LOG_ENDOBJECT, 1, handler.LOG_ENDOBJECT, 1,
handler.LOG_STARTARRAY, handler.LOG_STARTARRAY,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment