diff --git a/example/lookaheadparser/lookaheadparser.cpp b/example/lookaheadparser/lookaheadparser.cpp index f4759c4..29469ed 100644 --- a/example/lookaheadparser/lookaheadparser.cpp +++ b/example/lookaheadparser/lookaheadparser.cpp @@ -19,15 +19,15 @@ // // After calling EnterObject, you retrieve keys via NextObjectKey() and values via // the normal getters. When NextObjectKey() returns null, you have exited the -// object, or you can call ExitObject() to skip to the end of the object +// object, or you can call SkipObject() to skip to the end of the object // immediately. If you fetch the entire object (i.e. NextObjectKey() returned null), -// you should not call ExitObject(). +// you should not call SkipObject(). // // After calling EnterArray(), you must alternate between calling NextArrayValue() // to see if the array has more data, and then retrieving values via the normal -// getters. You can call ExitArray() to skip to the end of the array immediately. +// getters. You can call SkipArray() to skip to the end of the array immediately. // If you fetch the entire array (i.e. NextArrayValue() returned null), -// you should not call ExitArray(). +// you should not call SkipArray(). // // This parser uses in-situ strings, so the JSON buffer will be altered during the // parse. @@ -37,15 +37,15 @@ using namespace rapidjson; class LookaheadParserHandler { public: - bool Null() { st_ = kHasValue; v_.SetNull(); return true; } - bool Bool(bool b) { st_ = kHasValue; v_.SetBool(b); return true; } - bool Int(int i) { st_ = kHasValue; v_.SetInt(i); return true; } - bool Uint(unsigned u) { st_ = kHasValue; v_.SetUint(u); return true; } - bool Int64(int64_t i) { st_ = kHasValue; v_.SetInt64(i); return true; } - bool Uint64(uint64_t u) { st_ = kHasValue; v_.SetUint64(u); return true; } - bool Double(double d) { st_ = kHasValue; v_.SetDouble(d); return true; } + bool Null() { st_ = kHasNull; v_.SetNull(); return true; } + bool Bool(bool b) { st_ = kHasBool; v_.SetBool(b); return true; } + bool Int(int i) { st_ = kHasNumber; v_.SetInt(i); return true; } + bool Uint(unsigned u) { st_ = kHasNumber; v_.SetUint(u); return true; } + bool Int64(int64_t i) { st_ = kHasNumber; v_.SetInt64(i); return true; } + bool Uint64(uint64_t u) { st_ = kHasNumber; v_.SetUint64(u); return true; } + bool Double(double d) { st_ = kHasNumber; v_.SetDouble(d); return true; } bool RawNumber(const char*, SizeType, bool) { return false; } - bool String(const char* str, SizeType length, bool) { st_ = kHasValue; v_.SetString(str, length); return true; } + bool String(const char* str, SizeType length, bool) { st_ = kHasString; v_.SetString(str, length); return true; } bool StartObject() { st_ = kEnteringObject; return true; } bool Key(const char* str, SizeType length, bool) { st_ = kHasKey; v_.SetString(str, length); return true; } bool EndObject(SizeType) { st_ = kExitingObject; return true; } @@ -58,8 +58,12 @@ protected: protected: enum LookaheadParsingState { + kInit, kError, - kHasValue, + kHasNull, + kHasBool, + kHasNumber, + kHasString, kHasKey, kEnteringObject, kExitingObject, @@ -75,7 +79,7 @@ protected: static const int parseFlags = kParseDefaultFlags | kParseInsituFlag; }; -LookaheadParserHandler::LookaheadParserHandler(char* str) : ss_(str) { +LookaheadParserHandler::LookaheadParserHandler(char* str) : v_(), st_(kInit), r_(), ss_(str) { r_.IterativeParseInit(); ParseNext(); } @@ -93,10 +97,8 @@ class LookaheadParser : protected LookaheadParserHandler { public: LookaheadParser(char* str) : LookaheadParserHandler(str) {} - void EnterObject(); - void EnterArray(); - void ExitObject(); - void ExitArray(); + bool EnterObject(); + bool EnterArray(); const char* NextObjectKey(); bool NextArrayValue(); int GetInt(); @@ -105,57 +107,52 @@ public: bool GetBool(); void GetNull(); + void SkipObject(); + void SkipArray(); void SkipValue(); Value* PeekValue(); int PeekType(); // returns a rapidjson::Type, or -1 for no value (at end of object/array) bool IsValid() { return st_ != kError; } + +protected: + void SkipOut(int depth); }; -void LookaheadParser::EnterObject() { +bool LookaheadParser::EnterObject() { if (st_ != kEnteringObject) { st_ = kError; - return; + return false; } ParseNext(); + return true; } -void LookaheadParser::EnterArray() { +bool LookaheadParser::EnterArray() { if (st_ != kEnteringArray) { st_ = kError; - return; + return false; } ParseNext(); -} - -void LookaheadParser::ExitObject() { - while (NextObjectKey()) { - SkipValue(); - } -} - -void LookaheadParser::ExitArray() { - while (NextArrayValue()) { - SkipValue(); - } + return true; } const char* LookaheadParser::NextObjectKey() { - if (st_ == kExitingObject) { + if (st_ == kHasKey) { + const char* result = v_.GetString(); ParseNext(); - return 0; + return result; } - - if (st_ != kHasKey || !v_.IsString()) { + + if (st_ != kExitingObject) { st_ = kError; return 0; } - const char* result = v_.GetString(); ParseNext(); - return result; + return 0; } bool LookaheadParser::NextArrayValue() { @@ -164,11 +161,16 @@ bool LookaheadParser::NextArrayValue() { return false; } + if (st_ == kError || st_ == kExitingObject || st_ == kHasKey) { + st_ = kError; + return false; + } + return true; } int LookaheadParser::GetInt() { - if (st_ != kHasValue || !v_.IsInt()) { + if (st_ != kHasNumber || !v_.IsInt()) { st_ = kError; return 0; } @@ -179,7 +181,7 @@ int LookaheadParser::GetInt() { } double LookaheadParser::GetDouble() { - if (st_ != kHasValue || !v_.IsNumber()) { + if (st_ != kHasNumber) { st_ = kError; return 0.; } @@ -190,7 +192,7 @@ double LookaheadParser::GetDouble() { } bool LookaheadParser::GetBool() { - if (st_ != kHasValue || !v_.IsBool()) { + if (st_ != kHasBool) { st_ = kError; return false; } @@ -201,7 +203,7 @@ bool LookaheadParser::GetBool() { } void LookaheadParser::GetNull() { - if (st_ != kHasValue || !v_.IsNull()) { + if (st_ != kHasNull) { st_ = kError; return; } @@ -210,7 +212,7 @@ void LookaheadParser::GetNull() { } const char* LookaheadParser::GetString() { - if (st_ != kHasValue || !v_.IsString()) { + if (st_ != kHasString) { st_ = kError; return 0; } @@ -220,34 +222,37 @@ const char* LookaheadParser::GetString() { return result; } -void LookaheadParser::SkipValue() { - int depth = 0; +void LookaheadParser::SkipOut(int depth) { do { - switch (st_) { - case kEnteringArray: - case kEnteringObject: - ++depth; - break; - - case kExitingArray: - case kExitingObject: - --depth; - break; - - case kError: - return; - - case kHasKey: - case kHasValue: - break; + if (st_ == kEnteringArray || st_ == kEnteringObject) { + ++depth; } + else if (st_ == kExitingArray || st_ == kExitingObject) { + --depth; + } + else if (st_ == kError) { + return; + } + ParseNext(); } while (depth > 0); } +void LookaheadParser::SkipValue() { + SkipOut(0); +} + +void LookaheadParser::SkipArray() { + SkipOut(1); +} + +void LookaheadParser::SkipObject() { + SkipOut(1); +} + Value* LookaheadParser::PeekValue() { - if (st_ == kHasValue || st_ == kHasKey) { + if (st_ >= kHasNull && st_ <= kHasKey) { return &v_; } @@ -255,23 +260,19 @@ Value* LookaheadParser::PeekValue() { } int LookaheadParser::PeekType() { - switch (st_) { - case kHasValue: - case kHasKey: - return v_.GetType(); - - case kEnteringArray: - return kArrayType; - - case kEnteringObject: - return kObjectType; - - case kExitingArray: - case kExitingObject: - case kError: - default: - return -1; + if (st_ >= kHasNull && st_ <= kHasKey) { + return v_.GetType(); } + + if (st_ == kEnteringArray) { + return kArrayType; + } + + if (st_ == kEnteringObject) { + return kObjectType; + } + + return -1; } //------------------------------------------------------------------------- @@ -325,7 +326,7 @@ int main() { cout << r.GetString() << " "; } else { - r.ExitArray(); + r.SkipArray(); break; } }