aboutsummaryrefslogtreecommitdiffstats
path: root/LibOVR/Src/OVR_JSON.cpp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-03-28 01:43:35 +0100
committerSven Gothel <[email protected]>2015-03-28 01:43:35 +0100
commit4207f9c279e832e3afcb3f5fc6cd8d84cb4cfe4c (patch)
treecf3671058d55b47ab6cb6f36f369928606137628 /LibOVR/Src/OVR_JSON.cpp
parentc29cd1a2fbff6282bab956ad61661ac9d48c4e6e (diff)
Bump OculusVR RIFT SDK to 0.5.0.1vanilla_0.5.0.1
Diffstat (limited to 'LibOVR/Src/OVR_JSON.cpp')
-rw-r--r--LibOVR/Src/OVR_JSON.cpp1287
1 files changed, 0 insertions, 1287 deletions
diff --git a/LibOVR/Src/OVR_JSON.cpp b/LibOVR/Src/OVR_JSON.cpp
deleted file mode 100644
index 7b40fb1..0000000
--- a/LibOVR/Src/OVR_JSON.cpp
+++ /dev/null
@@ -1,1287 +0,0 @@
-/************************************************************************************
-
-PublicHeader: None
-Filename : OVR_JSON.h
-Content : JSON format reader and writer
-Created : April 9, 2013
-Author : Brant Lewis
-Notes :
- The code is a derivative of the cJSON library written by Dave Gamble and subject
- to the following permissive copyright.
-
- Copyright (c) 2009 Dave Gamble
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
-
-Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
-
-Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
-you may not use the Oculus VR Rift SDK except in compliance with the License,
-which is provided at the time of installation or download, or which
-otherwise accompanies this software in either electronic or hard copy form.
-
-You may obtain a copy of the License at
-
-http://www.oculusvr.com/licenses/LICENSE-3.2
-
-Unless required by applicable law or agreed to in writing, the Oculus VR SDK
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-************************************************************************************/
-
-#include <string.h>
-#include <stdio.h>
-#include <math.h>
-#include <stdlib.h>
-#include <float.h>
-#include <limits.h>
-#include <ctype.h>
-#include "OVR_JSON.h"
-#include "Kernel/OVR_SysFile.h"
-#include "Kernel/OVR_Log.h"
-
-#ifdef OVR_OS_LINUX
-#include <locale.h>
-#endif
-
-namespace OVR {
-
-
-//-----------------------------------------------------------------------------
-// Create a new copy of a string
-static char* JSON_strdup(const char* str)
-{
- size_t len = OVR_strlen(str) + 1;
- char* copy = (char*)OVR_ALLOC(len);
- if (!copy)
- return 0;
- memcpy(copy, str, len);
- return copy;
-}
-
-
-//-----------------------------------------------------------------------------
-// Render the number from the given item into a string.
-static char* PrintInt(int valueint)
-{
- char *str;
- str = (char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars.
- if (str)
- {
- OVR_sprintf(str, 21, "%d", valueint);
- }
- return str;
-}
-
-
-//-----------------------------------------------------------------------------
-// Render the number from the given item into a string.
-static char* PrintNumber(double d)
-{
- char *str;
- int valueint = (int)d;
- if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
- {
- return PrintInt(valueint);
- }
- else
- {
- str=(char*)OVR_ALLOC(64); // This is a nice tradeoff.
- if (str)
- {
- if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)
- OVR_sprintf(str, 64, "%.0f", d);
- else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)
- OVR_sprintf(str, 64, "%e", d);
- else
- OVR_sprintf(str, 64, "%f", d);
- }
- }
- return str;
-}
-
-
-// Parse the input text into an un-escaped cstring, and populate item.
-static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
-
-// Helper to assign error sting and return 0.
-const char* AssignError(const char** perror, const char *errorMessage)
-{
- if (perror)
- *perror = errorMessage;
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-// ***** JSON Node class
-
-JSON::JSON(JSONItemType itemType) :
- Type(itemType), dValue(0.)
-{
-}
-
-JSON::~JSON()
-{
- JSON* child = Children.GetFirst();
- while (!Children.IsNull(child))
- {
- child->RemoveNode();
- child->Release();
- child = Children.GetFirst();
- }
-}
-
-//-----------------------------------------------------------------------------
-// Parse the input text to generate a number, and populate the result into item
-// Returns the text position after the parsed number
-const char* JSON::parseNumber(const char *num)
-{
- const char* num_start = num;
- double n=0, scale=0;
- int subscale = 0,
- signsubscale = 1;
- bool positiveSign = true;
- char localeSeparator = '.';
-
-#ifdef OVR_OS_LINUX
- // We should switch to a locale aware parsing function, such as atof. We
- // will probably want to go farther and enforce the 'C' locale on all JSON
- // output/input.
- struct lconv* localeConv = localeconv();
- localeSeparator = localeConv->decimal_point[0];
-#endif
-
- // Could use sscanf for this?
- if (*num == '-')
- {
- positiveSign = false;
- num++; // Has sign?
- }
- if (*num == '0')
- {
- num++; // is zero
- }
-
- if (*num>='1' && *num<='9')
- {
- do
- {
- n = (n*10.0) + (*num++ - '0');
- }
- while (*num>='0' && *num<='9'); // Number?
- }
-
- if ((*num=='.' || *num==localeSeparator) && num[1]>='0' && num[1]<='9')
- {
- num++;
- do
- {
- n=(n*10.0)+(*num++ -'0');
- scale--;
- }
- while (*num>='0' && *num<='9'); // Fractional part?
- }
-
- if (*num=='e' || *num=='E') // Exponent?
- {
- num++;
- if (*num == '+')
- {
- num++;
- }
- else if (*num=='-')
- {
- signsubscale=-1;
- num++; // With sign?
- }
-
- while (*num >= '0' && *num <= '9')
- {
- subscale = (subscale * 10) + (*num++ - '0'); // Number?
- }
- }
-
- // Number = +/- number.fraction * 10^+/- exponent
- n *= pow(10.0, (scale + subscale*signsubscale));
-
- if (!positiveSign)
- {
- n = -n;
- }
-
- // Assign parsed value.
- Type = JSON_Number;
- dValue = n;
- Value.AssignString(num_start, num - num_start);
-
- return num;
-}
-
-// Parses a hex string up to the specified number of digits.
-// Returns the first character after the string.
-const char* ParseHex(unsigned* val, unsigned digits, const char* str)
-{
- *val = 0;
-
- for(unsigned digitCount = 0; digitCount < digits; digitCount++, str++)
- {
- unsigned v = *str;
-
- if ((v >= '0') && (v <= '9'))
- v -= '0';
- else if ((v >= 'a') && (v <= 'f'))
- v = 10 + v - 'a';
- else if ((v >= 'A') && (v <= 'F'))
- v = 10 + v - 'A';
- else
- break;
-
- *val = *val * 16 + v;
- }
-
- return str;
-}
-
-//-----------------------------------------------------------------------------
-// Parses the input text into a string item and returns the text position after
-// the parsed string
-const char* JSON::parseString(const char* str, const char** perror)
-{
- const char* ptr = str+1;
- const char* p;
- char* ptr2;
- char* out;
- int len=0;
- unsigned uc, uc2;
-
- if (*str!='\"')
- {
- return AssignError(perror, "Syntax Error: Missing quote");
- }
-
- while (*ptr!='\"' && *ptr && ++len)
- {
- if (*ptr++ == '\\') ptr++; // Skip escaped quotes.
- }
-
- // This is how long we need for the string, roughly.
- out=(char*)OVR_ALLOC(len+1);
- if (!out)
- return 0;
-
- ptr = str+1;
- ptr2= out;
-
- while (*ptr!='\"' && *ptr)
- {
- if (*ptr!='\\')
- {
- *ptr2++ = *ptr++;
- }
- else
- {
- ptr++;
- switch (*ptr)
- {
- case 'b': *ptr2++ = '\b'; break;
- case 'f': *ptr2++ = '\f'; break;
- case 'n': *ptr2++ = '\n'; break;
- case 'r': *ptr2++ = '\r'; break;
- case 't': *ptr2++ = '\t'; break;
-
- // Transcode utf16 to utf8.
- case 'u':
-
- // Get the unicode char.
- p = ParseHex(&uc, 4, ptr + 1);
- if (ptr != p)
- ptr = p - 1;
-
- if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)
- break; // Check for invalid.
-
- // UTF16 surrogate pairs.
- if (uc>=0xD800 && uc<=0xDBFF)
- {
- if (ptr[1]!='\\' || ptr[2]!='u')
- break; // Missing second-half of surrogate.
-
- p= ParseHex(&uc2, 4, ptr + 3);
- if (ptr != p)
- ptr = p - 1;
-
- if (uc2<0xDC00 || uc2>0xDFFF)
- break; // Invalid second-half of surrogate.
-
- uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
- }
-
- len=4;
-
- if (uc<0x80)
- len=1;
- else if (uc<0x800)
- len=2;
- else if (uc<0x10000)
- len=3;
-
- ptr2+=len;
-
- switch (len)
- {
- case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
- //no break, fall through
- case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
- //no break
- case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
- //no break
- case 1: *--ptr2 = (char)(uc | firstByteMark[len]);
- //no break
- }
- ptr2+=len;
- break;
-
- default:
- *ptr2++ = *ptr;
- break;
- }
- ptr++;
- }
- }
-
- *ptr2 = 0;
- if (*ptr=='\"')
- ptr++;
-
- // Make a copy of the string
- Value=out;
- OVR_FREE(out);
- Type=JSON_String;
-
- return ptr;
-}
-
-//-----------------------------------------------------------------------------
-// Render the string provided to an escaped version that can be printed.
-char* PrintString(const char* str)
-{
- const char *ptr;
- char *ptr2,*out;
- int len=0;
- unsigned char token;
-
- if (!str)
- return JSON_strdup("");
- ptr=str;
-
- token=*ptr;
- while (token && ++len)\
- {
- if (strchr("\"\\\b\f\n\r\t",token))
- len++;
- else if (token<32)
- len+=5;
- ptr++;
- token=*ptr;
- }
-
- int buff_size = len+3;
- out=(char*)OVR_ALLOC(buff_size);
- if (!out)
- return 0;
-
- ptr2 = out;
- ptr = str;
- *ptr2++ = '\"';
-
- while (*ptr)
- {
- if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\')
- *ptr2++=*ptr++;
- else
- {
- *ptr2++='\\';
- switch (token=*ptr++)
- {
- case '\\': *ptr2++='\\'; break;
- case '\"': *ptr2++='\"'; break;
- case '\b': *ptr2++='b'; break;
- case '\f': *ptr2++='f'; break;
- case '\n': *ptr2++='n'; break;
- case '\r': *ptr2++='r'; break;
- case '\t': *ptr2++='t'; break;
- default:
- OVR_sprintf(ptr2, buff_size - (ptr2-out), "u%04x",token);
- ptr2+=5;
- break; // Escape and print.
- }
- }
- }
- *ptr2++='\"';
- *ptr2++=0;
- return out;
-}
-
-//-----------------------------------------------------------------------------
-// Utility to jump whitespace and cr/lf
-static const char* skip(const char* in)
-{
- while (in && *in && (unsigned char)*in<=' ')
- in++;
- return in;
-}
-
-//-----------------------------------------------------------------------------
-// Parses the supplied buffer of JSON text and returns a JSON object tree
-// The returned object must be Released after use
-JSON* JSON::Parse(const char* buff, const char** perror)
-{
- const char* end = 0;
- JSON* json = new JSON();
-
- if (!json)
- {
- AssignError(perror, "Error: Failed to allocate memory");
- return 0;
- }
-
- end = json->parseValue(skip(buff), perror);
- if (!end)
- {
- json->Release();
- return NULL;
- } // parse failure. ep is set.
-
- return json;
-}
-
-//-----------------------------------------------------------------------------
-// This version works for buffers that are not null terminated strings.
-JSON* JSON::ParseBuffer(const char *buff, int len, const char** perror)
-{
- // Our JSON parser does not support length-based parsing,
- // so ensure it is null-terminated.
- char *termStr = new char[len + 1];
- memcpy(termStr, buff, len);
- termStr[len] = '\0';
-
- JSON *objJson = Parse(termStr, perror);
-
- delete[]termStr;
-
- return objJson;
-}
-
-//-----------------------------------------------------------------------------
-// Parser core - when encountering text, process appropriately.
-const char* JSON::parseValue(const char* buff, const char** perror)
-{
- if (perror)
- *perror = 0;
-
- if (!buff)
- return NULL; // Fail on null.
-
- if (!strncmp(buff,"null",4))
- {
- Type = JSON_Null;
- return buff+4;
- }
- if (!strncmp(buff,"false",5))
- {
- Type = JSON_Bool;
- Value = "false";
- dValue = 0.;
- return buff+5;
- }
- if (!strncmp(buff,"true",4))
- {
- Type = JSON_Bool;
- Value = "true";
- dValue = 1.;
- return buff + 4;
- }
- if (*buff=='\"')
- {
- return parseString(buff, perror);
- }
- if (*buff=='-' || (*buff>='0' && *buff<='9'))
- {
- return parseNumber(buff);
- }
- if (*buff=='[')
- {
- return parseArray(buff, perror);
- }
- if (*buff=='{')
- {
- return parseObject(buff, perror);
- }
-
- return AssignError(perror, "Syntax Error: Invalid syntax");
-}
-
-
-//-----------------------------------------------------------------------------
-// Render a value to text.
-char* JSON::PrintValue(int depth, bool fmt)
-{
- char *out=0;
-
- switch (Type)
- {
- case JSON_Null: out = JSON_strdup("null"); break;
- case JSON_Bool:
- if ((int)dValue == 0)
- out = JSON_strdup("false");
- else
- out = JSON_strdup("true");
- break;
- case JSON_Number: out = PrintNumber(dValue); break;
- case JSON_String: out = PrintString(Value); break;
- case JSON_Array: out = PrintArray(depth, fmt); break;
- case JSON_Object: out = PrintObject(depth, fmt); break;
- case JSON_None: OVR_ASSERT_LOG(false, ("Bad JSON type.")); break;
- }
- return out;
-}
-
-//-----------------------------------------------------------------------------
-// Build an array object from input text and returns the text position after
-// the parsed array
-const char* JSON::parseArray(const char* buff, const char** perror)
-{
- JSON *child;
- if (*buff!='[')
- {
- return AssignError(perror, "Syntax Error: Missing opening bracket");
- }
-
- Type=JSON_Array;
- buff=skip(buff+1);
-
- if (*buff==']')
- return buff+1; // empty array.
-
- child = new JSON();
- if (!child)
- return 0; // memory fail
- Children.PushBack(child);
-
- buff=skip(child->parseValue(skip(buff), perror)); // skip any spacing, get the buff.
- if (!buff)
- return 0;
-
- while (*buff==',')
- {
- JSON *new_item = new JSON();
- if (!new_item)
- return AssignError(perror, "Error: Failed to allocate memory");
-
- Children.PushBack(new_item);
-
- buff=skip(new_item->parseValue(skip(buff+1), perror));
- if (!buff)
- return AssignError(perror, "Error: Failed to allocate memory");
- }
-
- if (*buff==']')
- return buff+1; // end of array
-
- return AssignError(perror, "Syntax Error: Missing ending bracket");
-}
-
-//-----------------------------------------------------------------------------
-// Render an array to text. The returned text must be freed
-char* JSON::PrintArray(int depth, bool fmt)
-{
- char ** entries;
- char * out = 0, *ptr,*ret;
- intptr_t len = 5;
-
- bool fail = false;
-
- // How many entries in the array?
- int numentries = GetItemCount();
- if (!numentries)
- {
- out=(char*)OVR_ALLOC(3);
- if (out)
- OVR_strcpy(out, 3, "[]");
- return out;
- }
- // Allocate an array to hold the values for each
- entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
- if (!entries)
- return 0;
- memset(entries,0,numentries*sizeof(char*));
-
- //// Retrieve all the results:
- JSON* child = Children.GetFirst();
- for (int i=0; i<numentries; i++)
- {
- //JSON* child = Children[i];
- ret=child->PrintValue(depth+1, fmt);
- entries[i]=ret;
- if (ret)
- len+=OVR_strlen(ret)+2+(fmt?1:0);
- else
- {
- fail = true;
- break;
- }
- child = Children.GetNext(child);
- }
-
- // If we didn't fail, try to malloc the output string
- if (!fail)
- out=(char*)OVR_ALLOC(len);
- // If that fails, we fail.
- if (!out)
- fail = true;
-
- // Handle failure.
- if (fail)
- {
- for (int i=0; i<numentries; i++)
- {
- if (entries[i])
- OVR_FREE(entries[i]);
- }
- OVR_FREE(entries);
- return 0;
- }
-
- // Compose the output array.
- *out='[';
- ptr=out+1;
- *ptr=0;
- for (int i=0; i<numentries; i++)
- {
- OVR_strcpy(ptr, len - (ptr-out), entries[i]);
- ptr+=OVR_strlen(entries[i]);
- if (i!=numentries-1)
- {
- *ptr++=',';
- if (fmt)
- *ptr++=' ';
- *ptr=0;
- }
- OVR_FREE(entries[i]);
- }
- OVR_FREE(entries);
- *ptr++=']';
- *ptr++=0;
- return out;
-}
-
-//-----------------------------------------------------------------------------
-// Build an object from the supplied text and returns the text position after
-// the parsed object
-const char* JSON::parseObject(const char* buff, const char** perror)
-{
- if (*buff!='{')
- {
- return AssignError(perror, "Syntax Error: Missing opening brace");
- }
-
- Type=JSON_Object;
- buff=skip(buff+1);
- if (*buff=='}')
- return buff+1; // empty array.
-
- JSON* child = new JSON();
- Children.PushBack(child);
-
- buff=skip(child->parseString(skip(buff), perror));
- if (!buff)
- return 0;
- child->Name = child->Value;
- child->Value.Clear();
-
- if (*buff!=':')
- {
- return AssignError(perror, "Syntax Error: Missing colon");
- }
-
- buff=skip(child->parseValue(skip(buff+1), perror)); // skip any spacing, get the value.
- if (!buff)
- return 0;
-
- while (*buff==',')
- {
- child = new JSON();
- if (!child)
- return 0; // memory fail
-
- Children.PushBack(child);
-
- buff=skip(child->parseString(skip(buff+1), perror));
- if (!buff)
- return 0;
-
- child->Name=child->Value;
- child->Value.Clear();
-
- if (*buff!=':')
- {
- return AssignError(perror, "Syntax Error: Missing colon");
- } // fail!
-
- // Skip any spacing, get the value.
- buff=skip(child->parseValue(skip(buff+1), perror));
- if (!buff)
- return 0;
- }
-
- if (*buff=='}')
- return buff+1; // end of array
-
- return AssignError(perror, "Syntax Error: Missing closing brace");
-}
-
-//-----------------------------------------------------------------------------
-// Render an object to text. The returned string must be freed
-char* JSON::PrintObject(int depth, bool fmt)
-{
- char** entries = 0, **names = 0;
- char* out = 0;
- char* ptr, *ret, *str;
- intptr_t len = 7, i = 0, j;
- bool fail = false;
-
- // Count the number of entries.
- int numentries = GetItemCount();
-
- // Explicitly handle empty object case
- if (numentries == 0)
- {
- out=(char*)OVR_ALLOC(fmt?depth+4:4);
- if (!out)
- return 0;
- ptr=out;
- *ptr++='{';
-
- if (fmt)
- {
- *ptr++='\n';
- for (i=0;i<depth-1;i++)
- *ptr++='\t';
- }
- *ptr++='}';
- *ptr++=0;
- return out;
- }
- // Allocate space for the names and the objects
- entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
- if (!entries)
- return 0;
- names=(char**)OVR_ALLOC(numentries*sizeof(char*));
-
- if (!names)
- {
- OVR_FREE(entries);
- return 0;
- }
- memset(entries,0,sizeof(char*)*numentries);
- memset(names,0,sizeof(char*)*numentries);
-
- // Collect all the results into our arrays:
- depth++;
- if (fmt)
- len+=depth;
-
- JSON* child = Children.GetFirst();
- while (!Children.IsNull(child))
- {
- names[i] = str = PrintString(child->Name);
- entries[i++] = ret = child->PrintValue(depth, fmt);
-
- if (str && ret)
- {
- len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?3+depth:0);
- }
- else
- {
- fail = true;
- break;
- }
-
- child = Children.GetNext(child);
- }
-
- // Try to allocate the output string
- if (!fail)
- out=(char*)OVR_ALLOC(len);
- if (!out)
- fail=true;
-
- // Handle failure
- if (fail)
- {
- for (i=0;i<numentries;i++)
- {
- if (names[i])
- OVR_FREE(names[i]);
-
- if (entries[i])
- OVR_FREE(entries[i]);}
-
- OVR_FREE(names);
- OVR_FREE(entries);
- return 0;
- }
-
- // Compose the output:
- *out = '{';
- ptr = out+1;
- if (fmt)
- {
-#ifdef OVR_OS_WIN32
- *ptr++ = '\r';
-#endif
- *ptr++ = '\n';
- }
- *ptr = 0;
-
- for (i=0; i<numentries; i++)
- {
- if (fmt)
- {
- for (j = 0; j < depth; j++)
- {
- *ptr++ = '\t';
- }
- }
- OVR_strcpy(ptr, len - (ptr-out), names[i]);
- ptr += OVR_strlen(names[i]);
- *ptr++ =':';
-
- if (fmt)
- {
- *ptr++ = '\t';
- }
-
- OVR_strcpy(ptr, len - (ptr-out), entries[i]);
- ptr+=OVR_strlen(entries[i]);
-
- if (i != numentries - 1)
- {
- *ptr++ = ',';
- }
-
- if (fmt)
- {
-#ifdef OVR_OS_WIN32
- *ptr++ = '\r';
-#endif
- *ptr++ = '\n';
- }
- *ptr = 0;
-
- OVR_FREE(names[i]);
- OVR_FREE(entries[i]);
- }
-
- OVR_FREE(names);
- OVR_FREE(entries);
-
- if (fmt)
- {
- for (i = 0; i < depth - 1; i++)
- {
- *ptr++ = '\t';
- }
- }
- *ptr++='}';
- *ptr++=0;
-
- return out;
-}
-
-
-
-// Returns the number of child items in the object
-// Counts the number of items in the object.
-unsigned JSON::GetItemCount() const
-{
- unsigned count = 0;
- for (const JSON* p = Children.GetFirst(); !Children.IsNull(p); p = p->pNext)
- {
- count++;
- }
- return count;
-}
-
-JSON* JSON::GetItemByIndex(unsigned index)
-{
- unsigned i = 0;
- JSON* child = 0;
-
- if (!Children.IsEmpty())
- {
- child = Children.GetFirst();
-
- while (i < index)
- {
- if (Children.IsNull(child->pNext))
- {
- child = 0;
- break;
- }
- child = child->pNext;
- i++;
- }
- }
-
- return child;
-}
-
-// Returns the child item with the given name or NULL if not found
-JSON* JSON::GetItemByName(const char* name)
-{
- JSON* child = 0;
-
- if (!Children.IsEmpty())
- {
- child = Children.GetFirst();
-
- while (OVR_strcmp(child->Name, name) != 0)
- {
- if (Children.IsNull(child->pNext))
- {
- child = 0;
- break;
- }
- child = child->pNext;
- }
- }
-
- return child;
-}
-
-//-----------------------------------------------------------------------------
-// Adds a new item to the end of the child list
-void JSON::AddItem(const char *string, JSON *item)
-{
- if (item)
- {
- item->Name = string;
- Children.PushBack(item);
- }
-}
-
-/*
-
-// Removes and frees the items at the given index
-void JSON::DeleteItem(unsigned int index)
-{
- unsigned int num_items = 0;
- JSON* child = Children.GetFirst();
- while (!Children.IsNull(child) && num_items < index)
- {
- num_items++;
- child = Children.GetNext(child);
- }
-
- if (!Children.IsNull(child))
-
- child->RemoveNode();
- child->Release();
- }
-}
-
-// Replaces and frees the item at the give index with the new item
-void JSON::ReplaceItem(unsigned int index, JSON* new_item)
-{
- unsigned int num_items = 0;
- JSON* child = Children.GetFirst();
- while (!Children.IsNull(child) && num_items < index)
- {
- num_items++;
- child = Children.GetNext(child);
- }
-
- if (!Children.IsNull(child))
- {
- child->ReplaceNodeWith(new_item);
- child->Release();
- }
-}
-*/
-
-// Removes and frees the last child item
-void JSON::RemoveLast()
-{
- JSON* child = Children.GetLast();
- if (!Children.IsNull(child))
- {
- child->RemoveNode();
- child->Release();
- }
-}
-
-JSON* JSON::CreateBool(bool b)
-{
- JSON *item = new JSON(JSON_Bool);
- if (item)
- {
- item->dValue = b ? 1. : 0.;
- item->Value = b ? "true" : "false";
- }
- return item;
-}
-
-JSON* JSON::CreateNumber(double num)
-{
- JSON *item = new JSON(JSON_Number);
- if (item)
- {
- item->dValue = num;
- }
- return item;
-}
-
-JSON* JSON::CreateInt(int num)
-{
- JSON *item = new JSON(JSON_Number);
- if (item)
- {
- item->dValue = num;
- }
- return item;
-}
-
-JSON* JSON::CreateString(const char *s)
-{
- JSON *item = new JSON(JSON_String);
- if (item && s)
- {
- item->Value = s;
- }
- return item;
-}
-
-
-//-----------------------------------------------------------------------------
-// Get elements by name
-double JSON::GetNumberByName(const char *name, double defValue)
-{
- JSON* item = GetItemByName(name);
- if (!item || item->Type != JSON_Number)
- {
- return defValue;
- }
- else
- {
- return item->dValue;
- }
-}
-
-int JSON::GetIntByName(const char *name, int defValue)
-{
- JSON* item = GetItemByName(name);
- if (!item || item->Type != JSON_Number)
- {
- return defValue;
- }
- else
- {
- return (int)item->dValue;
- }
-}
-
-bool JSON::GetBoolByName(const char *name, bool defValue)
-{
- JSON* item = GetItemByName(name);
- if (!item || item->Type != JSON_Bool)
- {
- return defValue;
- }
- else
- {
- return (int)item->dValue != 0;
- }
-}
-
-String JSON::GetStringByName(const char *name, const String &defValue)
-{
- JSON* item = GetItemByName(name);
- if (!item || item->Type != JSON_String)
- {
- return defValue;
- }
- else
- {
- return item->Value;
- }
-}
-
-//-----------------------------------------------------------------------------
-// Adds an element to an array object type
-void JSON::AddArrayElement(JSON *item)
-{
- if (item)
- {
- Children.PushBack(item);
- }
-}
-
-// Inserts an element into a valid array position
-void JSON::InsertArrayElement(int index, JSON *item)
-{
- if (!item)
- {
- return;
- }
-
- if (index == 0)
- {
- Children.PushFront(item);
- return;
- }
-
- JSON* iter = Children.GetFirst();
- int i=0;
- while (iter && i<index)
- {
- iter = Children.GetNext(iter);
- i++;
- }
-
- if (iter)
- iter->InsertNodeBefore(item);
- else
- Children.PushBack(item);
-}
-
-// Returns the size of an array
-int JSON::GetArraySize()
-{
- if (Type == JSON_Array)
- {
- return GetItemCount();
- }
-
- return 0;
-}
-
-// Returns the number value an the give array index
-double JSON::GetArrayNumber(int index)
-{
- if (Type == JSON_Array)
- {
- JSON* number = GetItemByIndex(index);
- return number ? number->dValue : 0.0;
- }
-
- return 0;
-}
-
-// Returns the string value at the given array index
-const char* JSON::GetArrayString(int index)
-{
- if (Type == JSON_Array)
- {
- JSON* number = GetItemByIndex(index);
- return number ? number->Value : 0;
- }
-
- return 0;
-}
-
-JSON* JSON::Copy()
-{
- JSON* copy = new JSON(Type);
- copy->Name = Name;
- copy->Value = Value;
- copy->dValue = dValue;
-
- JSON* child = Children.GetFirst();
- while (!Children.IsNull(child))
- {
- copy->Children.PushBack(child->Copy());
- child = Children.GetNext(child);
- }
-
- return copy;
-}
-
-//-----------------------------------------------------------------------------
-// Loads and parses the given JSON file pathname and returns a JSON object tree.
-// The returned object must be Released after use.
-JSON* JSON::Load(const char* path, const char** perror)
-{
- SysFile f;
- if (!f.Open(path, File::Open_Read, File::Mode_Read))
- {
- AssignError(perror, "Failed to open file");
- return NULL;
- }
-
- int len = f.GetLength();
- uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1);
- int bytes = f.Read(buff, len);
- f.Close();
-
- if (bytes == 0 || bytes != len)
- {
- OVR_FREE(buff);
- return NULL;
- }
-
- // Ensure the result is null-terminated since Parse() expects null-terminated input.
- buff[len] = '\0';
-
- JSON* json = JSON::Parse((char*)buff, perror);
- OVR_FREE(buff);
- return json;
-}
-
-//-----------------------------------------------------------------------------
-// Serializes the JSON object and writes to the give file path
-bool JSON::Save(const char* path)
-{
- SysFile f;
- if (!f.Open(path, File::Open_Write | File::Open_Create | File::Open_Truncate, File::Mode_Write))
- return false;
-
- char* text = PrintValue(0, true);
- if (text)
- {
- intptr_t len = OVR_strlen(text);
- OVR_ASSERT(len <= (intptr_t)(int)len);
-
- int bytes = f.Write((uint8_t*)text, (int)len);
- f.Close();
- OVR_FREE(text);
- return (bytes == len);
- }
- else
- {
- return false;
- }
-}
-
-
-} // namespace OVR