Bike-X  0.8
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
OVR_JSON.cpp
Go to the documentation of this file.
1 /************************************************************************************
2 
3 PublicHeader: None
4 Filename : OVR_JSON.h
5 Content : JSON format reader and writer
6 Created : April 9, 2013
7 Author : Brant Lewis
8 Notes :
9  The code is a derivative of the cJSON library written by Dave Gamble and subject
10  to the following permissive copyright.
11 
12  Copyright (c) 2009 Dave Gamble
13 
14  Permission is hereby granted, free of charge, to any person obtaining a copy
15  of this software and associated documentation files (the "Software"), to deal
16  in the Software without restriction, including without limitation the rights
17  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18  copies of the Software, and to permit persons to whom the Software is
19  furnished to do so, subject to the following conditions:
20 
21  The above copyright notice and this permission notice shall be included in
22  all copies or substantial portions of the Software.
23 
24  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30  THE SOFTWARE.
31 
32 
33 Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved.
34 
35 Licensed under the Oculus VR Rift SDK License Version 3.1 (the "License");
36 you may not use the Oculus VR Rift SDK except in compliance with the License,
37 which is provided at the time of installation or download, or which
38 otherwise accompanies this software in either electronic or hard copy form.
39 
40 You may obtain a copy of the License at
41 
42 http://www.oculusvr.com/licenses/LICENSE-3.1
43 
44 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
45 distributed under the License is distributed on an "AS IS" BASIS,
46 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47 See the License for the specific language governing permissions and
48 limitations under the License.
49 
50 ************************************************************************************/
51 
52 #include <string.h>
53 #include <stdio.h>
54 #include <math.h>
55 #include <stdlib.h>
56 #include <float.h>
57 #include <limits.h>
58 #include <ctype.h>
59 #include "OVR_JSON.h"
60 #include "Kernel/OVR_SysFile.h"
61 #include "Kernel/OVR_Log.h"
62 
63 namespace OVR {
64 
65 
66 //-----------------------------------------------------------------------------
67 // Create a new copy of a string
68 static char* JSON_strdup(const char* str)
69 {
70  UPInt len = OVR_strlen(str) + 1;
71  char* copy = (char*)OVR_ALLOC(len);
72  if (!copy)
73  return 0;
74  memcpy(copy, str, len);
75  return copy;
76 }
77 
78 
79 //-----------------------------------------------------------------------------
80 // Render the number from the given item into a string.
81 static char* PrintNumber(double d)
82 {
83  char *str;
84  //double d=item->valuedouble;
85  int valueint = (int)d;
86  if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
87  {
88  str=(char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars.
89  if (str)
90  OVR_sprintf(str, 21, "%d", valueint);
91  }
92  else
93  {
94  str=(char*)OVR_ALLOC(64); // This is a nice tradeoff.
95  if (str)
96  {
97  if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)
98  OVR_sprintf(str, 64, "%.0f", d);
99  else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)
100  OVR_sprintf(str, 64, "%e", d);
101  else
102  OVR_sprintf(str, 64, "%f", d);
103  }
104  }
105  return str;
106 }
107 
108 // Parse the input text into an un-escaped cstring, and populate item.
109 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
110 
111 // Helper to assign error sting and return 0.
112 const char* AssignError(const char** perror, const char *errorMessage)
113 {
114  if (perror)
115  *perror = errorMessage;
116  return 0;
117 }
118 
119 //-----------------------------------------------------------------------------
120 // ***** JSON Node class
121 
123  : Type(itemType), dValue(0.0)
124 {
125 }
126 
128 {
129  JSON* child = Children.GetFirst();
130  while (!Children.IsNull(child))
131  {
132  child->RemoveNode();
133  child->Release();
134  child = Children.GetFirst();
135  }
136 }
137 
138 //-----------------------------------------------------------------------------
139 // Parse the input text to generate a number, and populate the result into item
140 // Returns the text position after the parsed number
141 const char* JSON::parseNumber(const char *num)
142 {
143  const char* num_start = num;
144  double n=0, sign=1, scale=0;
145  int subscale = 0,
146  signsubscale = 1;
147 
148  // Could use sscanf for this?
149  if (*num=='-')
150  sign=-1,num++; // Has sign?
151  if (*num=='0')
152  num++; // is zero
153 
154  if (*num>='1' && *num<='9')
155  {
156  do
157  {
158  n=(n*10.0)+(*num++ -'0');
159  }
160  while (*num>='0' && *num<='9'); // Number?
161  }
162 
163  if (*num=='.' && num[1]>='0' && num[1]<='9')
164  {
165  num++;
166  do
167  {
168  n=(n*10.0)+(*num++ -'0');
169  scale--;
170  }
171  while (*num>='0' && *num<='9'); // Fractional part?
172  }
173 
174  if (*num=='e' || *num=='E') // Exponent?
175  {
176  num++;
177  if (*num=='+')
178  num++;
179  else if (*num=='-')
180  {
181  signsubscale=-1;
182  num++; // With sign?
183  }
184 
185  while (*num>='0' && *num<='9')
186  subscale=(subscale*10)+(*num++ - '0'); // Number?
187  }
188 
189  // Number = +/- number.fraction * 10^+/- exponent
190  n = sign*n*pow(10.0,(scale+subscale*signsubscale));
191 
192  // Assign parsed value.
193  Type = JSON_Number;
194  dValue = n;
195  Value.AssignString(num_start, num - num_start);
196 
197  return num;
198 }
199 
200 // Parses a hex string up to the specified number of digits.
201 // Returns the first character after the string.
202 const char* ParseHex(unsigned* val, unsigned digits, const char* str)
203 {
204  *val = 0;
205 
206  for(unsigned digitCount = 0; digitCount < digits; digitCount++, str++)
207  {
208  unsigned v = *str;
209 
210  if ((v >= '0') && (v <= '9'))
211  v -= '0';
212  else if ((v >= 'a') && (v <= 'f'))
213  v = 10 + v - 'a';
214  else if ((v >= 'A') && (v <= 'F'))
215  v = 10 + v - 'A';
216  else
217  break;
218 
219  *val = *val * 16 + v;
220  }
221 
222  return str;
223 }
224 
225 //-----------------------------------------------------------------------------
226 // Parses the input text into a string item and returns the text position after
227 // the parsed string
228 const char* JSON::parseString(const char* str, const char** perror)
229 {
230  const char* ptr = str+1;
231  const char* p;
232  char* ptr2;
233  char* out;
234  int len=0;
235  unsigned uc, uc2;
236 
237  if (*str!='\"')
238  {
239  return AssignError(perror, "Syntax Error: Missing quote");
240  }
241 
242  while (*ptr!='\"' && *ptr && ++len)
243  {
244  if (*ptr++ == '\\') ptr++; // Skip escaped quotes.
245  }
246 
247  // This is how long we need for the string, roughly.
248  out=(char*)OVR_ALLOC(len+1);
249  if (!out)
250  return 0;
251 
252  ptr = str+1;
253  ptr2= out;
254 
255  while (*ptr!='\"' && *ptr)
256  {
257  if (*ptr!='\\')
258  {
259  *ptr2++ = *ptr++;
260  }
261  else
262  {
263  ptr++;
264  switch (*ptr)
265  {
266  case 'b': *ptr2++ = '\b'; break;
267  case 'f': *ptr2++ = '\f'; break;
268  case 'n': *ptr2++ = '\n'; break;
269  case 'r': *ptr2++ = '\r'; break;
270  case 't': *ptr2++ = '\t'; break;
271 
272  // Transcode utf16 to utf8.
273  case 'u':
274 
275  // Get the unicode char.
276  p = ParseHex(&uc, 4, ptr + 1);
277  if (ptr != p)
278  ptr = p - 1;
279 
280  if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)
281  break; // Check for invalid.
282 
283  // UTF16 surrogate pairs.
284  if (uc>=0xD800 && uc<=0xDBFF)
285  {
286  if (ptr[1]!='\\' || ptr[2]!='u')
287  break; // Missing second-half of surrogate.
288 
289  p= ParseHex(&uc2, 4, ptr + 3);
290  if (ptr != p)
291  ptr = p - 1;
292 
293  if (uc2<0xDC00 || uc2>0xDFFF)
294  break; // Invalid second-half of surrogate.
295 
296  uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
297  }
298 
299  len=4;
300 
301  if (uc<0x80)
302  len=1;
303  else if (uc<0x800)
304  len=2;
305  else if (uc<0x10000)
306  len=3;
307 
308  ptr2+=len;
309 
310  switch (len)
311  {
312  case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
313  case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
314  case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
315  case 1: *--ptr2 = (char)(uc | firstByteMark[len]);
316  }
317  ptr2+=len;
318  break;
319 
320  default:
321  *ptr2++ = *ptr;
322  break;
323  }
324  ptr++;
325  }
326  }
327 
328  *ptr2 = 0;
329  if (*ptr=='\"')
330  ptr++;
331 
332  // Make a copy of the string
333  Value=out;
334  OVR_FREE(out);
336 
337  return ptr;
338 }
339 
340 //-----------------------------------------------------------------------------
341 // Render the string provided to an escaped version that can be printed.
342 char* PrintString(const char* str)
343 {
344  const char *ptr;
345  char *ptr2,*out;
346  int len=0;
347  unsigned char token;
348 
349  if (!str)
350  return JSON_strdup("");
351  ptr=str;
352 
353  token=*ptr;
354  while (token && ++len)\
355  {
356  if (strchr("\"\\\b\f\n\r\t",token))
357  len++;
358  else if (token<32)
359  len+=5;
360  ptr++;
361  token=*ptr;
362  }
363 
364  int buff_size = len+3;
365  out=(char*)OVR_ALLOC(buff_size);
366  if (!out)
367  return 0;
368 
369  ptr2 = out;
370  ptr = str;
371  *ptr2++ = '\"';
372 
373  while (*ptr)
374  {
375  if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\')
376  *ptr2++=*ptr++;
377  else
378  {
379  *ptr2++='\\';
380  switch (token=*ptr++)
381  {
382  case '\\': *ptr2++='\\'; break;
383  case '\"': *ptr2++='\"'; break;
384  case '\b': *ptr2++='b'; break;
385  case '\f': *ptr2++='f'; break;
386  case '\n': *ptr2++='n'; break;
387  case '\r': *ptr2++='r'; break;
388  case '\t': *ptr2++='t'; break;
389  default:
390  OVR_sprintf(ptr2, buff_size - (ptr2-out), "u%04x",token);
391  ptr2+=5;
392  break; // Escape and print.
393  }
394  }
395  }
396  *ptr2++='\"';
397  *ptr2++=0;
398  return out;
399 }
400 
401 //-----------------------------------------------------------------------------
402 // Utility to jump whitespace and cr/lf
403 static const char* skip(const char* in)
404 {
405  while (in && *in && (unsigned char)*in<=' ')
406  in++;
407  return in;
408 }
409 
410 //-----------------------------------------------------------------------------
411 // Parses the supplied buffer of JSON text and returns a JSON object tree
412 // The returned object must be Released after use
413 JSON* JSON::Parse(const char* buff, const char** perror)
414 {
415  const char* end = 0;
416  JSON* json = new JSON();
417 
418  if (!json)
419  {
420  AssignError(perror, "Error: Failed to allocate memory");
421  return 0;
422  }
423 
424  end = json->parseValue(skip(buff), perror);
425  if (!end)
426  {
427  json->Release();
428  return NULL;
429  } // parse failure. ep is set.
430 
431  return json;
432 }
433 
434 //-----------------------------------------------------------------------------
435 // This version works for buffers that are not null terminated strings.
436 JSON* JSON::ParseBuffer(const char *buff, int len, const char** perror)
437 {
438  // Our JSON parser does not support length-based parsing,
439  // so ensure it is null-terminated.
440  char *termStr = new char[len + 1];
441  memcpy(termStr, buff, len);
442  termStr[len] = '\0';
443 
444  JSON *objJson = Parse(termStr, perror);
445 
446  delete[]termStr;
447 
448  return objJson;
449 }
450 
451 //-----------------------------------------------------------------------------
452 // Parser core - when encountering text, process appropriately.
453 const char* JSON::parseValue(const char* buff, const char** perror)
454 {
455  if (perror)
456  *perror = 0;
457 
458  if (!buff)
459  return NULL; // Fail on null.
460 
461  if (!strncmp(buff,"null",4))
462  {
463  Type = JSON_Null;
464  return buff+4;
465  }
466  if (!strncmp(buff,"false",5))
467  {
468  Type = JSON_Bool;
469  Value = "false";
470  dValue = 0;
471  return buff+5;
472  }
473  if (!strncmp(buff,"true",4))
474  {
475  Type = JSON_Bool;
476  Value = "true";
477  dValue = 1;
478  return buff+4;
479  }
480  if (*buff=='\"')
481  {
482  return parseString(buff, perror);
483  }
484  if (*buff=='-' || (*buff>='0' && *buff<='9'))
485  {
486  return parseNumber(buff);
487  }
488  if (*buff=='[')
489  {
490  return parseArray(buff, perror);
491  }
492  if (*buff=='{')
493  {
494  return parseObject(buff, perror);
495  }
496 
497  return AssignError(perror, "Syntax Error: Invalid syntax");
498 }
499 
500 
501 //-----------------------------------------------------------------------------
502 // Render a value to text.
503 char* JSON::PrintValue(int depth, bool fmt)
504 {
505  char *out=0;
506 
507  switch (Type)
508  {
509  case JSON_Null: out = JSON_strdup("null"); break;
510  case JSON_Bool:
511  if (dValue == 0)
512  out = JSON_strdup("false");
513  else
514  out = JSON_strdup("true");
515  break;
516  case JSON_Number: out = PrintNumber(dValue); break;
517  case JSON_String: out = PrintString(Value); break;
518  case JSON_Array: out = PrintArray(depth, fmt); break;
519  case JSON_Object: out = PrintObject(depth, fmt); break;
520  case JSON_None: OVR_ASSERT_LOG(false, ("Bad JSON type.")); break;
521  }
522  return out;
523 }
524 
525 //-----------------------------------------------------------------------------
526 // Build an array object from input text and returns the text position after
527 // the parsed array
528 const char* JSON::parseArray(const char* buff, const char** perror)
529 {
530  JSON *child;
531  if (*buff!='[')
532  {
533  return AssignError(perror, "Syntax Error: Missing opening bracket");
534  }
535 
537  buff=skip(buff+1);
538 
539  if (*buff==']')
540  return buff+1; // empty array.
541 
542  child = new JSON();
543  if (!child)
544  return 0; // memory fail
545  Children.PushBack(child);
546 
547  buff=skip(child->parseValue(skip(buff), perror)); // skip any spacing, get the buff.
548  if (!buff)
549  return 0;
550 
551  while (*buff==',')
552  {
553  JSON *new_item = new JSON();
554  if (!new_item)
555  return AssignError(perror, "Error: Failed to allocate memory");
556 
557  Children.PushBack(new_item);
558 
559  buff=skip(new_item->parseValue(skip(buff+1), perror));
560  if (!buff)
561  return AssignError(perror, "Error: Failed to allocate memory");
562  }
563 
564  if (*buff==']')
565  return buff+1; // end of array
566 
567  return AssignError(perror, "Syntax Error: Missing ending bracket");
568 }
569 
570 //-----------------------------------------------------------------------------
571 // Render an array to text. The returned text must be freed
572 char* JSON::PrintArray(int depth, bool fmt)
573 {
574  char **entries;
575  char * out = 0,*ptr,*ret;
576  SPInt len = 5;
577 
578  bool fail = false;
579 
580  // How many entries in the array?
581  int numentries = GetItemCount();
582  if (!numentries)
583  {
584  out=(char*)OVR_ALLOC(3);
585  if (out)
586  OVR_strcpy(out, 3, "[]");
587  return out;
588  }
589  // Allocate an array to hold the values for each
590  entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
591  if (!entries)
592  return 0;
593  memset(entries,0,numentries*sizeof(char*));
594 
596  JSON* child = Children.GetFirst();
597  for (int i=0; i<numentries; i++)
598  {
599  //JSON* child = Children[i];
600  ret=child->PrintValue(depth+1, fmt);
601  entries[i]=ret;
602  if (ret)
603  len+=OVR_strlen(ret)+2+(fmt?1:0);
604  else
605  {
606  fail = true;
607  break;
608  }
609  child = Children.GetNext(child);
610  }
611 
612  // If we didn't fail, try to malloc the output string
613  if (!fail)
614  out=(char*)OVR_ALLOC(len);
615  // If that fails, we fail.
616  if (!out)
617  fail = true;
618 
619  // Handle failure.
620  if (fail)
621  {
622  for (int i=0; i<numentries; i++)
623  {
624  if (entries[i])
625  OVR_FREE(entries[i]);
626  }
627  OVR_FREE(entries);
628  return 0;
629  }
630 
631  // Compose the output array.
632  *out='[';
633  ptr=out+1;
634  *ptr=0;
635  for (int i=0; i<numentries; i++)
636  {
637  OVR_strcpy(ptr, len - (ptr-out), entries[i]);
638  ptr+=OVR_strlen(entries[i]);
639  if (i!=numentries-1)
640  {
641  *ptr++=',';
642  if (fmt)
643  *ptr++=' ';
644  *ptr=0;
645  }
646  OVR_FREE(entries[i]);
647  }
648  OVR_FREE(entries);
649  *ptr++=']';
650  *ptr++=0;
651  return out;
652 }
653 
654 //-----------------------------------------------------------------------------
655 // Build an object from the supplied text and returns the text position after
656 // the parsed object
657 const char* JSON::parseObject(const char* buff, const char** perror)
658 {
659  if (*buff!='{')
660  {
661  return AssignError(perror, "Syntax Error: Missing opening brace");
662  }
663 
665  buff=skip(buff+1);
666  if (*buff=='}')
667  return buff+1; // empty array.
668 
669  JSON* child = new JSON();
670  Children.PushBack(child);
671 
672  buff=skip(child->parseString(skip(buff), perror));
673  if (!buff)
674  return 0;
675  child->Name = child->Value;
676  child->Value.Clear();
677 
678  if (*buff!=':')
679  {
680  return AssignError(perror, "Syntax Error: Missing colon");
681  }
682 
683  buff=skip(child->parseValue(skip(buff+1), perror)); // skip any spacing, get the value.
684  if (!buff)
685  return 0;
686 
687  while (*buff==',')
688  {
689  child = new JSON();
690  if (!child)
691  return 0; // memory fail
692 
693  Children.PushBack(child);
694 
695  buff=skip(child->parseString(skip(buff+1), perror));
696  if (!buff)
697  return 0;
698 
699  child->Name=child->Value;
700  child->Value.Clear();
701 
702  if (*buff!=':')
703  {
704  return AssignError(perror, "Syntax Error: Missing colon");
705  } // fail!
706 
707  // Skip any spacing, get the value.
708  buff=skip(child->parseValue(skip(buff+1), perror));
709  if (!buff)
710  return 0;
711  }
712 
713  if (*buff=='}')
714  return buff+1; // end of array
715 
716  return AssignError(perror, "Syntax Error: Missing closing brace");
717 }
718 
719 //-----------------------------------------------------------------------------
720 // Render an object to text. The returned string must be freed
721 char* JSON::PrintObject(int depth, bool fmt)
722 {
723  char** entries = 0, **names = 0;
724  char* out = 0;
725  char* ptr, *ret, *str;
726  SPInt len = 7, i = 0, j;
727  bool fail = false;
728 
729  // Count the number of entries.
730  int numentries = GetItemCount();
731 
732  // Explicitly handle empty object case
733  if (numentries == 0)
734  {
735  out=(char*)OVR_ALLOC(fmt?depth+3:3);
736  if (!out)
737  return 0;
738  ptr=out;
739  *ptr++='{';
740 
741  if (fmt)
742  {
743  *ptr++='\n';
744  for (i=0;i<depth-1;i++)
745  *ptr++='\t';
746  }
747  *ptr++='}';
748  *ptr++=0;
749  return out;
750  }
751  // Allocate space for the names and the objects
752  entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
753  if (!entries)
754  return 0;
755  names=(char**)OVR_ALLOC(numentries*sizeof(char*));
756 
757  if (!names)
758  {
759  OVR_FREE(entries);
760  return 0;
761  }
762  memset(entries,0,sizeof(char*)*numentries);
763  memset(names,0,sizeof(char*)*numentries);
764 
765  // Collect all the results into our arrays:
766  depth++;
767  if (fmt)
768  len+=depth;
769 
770  JSON* child = Children.GetFirst();
771  while (!Children.IsNull(child))
772  {
773  names[i] = str = PrintString(child->Name);
774  entries[i++] = ret = child->PrintValue(depth, fmt);
775 
776  if (str && ret)
777  {
778  len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?2+depth:0);
779  }
780  else
781  {
782  fail = true;
783  break;
784  }
785 
786  child = Children.GetNext(child);
787  }
788 
789  // Try to allocate the output string
790  if (!fail)
791  out=(char*)OVR_ALLOC(len);
792  if (!out)
793  fail=true;
794 
795  // Handle failure
796  if (fail)
797  {
798  for (i=0;i<numentries;i++)
799  {
800  if (names[i])
801  OVR_FREE(names[i]);
802 
803  if (entries[i])
804  OVR_FREE(entries[i]);}
805 
806  OVR_FREE(names);
807  OVR_FREE(entries);
808  return 0;
809  }
810 
811  // Compose the output:
812  *out = '{';
813  ptr = out+1;
814  if (fmt)
815  *ptr++='\n';
816  *ptr = 0;
817 
818  for (i=0; i<numentries; i++)
819  {
820  if (fmt)
821  {
822  for (j=0; j<depth; j++)
823  *ptr++ = '\t';
824  }
825  OVR_strcpy(ptr, len - (ptr-out), names[i]);
826  ptr += OVR_strlen(names[i]);
827  *ptr++ =':';
828 
829  if (fmt)
830  *ptr++='\t';
831 
832  OVR_strcpy(ptr, len - (ptr-out), entries[i]);
833  ptr+=OVR_strlen(entries[i]);
834 
835  if (i!=numentries-1)
836  *ptr++ = ',';
837 
838  if (fmt)
839  *ptr++ = '\n';
840  *ptr = 0;
841 
842  OVR_FREE(names[i]);
843  OVR_FREE(entries[i]);
844  }
845 
846  OVR_FREE(names);
847  OVR_FREE(entries);
848 
849  if (fmt)
850  {
851  for (i=0;i<depth-1;i++)
852  *ptr++='\t';
853  }
854  *ptr++='}';
855  *ptr++=0;
856 
857  return out;
858 }
859 
860 
861 
862 // Returns the number of child items in the object
863 // Counts the number of items in the object.
864 unsigned JSON::GetItemCount() const
865 {
866  unsigned count = 0;
867  for(const JSON* p = Children.GetFirst(); !Children.IsNull(p); p = p->pNext)
868  count++;
869  return count;
870 }
871 
873 {
874  unsigned i = 0;
875  JSON* child = 0;
876 
877  if (!Children.IsEmpty())
878  {
879  child = Children.GetFirst();
880 
881  while (i < index)
882  {
883  if (Children.IsNull(child->pNext))
884  {
885  child = 0;
886  break;
887  }
888  child = child->pNext;
889  i++;
890  }
891  }
892 
893  return child;
894 }
895 
896 // Returns the child item with the given name or NULL if not found
897 JSON* JSON::GetItemByName(const char* name)
898 {
899  JSON* child = 0;
900 
901  if (!Children.IsEmpty())
902  {
903  child = Children.GetFirst();
904 
905  while (OVR_strcmp(child->Name, name) != 0)
906  {
907  if (Children.IsNull(child->pNext))
908  {
909  child = 0;
910  break;
911  }
912  child = child->pNext;
913  }
914  }
915 
916  return child;
917 }
918 
919 //-----------------------------------------------------------------------------
920 // Adds a new item to the end of the child list
921 void JSON::AddItem(const char *string, JSON *item)
922 {
923  if (!item)
924  return;
925 
926  item->Name = string;
927  Children.PushBack(item);
928 }
929 
930 /*
931 
932 // Removes and frees the items at the given index
933 void JSON::DeleteItem(unsigned int index)
934 {
935  unsigned int num_items = 0;
936  JSON* child = Children.GetFirst();
937  while (!Children.IsNull(child) && num_items < index)
938  {
939  num_items++;
940  child = Children.GetNext(child);
941  }
942 
943  if (!Children.IsNull(child))
944 
945  child->RemoveNode();
946  child->Release();
947  }
948 }
949 
950 // Replaces and frees the item at the give index with the new item
951 void JSON::ReplaceItem(unsigned int index, JSON* new_item)
952 {
953  unsigned int num_items = 0;
954  JSON* child = Children.GetFirst();
955  while (!Children.IsNull(child) && num_items < index)
956  {
957  num_items++;
958  child = Children.GetNext(child);
959  }
960 
961  if (!Children.IsNull(child))
962  {
963  child->ReplaceNodeWith(new_item);
964  child->Release();
965  }
966 }
967 */
968 
969 // Removes and frees the last child item
971 {
972  JSON* child = Children.GetLast();
973  if (!Children.IsNull(child))
974  {
975  child->RemoveNode();
976  child->Release();
977  }
978 }
979 
980 // Helper function to simplify creation of a typed object
981 JSON* JSON::createHelper(JSONItemType itemType, double dval, const char* strVal)
982 {
983  JSON *item = new JSON(itemType);
984  if (item)
985  {
986  item->dValue = dval;
987  if (strVal)
988  item->Value = strVal;
989  }
990  return item;
991 }
992 
993 //-----------------------------------------------------------------------------
994 // Get elements by name
995 double JSON::GetNumberByName(const char *name, double defValue)
996 {
997  JSON* item = GetItemByName(name);
998  if (!item || item->Type != JSON_Number) {
999  return defValue;
1000  }
1001  else {
1002  return item->dValue;
1003  }
1004 }
1005 
1006 int JSON::GetIntByName(const char *name, int defValue)
1007 {
1008  JSON* item = GetItemByName(name);
1009  if (!item || item->Type != JSON_Number) {
1010  return defValue;
1011  }
1012  else {
1013  return (int)item->dValue;
1014  }
1015 }
1016 
1017 bool JSON::GetBoolByName(const char *name, bool defValue)
1018 {
1019  JSON* item = GetItemByName(name);
1020  if (!item || item->Type != JSON_Bool) {
1021  return defValue;
1022  }
1023  else {
1024  return (int)item->dValue != 0;
1025  }
1026 }
1027 
1028 String JSON::GetStringByName(const char *name, const String &defValue)
1029 {
1030  JSON* item = GetItemByName(name);
1031  if (!item || item->Type != JSON_String) {
1032  return defValue;
1033  }
1034  else {
1035  return item->Value;
1036  }
1037 }
1038 
1039 //-----------------------------------------------------------------------------
1040 // Adds an element to an array object type
1042 {
1043  if (!item)
1044  return;
1045 
1046  Children.PushBack(item);
1047 }
1048 
1049 // Inserts an element into a valid array position
1051 {
1052  if (!item)
1053  return;
1054 
1055  if (index == 0)
1056  {
1057  Children.PushFront(item);
1058  return;
1059  }
1060 
1061  JSON* iter = Children.GetFirst();
1062  int i=0;
1063  while (iter && i<index)
1064  {
1065  iter = Children.GetNext(iter);
1066  i++;
1067  }
1068 
1069  if (iter)
1070  iter->InsertNodeBefore(item);
1071  else
1072  Children.PushBack(item);
1073 }
1074 
1075 // Returns the size of an array
1077 {
1078  if (Type == JSON_Array)
1079  return GetItemCount();
1080  else
1081  return 0;
1082 }
1083 
1084 // Returns the number value an the give array index
1086 {
1087  if (Type == JSON_Array)
1088  {
1089  JSON* number = GetItemByIndex(index);
1090  return number ? number->dValue : 0.0;
1091  }
1092  else
1093  {
1094  return 0;
1095  }
1096 }
1097 
1098 // Returns the string value at the given array index
1099 const char* JSON::GetArrayString(int index)
1100 {
1101  if (Type == JSON_Array)
1102  {
1103  JSON* number = GetItemByIndex(index);
1104  return number ? number->Value : 0;
1105  }
1106  else
1107  {
1108  return 0;
1109  }
1110 }
1111 
1113 {
1114  JSON* copy = new JSON(Type);
1115  copy->Name = Name;
1116  copy->Value = Value;
1117  copy->dValue = dValue;
1118 
1119  JSON* child = Children.GetFirst();
1120  while (!Children.IsNull(child))
1121  {
1122  copy->Children.PushBack(child->Copy());
1123  child = Children.GetNext(child);
1124  }
1125 
1126  return copy;
1127 }
1128 
1129 //-----------------------------------------------------------------------------
1130 // Loads and parses the given JSON file pathname and returns a JSON object tree.
1131 // The returned object must be Released after use.
1132 JSON* JSON::Load(const char* path, const char** perror)
1133 {
1134  SysFile f;
1135  if (!f.Open(path, File::Open_Read, File::Mode_Read))
1136  {
1137  AssignError(perror, "Failed to open file");
1138  return NULL;
1139  }
1140 
1141  int len = f.GetLength();
1142  UByte* buff = (UByte*)OVR_ALLOC(len + 1);
1143  int bytes = f.Read(buff, len);
1144  f.Close();
1145 
1146  if (bytes == 0 || bytes != len)
1147  {
1148  OVR_FREE(buff);
1149  return NULL;
1150  }
1151 
1152  // Ensure the result is null-terminated since Parse() expects null-terminated input.
1153  buff[len] = '\0';
1154 
1155  JSON* json = JSON::Parse((char*)buff, perror);
1156  OVR_FREE(buff);
1157  return json;
1158 }
1159 
1160 //-----------------------------------------------------------------------------
1161 // Serializes the JSON object and writes to the give file path
1162 bool JSON::Save(const char* path)
1163 {
1164  SysFile f;
1166  return false;
1167 
1168  char* text = PrintValue(0, true);
1169  if (text)
1170  {
1171  SPInt len = OVR_strlen(text);
1172  OVR_ASSERT(len <= (SPInt)(int)len);
1173 
1174  int bytes = f.Write((UByte*)text, (int)len);
1175  f.Close();
1176  OVR_FREE(text);
1177  return (bytes == len);
1178  }
1179  else
1180  {
1181  return false;
1182  }
1183 }
1184 
1185 }
double GetArrayNumber(int index)
Definition: OVR_JSON.cpp:1085
static JSON * createHelper(JSONItemType itemType, double dval, const char *strVal=0)
Definition: OVR_JSON.cpp:981
virtual int GetLength()
Definition: OVR_File.h:299
bool Save(const char *path)
Definition: OVR_JSON.cpp:1162
#define OVR_ASSERT_LOG(c, args)
Definition: OVR_Log.h:198
int GetArraySize()
Definition: OVR_JSON.cpp:1076
unsigned GetItemCount() const
Definition: OVR_JSON.cpp:864
#define DBL_EPSILON
__BEGIN_NAMESPACE_STD void * memcpy(void *__restrict __dest, const void *__restrict __src, size_t __n) __THROW __nonnull((1
int GetIntByName(const char *name, int defValue=0)
Definition: OVR_JSON.cpp:1006
char * PrintValue(int depth, bool fmt)
Definition: OVR_JSON.cpp:503
static const unsigned char firstByteMark[7]
Definition: OVR_JSON.cpp:109
static char * PrintNumber(double d)
Definition: OVR_JSON.cpp:81
void InsertArrayElement(int index, JSON *item)
Definition: OVR_JSON.cpp:1050
List< JSON > Children
Definition: OVR_JSON.h:61
static JSON * ParseBuffer(const char *buff, int len, const char **perror=0)
Definition: OVR_JSON.cpp:436
const char * parseString(const char *str, const char **perror)
Definition: OVR_JSON.cpp:228
const char * parseValue(const char *buff, const char **perror)
Definition: OVR_JSON.cpp:453
double GetNumberByName(const char *name, double defValue=0.0)
Definition: OVR_JSON.cpp:995
char * PrintString(const char *str)
Definition: OVR_JSON.cpp:342
String Name
Definition: OVR_JSON.h:65
size_t UPInt
Definition: OVR_Types.h:218
virtual int Read(UByte *pbuffer, int numBytes)
Definition: OVR_File.h:308
uint8_t UByte
Definition: OVR_Types.h:249
String Value
Definition: OVR_JSON.h:66
void Clear()
Definition: OVR_String.cpp:386
char *OVR_CDECL OVR_strcpy(char *dest, UPInt destsize, const char *src)
Definition: OVR_Std.h:148
const char * GetArrayString(int index)
Definition: OVR_JSON.cpp:1099
void RemoveNode()
Definition: OVR_List.h:58
const char * ParseHex(unsigned *val, unsigned digits, const char *str)
Definition: OVR_JSON.cpp:202
static JSON * Parse(const char *buff, const char **perror=0)
Definition: OVR_JSON.cpp:413
static const char * skip(const char *in)
Definition: OVR_JSON.cpp:403
String GetStringByName(const char *name, const String &defValue="")
Definition: OVR_JSON.cpp:1028
JSONItemType Type
Definition: OVR_JSON.h:64
static JSON * Load(const char *path, const char **perror=0)
Definition: OVR_JSON.cpp:1132
virtual int Write(const UByte *pbuffer, int numBytes)
Definition: OVR_File.h:307
__BEGIN_NAMESPACE_STD char * strchr(const char *__s, int __c) __THROW __attribute_pure__ __nonnull((1))
#define OVR_ASSERT(p)
__END_NAMESPACE_STD __BEGIN_NAMESPACE_STD char char char char int int strncmp(const char *__s1, const char *__s2, size_t __n) __THROW __attribute_pure__ __nonnull((1
const char * parseObject(const char *value, const char **perror)
Definition: OVR_JSON.cpp:657
void AddArrayElement(JSON *item)
Definition: OVR_JSON.cpp:1041
void AddItem(const char *string, JSON *item)
Definition: OVR_JSON.cpp:921
void RemoveLast()
Definition: OVR_JSON.cpp:970
JSON * GetItemByIndex(unsigned i)
Definition: OVR_JSON.cpp:872
int OVR_CDECL OVR_strcmp(const char *dest, const char *src)
Definition: OVR_Std.h:181
void InsertNodeBefore(T *p)
Definition: OVR_List.h:82
bool Open(const String &path, int flags=Open_Read|Open_Buffered, int mode=Mode_ReadWrite)
Definition: OVR_SysFile.cpp:98
ptrdiff_t SPInt
Definition: OVR_Types.h:219
__BEGIN_NAMESPACE_STD void void __END_NAMESPACE_STD void __BEGIN_NAMESPACE_STD void * memset(void *__s, int __c, size_t __n) __THROW __nonnull((1))
const char * parseNumber(const char *num)
Definition: OVR_JSON.cpp:141
UPInt OVR_CDECL OVR_sprintf(char *dest, UPInt destsize, const char *format,...)
Definition: OVR_Std.h:280
int char * index(const char *__s, int __c) __THROW __attribute_pure__ __nonnull((1))
char * PrintArray(int depth, bool fmt)
Definition: OVR_JSON.cpp:572
char * PrintObject(int depth, bool fmt)
Definition: OVR_JSON.cpp:721
#define OVR_ALLOC(s)
virtual bool Close()
double dValue
Definition: OVR_JSON.h:67
const char * parseArray(const char *value, const char **perror)
Definition: OVR_JSON.cpp:528
#define OVR_FREE(p)
const char * AssignError(const char **perror, const char *errorMessage)
Definition: OVR_JSON.cpp:112
UPInt OVR_CDECL OVR_strlen(const char *str)
Definition: OVR_Std.h:143
void AssignString(const InitStruct &src, UPInt size)
Definition: OVR_String.cpp:264
static char * JSON_strdup(const char *str)
Definition: OVR_JSON.cpp:68
JSONItemType
Definition: OVR_JSON.h:40
JSON * GetItemByName(const char *name)
Definition: OVR_JSON.cpp:897
JSON * Copy()
Definition: OVR_JSON.cpp:1112
JSON(JSONItemType itemType=JSON_Object)
Definition: OVR_JSON.cpp:122
bool GetBoolByName(const char *name, bool defValue=false)
Definition: OVR_JSON.cpp:1017