Operator Console
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Static Public Member Functions | Static Public Attributes | List of all members
JSONWorker Class Reference

#include <JSONWorker.h>

Static Public Member Functions

static json_string RemoveWhiteSpaceAndComments (const json_string &value_t, bool escapeQuotes) json_nothrow json_read_priority
 
static void DoArray (const internalJSONNode *parent, const json_string &value_t) json_nothrow json_read_priority
 
static void DoNode (const internalJSONNode *parent, const json_string &value_t) json_nothrow json_read_priority
 
static json_string FixString (const json_string &value_t, bool &flag) json_nothrow json_read_priority
 
template<json_char ch>
static size_t FindNextRelevant (const json_string &value_t, const size_t pos) json_nothrow json_read_priority
 
static void UnfixString (const json_string &value_t, bool flag, json_string &res) json_nothrow
 
static JSON_PRIVATE json_char Hex (const json_char *&pos) json_nothrow
 
static json_uchar UTF8 (const json_char *&pos) json_nothrow
 
static json_string toUTF8 (json_uchar p) json_nothrow
 
static void SpecialChar (const json_char *&pos, json_string &res) json_nothrow
 
static void NewNode (const internalJSONNode *parent, const json_string &name, const json_string &value, bool array) json_nothrow
 
static json_string RemoveWhiteSpaceAndComments (const json_string &value_t, bool escapeQuotes) json_nothrow json_read_priority
 
static void DoArray (const internalJSONNode *parent, const json_string &value_t) json_nothrow json_read_priority
 
static void DoNode (const internalJSONNode *parent, const json_string &value_t) json_nothrow json_read_priority
 
static json_string FixString (const json_string &value_t, bool &flag) json_nothrow json_read_priority
 
template<json_char ch>
static size_t FindNextRelevant (const json_string &value_t, const size_t pos) json_nothrow json_read_priority
 
static void UnfixString (const json_string &value_t, bool flag, json_string &res) json_nothrow
 
static JSON_PRIVATE json_char Hex (const json_char *&pos) json_nothrow
 
static json_uchar UTF8 (const json_char *&pos) json_nothrow
 
static json_string toUTF8 (json_uchar p) json_nothrow
 
static void SpecialChar (const json_char *&pos, json_string &res) json_nothrow
 
static void NewNode (const internalJSONNode *parent, const json_string &name, const json_string &value, bool array) json_nothrow
 

Static Public Attributes

static JSONNode static parse(const
json_string &json) json_throws(std
JSONNode static
parse_unformatted(const
json_string &json) json_throws(std
JSONNode static
_parse_unformatted(const
json_char *json) json_throws(std
json_char 
RemoveWhiteSpace )(const json_string &value_t, bool escapeQuotes) json_nothrow json_read_priority
 

Member Function Documentation

void JSONWorker::DoArray ( const internalJSONNode parent,
const json_string &  value_t 
)
static

References FIND_NEXT_RELEVANT, JSON_ASSERT, JSON_ASSERT_SAFE, json_global, JSON_TEXT, and json_unlikely.

Referenced by internalJSONNode::FetchArray().

638  {
639  //This takes an array and creates nodes out of them
640  JSON_ASSERT(!value_t.empty(), JSON_TEXT("DoArray is empty"));
641  JSON_ASSERT_SAFE(value_t[0] == JSON_TEXT('['), JSON_TEXT("DoArray is not an array"), parent -> Nullify(); return;);
642  if (json_unlikely(value_t.length() <= 2)) return; // just a [] (blank array)
643 
644  #ifdef JSON_SAFE
645  json_string newValue; //share this so it has a reserved buffer
646  #endif
647  size_t starting = 1; //ignore the [
648 
649  //Not sure what's in the array, so we have to use commas
650  for(size_t ending = FIND_NEXT_RELEVANT(JSON_TEXT(','), value_t, 1);
651  ending != json_string::npos;
652  ending = FIND_NEXT_RELEVANT(JSON_TEXT(','), value_t, starting)){
653 
654  #ifdef JSON_SAFE
655  newValue.assign(value_t.begin() + starting, value_t.begin() + ending);
656  JSON_ASSERT_SAFE(FIND_NEXT_RELEVANT(JSON_TEXT(':'), newValue, 0) == json_string::npos, JSON_TEXT("Key/Value pairs are not allowed in arrays"), parent -> Nullify(); return;);
657  NewNode(parent, json_global(EMPTY_JSON_STRING), newValue, true);
658  #else
659  NewNode(parent, json_global(EMPTY_JSON_STRING), json_string(value_t.begin() + starting, value_t.begin() + ending), true);
660  #endif
661  starting = ending + 1;
662  }
663  //since the last one will not find the comma, we have to add it here, but ignore the final ]
664 
665  #ifdef JSON_SAFE
666  newValue.assign(value_t.begin() + starting, value_t.end() - 1);
667  JSON_ASSERT_SAFE(FIND_NEXT_RELEVANT(JSON_TEXT(':'), newValue, 0) == json_string::npos, JSON_TEXT("Key/Value pairs are not allowed in arrays"), parent -> Nullify(); return;);
668  NewNode(parent, json_global(EMPTY_JSON_STRING), newValue, true);
669  #else
670  NewNode(parent, json_global(EMPTY_JSON_STRING), json_string(value_t.begin() + starting, value_t.end() - 1), true);
671  #endif
672 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define json_unlikely(x)
Definition: Unknown_C.h:17
#define FIND_NEXT_RELEVANT(ch, vt, po)
Definition: JSONWorker.cpp:135
#define json_global(NAME)
Definition: JSONGlobals.h:26
#define JSON_ASSERT(condition, msg)
Definition: JSONDebug.h:53
#define JSON_ASSERT_SAFE(condition, msg, code)
Definition: JSONDebug.h:49
static void NewNode(const internalJSONNode *parent, const json_string &name, const json_string &value, bool array) json_nothrow

Here is the caller graph for this function:

static void JSONWorker::DoArray ( const internalJSONNode parent,
const json_string &  value_t 
)
static
void JSONWorker::DoNode ( const internalJSONNode parent,
const json_string &  value_t 
)
static

References FIND_NEXT_RELEVANT, JSON_ASSERT, JSON_ASSERT_SAFE, JSON_TEXT, and json_unlikely.

Referenced by internalJSONNode::FetchNode().

676  {
677  //This take a node and creates its members and such
678  JSON_ASSERT(!value_t.empty(), JSON_TEXT("DoNode is empty"));
679  JSON_ASSERT_SAFE(value_t[0] == JSON_TEXT('{'), JSON_TEXT("DoNode is not an node"), parent -> Nullify(); return;);
680  if (json_unlikely(value_t.length() <= 2)) return; // just a {} (blank node)
681 
682  size_t name_ending = FIND_NEXT_RELEVANT(JSON_TEXT(':'), value_t, 1); //find where the name ends
683  JSON_ASSERT_SAFE(name_ending != json_string::npos, JSON_TEXT("Missing :"), parent -> Nullify(); return;);
684  json_string name(value_t.begin() + 1, value_t.begin() + name_ending - 1); //pull the name out
685  for (size_t value_ending = FIND_NEXT_RELEVANT(JSON_TEXT(','), value_t, name_ending), //find the end of the value
686  name_starting = 1; //ignore the {
687  value_ending != json_string::npos;
688  value_ending = FIND_NEXT_RELEVANT(JSON_TEXT(','), value_t, name_ending)){
689 
690  NewNode(parent, name, json_string(value_t.begin() + name_ending + 1, value_t.begin() + value_ending), false);
691  name_starting = value_ending + 1;
692  name_ending = FIND_NEXT_RELEVANT(JSON_TEXT(':'), value_t, name_starting);
693  JSON_ASSERT_SAFE(name_ending != json_string::npos, JSON_TEXT("Missing :"), parent -> Nullify(); return;);
694  name.assign(value_t.begin() + name_starting, value_t.begin() + name_ending - 1);
695  }
696  //since the last one will not find the comma, we have to add it here
697  NewNode(parent, name, json_string(value_t.begin() + name_ending + 1, value_t.end() - 1), false);
698 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define json_unlikely(x)
Definition: Unknown_C.h:17
#define FIND_NEXT_RELEVANT(ch, vt, po)
Definition: JSONWorker.cpp:135
#define JSON_ASSERT(condition, msg)
Definition: JSONDebug.h:53
#define JSON_ASSERT_SAFE(condition, msg, code)
Definition: JSONDebug.h:49
static void NewNode(const internalJSONNode *parent, const json_string &name, const json_string &value, bool array) json_nothrow

Here is the caller graph for this function:

static void JSONWorker::DoNode ( const internalJSONNode parent,
const json_string &  value_t 
)
static
template<json_char ch>
size_t JSONWorker::FindNextRelevant ( const json_string &  value_t,
const size_t  pos 
)
static

References BRACKET, json_char, json_nothrow, JSON_TEXT, json_unlikely, and QUOTECASE.

137  {
138  #else
139  #define FIND_NEXT_RELEVANT(ch, vt, po) JSONWorker::FindNextRelevant(ch, vt, po)
140  size_t JSONWorker::FindNextRelevant(json_char ch, const json_string & value_t, const size_t pos) json_nothrow {
141  #endif
142  //TODO get rid of the c_str and use an iterator to take advantage of shared strings
143  json_string::const_iterator start = value_t.begin();
144  for (json_string::const_iterator p = start + pos; *p; ++p){
145  if (json_unlikely(*p == ch)) return p - start;
146  switch (*p){
147  BRACKET(JSON_TEXT('['), JSON_TEXT(']'))
148  BRACKET(JSON_TEXT('{'), JSON_TEXT('}'))
149  QUOTECASE()
150  }
151  };
152  return json_string::npos;
153  }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define json_unlikely(x)
Definition: Unknown_C.h:17
static size_t FindNextRelevant(const json_string &value_t, const size_t pos) json_nothrow json_read_priority
Definition: JSONWorker.cpp:137
#define json_char
Definition: Strings_Defs.h:21
#define BRACKET(left, right)
Definition: JSONWorker.cpp:112
#define json_nothrow
Definition: Unknown_C.h:8
template<json_char ch>
static size_t JSONWorker::FindNextRelevant ( const json_string &  value_t,
const size_t  pos 
)
static
json_string JSONWorker::FixString ( const json_string &  value_t,
bool &  flag 
)
static

References json_char, JSON_TEXT, setflag, and shrinkString.

Referenced by internalJSONNode::FetchString().

467  {
468  #define setflag(x) flag = x
469 #endif
470 
471  //Do things like unescaping
472  setflag(false);
473  json_string res;
474  res.reserve(value_t.length()); //since it goes one character at a time, want to reserve it first so that it doens't have to reallocating
475  for(const json_char * p = value_t.c_str(); *p; ++p){
476  switch (*p){
477  case JSON_TEXT('\\'):
478  setflag(true);
479  SpecialChar(++p, res);
480  break;
481  default:
482  res += *p;
483  break;
484  }
485  }
486  return shrinkString(res); //because this is actually setting something to be stored, shrink it it need be
487 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define shrinkString(str)
Definition: JSONMemory.h:162
#define setflag(x)
#define json_char
Definition: Strings_Defs.h:21
static void SpecialChar(const json_char *&pos, json_string &res) json_nothrow
Definition: JSONWorker.cpp:384

Here is the caller graph for this function:

static json_string JSONWorker::FixString ( const json_string &  value_t,
bool &  flag 
)
static
static JSON_PRIVATE json_char JSONWorker::Hex ( const json_char *&  pos)
static
json_char JSONWorker::Hex ( const json_char *&  pos)
static

References json_char, and json_uchar.

350  {
351  /*
352  takes the numeric value of the next two characters and convert them
353  \u0058 becomes 0x58
354 
355  In case of \u, it's SpecialChar's responsibility to move past the first two chars
356  as this method is also used for \x
357  */
358  //First character
359  json_uchar hi = *pos++ - 48;
360  if (hi > 48){ //A-F don't immediately follow 0-9, so have to pull them down a little
361  hi -= 39;
362  } else if (hi > 9){ //neither do a-f
363  hi -= 7;
364  }
365  //second character
366  json_uchar lo = *pos - 48;
367  if (lo > 48){ //A-F don't immediately follow 0-9, so have to pull them down a little
368  lo -= 39;
369  } else if (lo > 9){ //neither do a-f
370  lo -= 7;
371  }
372  //combine them
373  return (json_char)((hi << 4) | lo);
374 }
#define json_char
Definition: Strings_Defs.h:21
#define json_uchar
Definition: Strings_Defs.h:22
static void JSONWorker::NewNode ( const internalJSONNode parent,
const json_string &  name,
const json_string &  value,
bool  array 
)
static
static void JSONWorker::NewNode ( const internalJSONNode parent,
const json_string &  name,
const json_string &  value,
bool  array 
)
static
json_string JSONWorker::RemoveWhiteSpaceAndComments ( const json_string &  value_t,
bool  escapeQuotes 
)
static

References ascii_one(), JSON_ASSERT_SAFE, json_char, JSON_TEXT, json_uchar, json_unlikely, and SingleLineComment().

Referenced by libjson::is_valid(), and libjson::strip_white_space().

248  {
249  json_string result;
250  result.reserve(value_t.length());
251  try {
252  for(const json_char * p = value_t.c_str(); *p; ++p){
253  switch(*p){
254  case JSON_TEXT(' '): //defined as white space
255  case JSON_TEXT('\t'): //defined as white space
256  case JSON_TEXT('\n'): //defined as white space
257  case JSON_TEXT('\r'): //defined as white space
258  break;
259  #ifndef JSON_STRICT
260  case JSON_TEXT('/'): //a C comment
261  if (*(++p) == JSON_TEXT('*')){ //a multiline comment
262  while ((*(++p) != JSON_TEXT('*')) || (*(p + 1) != JSON_TEXT('/'))){
263  if (json_unlikely(*p == JSON_TEXT('\0'))) throw false;
264  }
265  ++p;
266  break;
267  }
268  //Should be a single line C comment, so let it fall through to use the bash comment stripper
269  JSON_ASSERT_SAFE(*p == JSON_TEXT('/'), JSON_TEXT("stray / character, not quoted, or a comment"), throw false;);
270  case JSON_TEXT('#'): //a bash comment
272  break;
273  #endif
274  case JSON_TEXT('\"'): //a quote
275  result += JSON_TEXT('\"');
276  while(*(++p) != JSON_TEXT('\"')){ //find the end of the quotation, as white space is preserved within it
277  switch(*p){
278  case JSON_TEXT('\\'):
279  result += JSON_TEXT('\\');
280  if (escapeQuotes){
281  result += (*++p == JSON_TEXT('\"')) ? ascii_one() : *p; //an escaped quote will reak havoc will all of my searching functions, so change it into an illegal character in JSON for convertion later on
282  }
283  break;
284  case '\0':
285  throw false;
286  default:
287  result += *p;
288  break;
289  }
290  }
291  //no break, let it fall through so that the trailing quote gets added
292  default:
293  JSON_ASSERT_SAFE((json_uchar)*p >= 32, JSON_TEXT("Invalid JSON character detected (lo)"), throw false;);
294  JSON_ASSERT_SAFE((json_uchar)*p <= 126, JSON_TEXT("Invalid JSON character detected (hi)"), throw false;);
295  result += *p;
296  break;
297  }
298  }
299  } catch (...){}
300  return result;
301 }
json_char ascii_one(void) json_nothrow
Definition: JSONWorker.cpp:4
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define json_unlikely(x)
Definition: Unknown_C.h:17
void SingleLineComment(const json_char *&p, json_char *&runner) json_nothrow
Definition: JSONWorker.cpp:159
#define json_char
Definition: Strings_Defs.h:21
#define JSON_ASSERT_SAFE(condition, msg, code)
Definition: JSONDebug.h:49
#define json_uchar
Definition: Strings_Defs.h:22

Here is the call graph for this function:

Here is the caller graph for this function:

static json_string JSONWorker::RemoveWhiteSpaceAndComments ( const json_string &  value_t,
bool  escapeQuotes 
)
static
void JSONWorker::SpecialChar ( const json_char *&  pos,
json_string &  res 
)
static

References FromOctal(), JSON_FAIL, and JSON_TEXT.

384  {
385  /*
386  Since JSON uses forward slash escaping for special characters within strings, I have to
387  convert these escaped characters into C characters
388  */
389  switch(*pos){
390  case JSON_TEXT('\1'): //quote character (altered by RemoveWhiteSpace)
391  res += JSON_TEXT('\"');
392  break;
393  case JSON_TEXT('t'): //tab character
394  res += JSON_TEXT('\t');
395  break;
396  case JSON_TEXT('n'): //newline character
397  res += JSON_TEXT('\n');
398  break;
399  case JSON_TEXT('r'): //return character
400  res += JSON_TEXT('\r');
401  break;
402  case JSON_TEXT('\\'): //backslash
403  res += JSON_TEXT('\\');
404  break;
405  case JSON_TEXT('/'): //forward slash
406  res += JSON_TEXT('/');
407  break;
408  case JSON_TEXT('b'): //backspace
409  res += JSON_TEXT('\b');
410  break;
411  case JSON_TEXT('f'): //formfeed
412  res += JSON_TEXT('\f');
413  break;
414  case JSON_TEXT('v'): //vertical tab
415  res += JSON_TEXT('\v');
416  break;
417  case JSON_TEXT('u'): //utf character
418  #ifdef JSON_UNICODE
419  UTF(pos, res);
420  #else
421  res += UTF8(pos);
422  #endif
423  break;
424  #ifndef JSON_STRICT
425  case JSON_TEXT('x'): //hexidecimal ascii code
426  res += Hex(++pos);
427  break;
428 
429  #ifdef __GNUC__
430  case JSON_TEXT('0') ... JSON_TEXT('7'):
431  #else
432  //octal encoding
433  case JSON_TEXT('0'):
434  case JSON_TEXT('1'):
435  case JSON_TEXT('2'):
436  case JSON_TEXT('3'):
437  case JSON_TEXT('4'):
438  case JSON_TEXT('5'):
439  case JSON_TEXT('6'):
440  case JSON_TEXT('7'):
441  #endif
442  res += FromOctal(pos);
443  break;
444  default:
445  res += *pos;
446  break;
447  #elif defined(JSON_DEBUG)
448  default:
449  JSON_FAIL(JSON_TEXT("Unsupported escaped character"));
450  break;
451  #endif
452  }
453 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
json_char FromOctal(const json_char *&str) json_nothrow
Definition: JSONWorker.cpp:377
static json_uchar UTF8(const json_char *&pos) json_nothrow
Definition: JSONWorker.cpp:335
static JSON_PRIVATE json_char Hex(const json_char *&pos) json_nothrow
Definition: JSONWorker.cpp:350
#define JSON_FAIL(msg)
Definition: JSONDebug.h:54

Here is the call graph for this function:

static void JSONWorker::SpecialChar ( const json_char *&  pos,
json_string &  res 
)
static
json_string JSONWorker::toUTF8 ( json_uchar  p)
static

References END_MEM_SCOPE, JSON_TEXT, json_uchar, json_unlikely, and START_MEM_SCOPE.

512  {
513  #ifdef JSON_UNICODE
514  if (json_unlikely(p > 0xFFFF)) return toSurrogatePair(p);
515  #endif
516  json_string res(JSON_TEXT("\\u"));
517  #ifdef JSON_UNICODE
519  json_uchar hihi = ((p & 0xF000) >> 12) + 48;
520  if (hihi > 57) hihi += 7; //A-F don't immediately follow 0-9, so have to further adjust those
521  json_uchar hilo = ((p & 0x0F00) >> 8) + 48;
522  if (hilo > 57) hilo += 7; //A-F don't immediately follow 0-9, so have to further adjust those
523  res += hihi;
524  res += hilo;
526  json_uchar hi = ((p & 0x00F0) >> 4) + 48;
527  #else
528  res += JSON_TEXT("00");
529  json_uchar hi = (p >> 4) + 48;
530  #endif
531  //convert the character to be escaped into two digits between 0 and 15
532  if (hi > 57) hi += 7; //A-F don't immediately follow 0-9, so have to further adjust those
533  json_uchar lo = (p & 0x000F) + 48;
534  if (lo > 57) lo += 7; //A-F don't immediately follow 0-9, so have to further adjust those
535  res += hi;
536  res += lo;
537  return res;
538  }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define json_unlikely(x)
Definition: Unknown_C.h:17
#define END_MEM_SCOPE
Definition: JSONDefs.h:89
#define START_MEM_SCOPE
Definition: JSONDefs.h:88
#define json_uchar
Definition: Strings_Defs.h:22
static json_string JSONWorker::toUTF8 ( json_uchar  p)
static
void JSONWorker::UnfixString ( const json_string &  value_t,
bool  flag,
json_string &  res 
)
static

References json_char, JSON_TEXT, json_uchar, and json_unlikely.

Referenced by internalJSONNode::Write(), and internalJSONNode::WriteName().

541  {
542  if (!flag){
543  res += value_t;
544  return;
545  }
546  //Re-escapes a json_string so that it can be written out into a JSON file
547  for(const json_char * p = value_t.c_str(); *p; ++p){
548  switch(*p){
549  case JSON_TEXT('\"'): //quote character
550  res += JSON_TEXT("\\\"");
551  break;
552  case JSON_TEXT('\\'): //backslash
553  res += JSON_TEXT("\\\\");
554  break;
555  #ifdef JSON_ESCAPE_WRITES
556  case JSON_TEXT('\t'): //tab character
557  res += JSON_TEXT("\\t");
558  break;
559  case JSON_TEXT('\n'): //newline character
560  res += JSON_TEXT("\\n");
561  break;
562  case JSON_TEXT('\r'): //return character
563  res += JSON_TEXT("\\r");
564  break;
565  case JSON_TEXT('/'): //forward slash
566  res += JSON_TEXT("\\/");
567  break;
568  case JSON_TEXT('\b'): //backspace
569  res += JSON_TEXT("\\b");
570  break;
571  case JSON_TEXT('\f'): //formfeed
572  res += JSON_TEXT("\\f");
573  break;
574  default:
575  if (json_unlikely(((json_uchar)(*p) < 32) || ((json_uchar)(*p) > 126))){
576  res += toUTF8((json_uchar)(*p));
577  } else {
578  res += *p;
579  }
580  break;
581  #else
582  default:
583  res += *p;
584  break;
585  #endif
586  }
587  }
588 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
#define json_unlikely(x)
Definition: Unknown_C.h:17
static json_string toUTF8(json_uchar p) json_nothrow
Definition: JSONWorker.cpp:512
#define json_char
Definition: Strings_Defs.h:21
#define json_uchar
Definition: Strings_Defs.h:22

Here is the caller graph for this function:

static void JSONWorker::UnfixString ( const json_string &  value_t,
bool  flag,
json_string &  res 
)
static
json_uchar JSONWorker::UTF8 ( const json_char *&  pos)
static

References JSON_ASSERT, JSON_TEXT, and json_uchar.

335  {
336  #ifdef JSON_UNICODE
337  ++pos;
338  json_uchar temp = Hex(pos) << 8;
339  ++pos;
340  return temp | Hex(pos);
341  #else
342  JSON_ASSERT(*(pos + 1) == JSON_TEXT('0'), JSON_TEXT("wide utf character (hihi)"));
343  JSON_ASSERT(*(pos + 2) == JSON_TEXT('0'), JSON_TEXT("wide utf character (hilo)"));
344  pos += 3;
345  return Hex(pos);
346  #endif
347 }
#define JSON_TEXT(s)
Definition: Strings_Defs.h:30
static JSON_PRIVATE json_char Hex(const json_char *&pos) json_nothrow
Definition: JSONWorker.cpp:350
#define JSON_ASSERT(condition, msg)
Definition: JSONDebug.h:53
#define json_uchar
Definition: Strings_Defs.h:22
static json_uchar JSONWorker::UTF8 ( const json_char *&  pos)
static

Member Data Documentation

json_char * JSONWorker::RemoveWhiteSpace
static

The documentation for this class was generated from the following files: