2
0

JSONStream.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. #include "JSONStream.h"
  2. #ifdef JSON_STREAM
  3. #include "JSONWorker.h"
  4. #include "JSONValidator.h"
  5. 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) {
  6. LIBJSON_CTOR;
  7. }
  8. 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){
  9. LIBJSON_COPY_CTOR;
  10. }
  11. JSONStream & JSONStream::operator =(const JSONStream & orig) json_nothrow {
  12. LIBJSON_ASSIGNMENT;
  13. err_call = orig.err_call;
  14. call = orig.call;
  15. state = orig.state;
  16. buffer = orig.buffer;
  17. callback_identifier = orig.callback_identifier;
  18. return *this;
  19. }
  20. #ifdef JSON_LIBRARY
  21. JSONStream & JSONStream::operator << (const json_char * str) json_nothrow {
  22. #else
  23. JSONStream & JSONStream::operator << (const json_string & str) json_nothrow {
  24. #endif
  25. if (state){
  26. buffer += str;
  27. parse();
  28. }
  29. return *this;
  30. }
  31. #define QUOTECASE_STREAM()\
  32. case JSON_TEXT('\"'):\
  33. while (*(++p) != JSON_TEXT('\"')){\
  34. if (json_unlikely(*p == JSON_TEXT('\0'))) return json_string::npos;\
  35. }\
  36. break;
  37. #define NULLCASE_STREAM()\
  38. case JSON_TEXT('\0'):\
  39. return json_string::npos;\
  40. #define BRACKET_STREAM(left, right)\
  41. case left: {\
  42. size_t brac = 1;\
  43. while (brac){\
  44. switch (*(++p)){\
  45. case right:\
  46. --brac;\
  47. break;\
  48. case left:\
  49. ++brac;\
  50. break;\
  51. QUOTECASE_STREAM()\
  52. NULLCASE_STREAM()\
  53. }\
  54. }\
  55. break;}\
  56. case right:\
  57. return json_string::npos;
  58. #if (JSON_READ_PRIORITY == HIGH) && (!(defined(JSON_LESS_MEMORY)))
  59. #define STREAM_FIND_NEXT_RELEVANT(ch, vt, po) FindNextRelevant<ch>(vt, po)
  60. template<json_char ch>
  61. size_t JSONStream::FindNextRelevant(const json_string & value_t, const size_t pos) json_nothrow {
  62. #else
  63. #define STREAM_FIND_NEXT_RELEVANT(ch, vt, po) FindNextRelevant(ch, vt, po)
  64. size_t JSONStream::FindNextRelevant(json_char ch, const json_string & value_t, const size_t pos) json_nothrow {
  65. #endif
  66. const json_char * start = value_t.c_str();
  67. for (const json_char * p = start + pos; *p; ++p){
  68. if (json_unlikely(*p == ch)) return p - start;
  69. switch (*p){
  70. BRACKET_STREAM(JSON_TEXT('['), JSON_TEXT(']'))
  71. BRACKET_STREAM(JSON_TEXT('{'), JSON_TEXT('}'))
  72. QUOTECASE_STREAM()
  73. }
  74. };
  75. return json_string::npos;
  76. }
  77. void JSONStream::parse(void) json_nothrow {
  78. #ifdef JSON_SECURITY_MAX_STREAM_OBJECTS
  79. size_t objects = 0;
  80. #endif
  81. for(;;){
  82. size_t pos = buffer.find_first_of(JSON_TEXT("{["));
  83. if (json_likely(pos != json_string::npos)){
  84. 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);
  85. if (end != json_string::npos){
  86. #ifdef JSON_SECURITY_MAX_STREAM_OBJECTS
  87. if (++objects > JSON_SECURITY_MAX_STREAM_OBJECTS){
  88. JSON_FAIL(JSON_TEXT("Maximum number of json objects for a stream at once has been reached"));
  89. if (err_call) err_call(getIdentifier());
  90. state = false;
  91. return;
  92. }
  93. #endif
  94. START_MEM_SCOPE
  95. JSONNode temp(JSONWorker::parse(buffer.substr(pos, end - pos + 1)));
  96. #ifndef JSON_LIBRARY
  97. call(temp, getIdentifier());
  98. #else
  99. call(&temp, getIdentifier());
  100. #endif
  101. END_MEM_SCOPE
  102. json_string::iterator beginning = buffer.begin();
  103. buffer.erase(beginning, beginning + end);
  104. continue; //parse(); //parse the next object too
  105. }
  106. #ifdef JSON_SAFE
  107. else {
  108. //verify that what's in there is at least valid so far
  109. #ifndef JSON_VALIDATE
  110. #error In order to use safe mode and streams, JSON_VALIDATE needs to be defined
  111. #endif
  112. json_auto<json_char> s;
  113. size_t len;
  114. s.set(JSONWorker::RemoveWhiteSpace(json_string(buffer.c_str() + pos), len, false));
  115. if (!JSONValidator::isValidPartialRoot(s.ptr)){
  116. if (err_call) err_call(getIdentifier());
  117. state = false;
  118. }
  119. }
  120. #endif
  121. }
  122. break;
  123. }
  124. }
  125. #endif