1 #include "JSONStream.h"
4 #include "JSONWorker.h"
5 #include "JSONValidator.h"
8 JSONStream::JSONStream(json_stream_callback_t call_p, json_stream_e_callback_t call_e,
void * callbackIdentifier) json_nothrow : state(
true), call(call_p), err_call(call_e), buffer(), callback_identifier(callbackIdentifier) {
12 JSONStream::JSONStream(
const JSONStream & orig) json_nothrow : state(orig.state), call(orig.call), err_call(orig.err_call), buffer(orig.buffer), callback_identifier(orig.callback_identifier){
16 JSONStream & JSONStream::operator =(
const JSONStream & orig) json_nothrow {
18 err_call = orig.err_call;
22 callback_identifier = orig.callback_identifier;
27 JSONStream & JSONStream::operator << (
const json_char * str) json_nothrow {
29 JSONStream & JSONStream::operator << (
const json_string & str) json_nothrow {
39 #define QUOTECASE_STREAM()\
40 case JSON_TEXT('\"'):\
41 while (*(++p) != JSON_TEXT('\"')){\
42 if (json_unlikely(*p == JSON_TEXT('\0'))) return json_string::npos;\
47 #define NULLCASE_STREAM()\
48 case JSON_TEXT('\0'):\
49 return json_string::npos;\
52 #define BRACKET_STREAM(left, right)\
69 return json_string::npos;
71 #if (JSON_READ_PRIORITY == HIGH) && (!(defined(JSON_LESS_MEMORY)))
72 #define STREAM_FIND_NEXT_RELEVANT(ch, vt, po) FindNextRelevant<ch>(vt, po)
73 template<json_
char ch>
74 size_t JSONStream::FindNextRelevant(
const json_string & value_t,
const size_t pos) json_nothrow {
76 #define STREAM_FIND_NEXT_RELEVANT(ch, vt, po) FindNextRelevant(ch, vt, po)
77 size_t JSONStream::FindNextRelevant(json_char ch,
const json_string & value_t,
const size_t pos) json_nothrow {
79 const json_char * start = value_t.c_str();
80 for (
const json_char * p = start + pos; *p; ++p){
81 if (json_unlikely(*p == ch))
return p - start;
83 BRACKET_STREAM(JSON_TEXT(
'['), JSON_TEXT(
']'))
84 BRACKET_STREAM(JSON_TEXT('{
'), JSON_TEXT('}
'))
88 return json_string::npos;
91 void JSONStream::parse(void) json_nothrow {
92 #ifdef JSON_SECURITY_MAX_STREAM_OBJECTS
96 size_t pos = buffer.find_first_of(JSON_TEXT("{["));
97 if (json_likely(pos != json_string::npos)){
98 size_t end = (buffer[pos] == JSON_TEXT('[
')) ? STREAM_FIND_NEXT_RELEVANT(JSON_TEXT(']
'), buffer, pos + 1) : STREAM_FIND_NEXT_RELEVANT(JSON_TEXT('}
'), buffer, pos + 1);
99 if (end != json_string::npos){
100 #ifdef JSON_SECURITY_MAX_STREAM_OBJECTS
101 if (++objects > JSON_SECURITY_MAX_STREAM_OBJECTS){
102 JSON_FAIL(JSON_TEXT("Maximum number of json objects for a stream at once has been reached"));
103 if (err_call) err_call(getIdentifier());
109 JSONNode temp(JSONWorker::parse(buffer.substr(pos, end - pos + 1)));
111 call(temp, getIdentifier());
113 call(&temp, getIdentifier());
116 json_string::iterator beginning = buffer.begin();
117 buffer.erase(beginning, beginning + end);
118 continue; //parse(); //parse the next object too
122 //verify that what's in there is at least valid so far
123 #ifndef JSON_VALIDATE
124 #error In order to use safe mode and streams, JSON_VALIDATE needs to be defined
127 json_auto<json_char> s;
129 s.set(JSONWorker::RemoveWhiteSpace(json_string(buffer.c_str() + pos), len,
false));
132 if (!JSONValidator::isValidPartialRoot(s.ptr)){
133 if (err_call) err_call(getIdentifier());