00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include <string.h>
00042 #include <stdio.h>
00043 #include <math.h>
00044 #include <stdlib.h>
00045 #include <float.h>
00046 #include <limits.h>
00047 #include <ctype.h>
00048 #include "OVR_JSON.h"
00049 #include "Kernel/OVR_SysFile.h"
00050 #include "Kernel/OVR_Log.h"
00051
00052 namespace OVR {
00053
00054
00055
00056
00057 static char* JSON_strdup(const char* str)
00058 {
00059 UPInt len = OVR_strlen(str) + 1;
00060 char* copy = (char*)OVR_ALLOC(len);
00061 if (!copy)
00062 return 0;
00063 memcpy(copy, str, len);
00064 return copy;
00065 }
00066
00067
00068
00069
00070 static char* PrintNumber(double d)
00071 {
00072 char *str;
00073
00074 int valueint = (int)d;
00075 if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
00076 {
00077 str=(char*)OVR_ALLOC(21);
00078 if (str)
00079 OVR_sprintf(str, 21, "%d", valueint);
00080 }
00081 else
00082 {
00083 str=(char*)OVR_ALLOC(64);
00084 if (str)
00085 {
00086 if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)
00087 OVR_sprintf(str, 64, "%.0f", d);
00088 else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)
00089 OVR_sprintf(str, 64, "%e", d);
00090 else
00091 OVR_sprintf(str, 64, "%f", d);
00092 }
00093 }
00094 return str;
00095 }
00096
00097
00098 static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
00099
00100
00101 const char* AssignError(const char** perror, const char *errorMessage)
00102 {
00103 if (perror)
00104 *perror = errorMessage;
00105 return 0;
00106 }
00107
00108
00109
00110
00111 JSON::JSON(JSONItemType itemType)
00112 : Type(itemType), dValue(0.0)
00113 {
00114 }
00115
00116 JSON::~JSON()
00117 {
00118 JSON* child = Children.GetFirst();
00119 while (!Children.IsNull(child))
00120 {
00121 child->RemoveNode();
00122 child->Release();
00123 child = Children.GetFirst();
00124 }
00125 }
00126
00127
00128
00129
00130 const char* JSON::parseNumber(const char *num)
00131 {
00132 const char* num_start = num;
00133 double n=0, sign=1, scale=0;
00134 int subscale = 0,
00135 signsubscale = 1;
00136
00137
00138 if (*num=='-')
00139 sign=-1,num++;
00140 if (*num=='0')
00141 num++;
00142
00143 if (*num>='1' && *num<='9')
00144 {
00145 do
00146 {
00147 n=(n*10.0)+(*num++ -'0');
00148 }
00149 while (*num>='0' && *num<='9');
00150 }
00151
00152 if (*num=='.' && num[1]>='0' && num[1]<='9')
00153 {
00154 num++;
00155 do
00156 {
00157 n=(n*10.0)+(*num++ -'0');
00158 scale--;
00159 }
00160 while (*num>='0' && *num<='9');
00161 }
00162
00163 if (*num=='e' || *num=='E')
00164 {
00165 num++;
00166 if (*num=='+')
00167 num++;
00168 else if (*num=='-')
00169 {
00170 signsubscale=-1;
00171 num++;
00172 }
00173
00174 while (*num>='0' && *num<='9')
00175 subscale=(subscale*10)+(*num++ - '0');
00176 }
00177
00178
00179 n = sign*n*pow(10.0,(scale+subscale*signsubscale));
00180
00181
00182 Type = JSON_Number;
00183 dValue = n;
00184 Value.AssignString(num_start, num - num_start);
00185
00186 return num;
00187 }
00188
00189
00190
00191 const char* ParseHex(unsigned* val, unsigned digits, const char* str)
00192 {
00193 *val = 0;
00194
00195 for(unsigned digitCount = 0; digitCount < digits; digitCount++, str++)
00196 {
00197 unsigned v = *str;
00198
00199 if ((v >= '0') && (v <= '9'))
00200 v -= '0';
00201 else if ((v >= 'a') && (v <= 'f'))
00202 v = 10 + v - 'a';
00203 else if ((v >= 'A') && (v <= 'F'))
00204 v = 10 + v - 'A';
00205 else
00206 break;
00207
00208 *val = *val * 16 + v;
00209 }
00210
00211 return str;
00212 }
00213
00214
00215
00216
00217 const char* JSON::parseString(const char* str, const char** perror)
00218 {
00219 const char* ptr = str+1;
00220 const char* p;
00221 char* ptr2;
00222 char* out;
00223 int len=0;
00224 unsigned uc, uc2;
00225
00226 if (*str!='\"')
00227 {
00228 return AssignError(perror, "Syntax Error: Missing quote");
00229 }
00230
00231 while (*ptr!='\"' && *ptr && ++len)
00232 {
00233 if (*ptr++ == '\\') ptr++;
00234 }
00235
00236
00237 out=(char*)OVR_ALLOC(len+1);
00238 if (!out)
00239 return 0;
00240
00241 ptr = str+1;
00242 ptr2= out;
00243
00244 while (*ptr!='\"' && *ptr)
00245 {
00246 if (*ptr!='\\')
00247 {
00248 *ptr2++ = *ptr++;
00249 }
00250 else
00251 {
00252 ptr++;
00253 switch (*ptr)
00254 {
00255 case 'b': *ptr2++ = '\b'; break;
00256 case 'f': *ptr2++ = '\f'; break;
00257 case 'n': *ptr2++ = '\n'; break;
00258 case 'r': *ptr2++ = '\r'; break;
00259 case 't': *ptr2++ = '\t'; break;
00260
00261
00262 case 'u':
00263
00264
00265 p = ParseHex(&uc, 4, ptr + 1);
00266 if (ptr != p)
00267 ptr = p - 1;
00268
00269 if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)
00270 break;
00271
00272
00273 if (uc>=0xD800 && uc<=0xDBFF)
00274 {
00275 if (ptr[1]!='\\' || ptr[2]!='u')
00276 break;
00277
00278 p= ParseHex(&uc2, 4, ptr + 3);
00279 if (ptr != p)
00280 ptr = p - 1;
00281
00282 if (uc2<0xDC00 || uc2>0xDFFF)
00283 break;
00284
00285 uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
00286 }
00287
00288 len=4;
00289
00290 if (uc<0x80)
00291 len=1;
00292 else if (uc<0x800)
00293 len=2;
00294 else if (uc<0x10000)
00295 len=3;
00296
00297 ptr2+=len;
00298
00299 switch (len)
00300 {
00301 case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
00302 case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
00303 case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
00304 case 1: *--ptr2 = (char)(uc | firstByteMark[len]);
00305 }
00306 ptr2+=len;
00307 break;
00308
00309 default:
00310 *ptr2++ = *ptr;
00311 break;
00312 }
00313 ptr++;
00314 }
00315 }
00316
00317 *ptr2 = 0;
00318 if (*ptr=='\"')
00319 ptr++;
00320
00321
00322 Value=out;
00323 OVR_FREE(out);
00324 Type=JSON_String;
00325
00326 return ptr;
00327 }
00328
00329
00330
00331 char* PrintString(const char* str)
00332 {
00333 const char *ptr;
00334 char *ptr2,*out;
00335 int len=0;
00336 unsigned char token;
00337
00338 if (!str)
00339 return JSON_strdup("");
00340 ptr=str;
00341
00342 token=*ptr;
00343 while (token && ++len)\
00344 {
00345 if (strchr("\"\\\b\f\n\r\t",token))
00346 len++;
00347 else if (token<32)
00348 len+=5;
00349 ptr++;
00350 token=*ptr;
00351 }
00352
00353 int buff_size = len+3;
00354 out=(char*)OVR_ALLOC(buff_size);
00355 if (!out)
00356 return 0;
00357
00358 ptr2 = out;
00359 ptr = str;
00360 *ptr2++ = '\"';
00361
00362 while (*ptr)
00363 {
00364 if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\')
00365 *ptr2++=*ptr++;
00366 else
00367 {
00368 *ptr2++='\\';
00369 switch (token=*ptr++)
00370 {
00371 case '\\': *ptr2++='\\'; break;
00372 case '\"': *ptr2++='\"'; break;
00373 case '\b': *ptr2++='b'; break;
00374 case '\f': *ptr2++='f'; break;
00375 case '\n': *ptr2++='n'; break;
00376 case '\r': *ptr2++='r'; break;
00377 case '\t': *ptr2++='t'; break;
00378 default:
00379 OVR_sprintf(ptr2, buff_size - (ptr2-out), "u%04x",token);
00380 ptr2+=5;
00381 break;
00382 }
00383 }
00384 }
00385 *ptr2++='\"';
00386 *ptr2++=0;
00387 return out;
00388 }
00389
00390
00391
00392 static const char* skip(const char* in)
00393 {
00394 while (in && *in && (unsigned char)*in<=' ')
00395 in++;
00396 return in;
00397 }
00398
00399
00400
00401
00402 JSON* JSON::Parse(const char* buff, const char** perror)
00403 {
00404 const char* end = 0;
00405 JSON* json = new JSON();
00406
00407 if (!json)
00408 {
00409 AssignError(perror, "Error: Failed to allocate memory");
00410 return 0;
00411 }
00412
00413 end = json->parseValue(skip(buff), perror);
00414 if (!end)
00415 {
00416 json->Release();
00417 return NULL;
00418 }
00419
00420 return json;
00421 }
00422
00423
00424
00425 const char* JSON::parseValue(const char* buff, const char** perror)
00426 {
00427 if (perror)
00428 *perror = 0;
00429
00430 if (!buff)
00431 return NULL;
00432
00433 if (!strncmp(buff,"null",4))
00434 {
00435 Type = JSON_Null;
00436 return buff+4;
00437 }
00438 if (!strncmp(buff,"false",5))
00439 {
00440 Type = JSON_Bool;
00441 Value = "false";
00442 dValue = 0;
00443 return buff+5;
00444 }
00445 if (!strncmp(buff,"true",4))
00446 {
00447 Type = JSON_Bool;
00448 Value = "true";
00449 dValue = 1;
00450 return buff+4;
00451 }
00452 if (*buff=='\"')
00453 {
00454 return parseString(buff, perror);
00455 }
00456 if (*buff=='-' || (*buff>='0' && *buff<='9'))
00457 {
00458 return parseNumber(buff);
00459 }
00460 if (*buff=='[')
00461 {
00462 return parseArray(buff, perror);
00463 }
00464 if (*buff=='{')
00465 {
00466 return parseObject(buff, perror);
00467 }
00468
00469 return AssignError(perror, "Syntax Error: Invalid syntax");
00470 }
00471
00472
00473
00474
00475 char* JSON::PrintValue(int depth, bool fmt)
00476 {
00477 char *out=0;
00478
00479 switch (Type)
00480 {
00481 case JSON_Null: out = JSON_strdup("null"); break;
00482 case JSON_Bool:
00483 if (dValue == 0)
00484 out = JSON_strdup("false");
00485 else
00486 out = JSON_strdup("true");
00487 break;
00488 case JSON_Number: out = PrintNumber(dValue); break;
00489 case JSON_String: out = PrintString(Value); break;
00490 case JSON_Array: out = PrintArray(depth, fmt); break;
00491 case JSON_Object: out = PrintObject(depth, fmt); break;
00492 case JSON_None: OVR_ASSERT_LOG(false, ("Bad JSON type.")); break;
00493 }
00494 return out;
00495 }
00496
00497
00498
00499
00500 const char* JSON::parseArray(const char* buff, const char** perror)
00501 {
00502 JSON *child;
00503 if (*buff!='[')
00504 {
00505 return AssignError(perror, "Syntax Error: Missing opening bracket");
00506 }
00507
00508 Type=JSON_Array;
00509 buff=skip(buff+1);
00510
00511 if (*buff==']')
00512 return buff+1;
00513
00514 child = new JSON();
00515 if (!child)
00516 return 0;
00517 Children.PushBack(child);
00518
00519 buff=skip(child->parseValue(skip(buff), perror));
00520 if (!buff)
00521 return 0;
00522
00523 while (*buff==',')
00524 {
00525 JSON *new_item = new JSON();
00526 if (!new_item)
00527 return AssignError(perror, "Error: Failed to allocate memory");
00528
00529 Children.PushBack(new_item);
00530
00531 buff=skip(new_item->parseValue(skip(buff+1), perror));
00532 if (!buff)
00533 return AssignError(perror, "Error: Failed to allocate memory");
00534 }
00535
00536 if (*buff==']')
00537 return buff+1;
00538
00539 return AssignError(perror, "Syntax Error: Missing ending bracket");
00540 }
00541
00542
00543
00544 char* JSON::PrintArray(int depth, bool fmt)
00545 {
00546 char **entries;
00547 char * out = 0,*ptr,*ret;
00548 SPInt len = 5;
00549
00550 bool fail = false;
00551
00552
00553 int numentries = GetItemCount();
00554 if (!numentries)
00555 {
00556 out=(char*)OVR_ALLOC(3);
00557 if (out)
00558 OVR_strcpy(out, 3, "[]");
00559 return out;
00560 }
00561
00562 entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
00563 if (!entries)
00564 return 0;
00565 memset(entries,0,numentries*sizeof(char*));
00566
00568 JSON* child = Children.GetFirst();
00569 for (int i=0; i<numentries; i++)
00570 {
00571
00572 ret=child->PrintValue(depth+1, fmt);
00573 entries[i]=ret;
00574 if (ret)
00575 len+=OVR_strlen(ret)+2+(fmt?1:0);
00576 else
00577 {
00578 fail = true;
00579 break;
00580 }
00581 child = Children.GetNext(child);
00582 }
00583
00584
00585 if (!fail)
00586 out=(char*)OVR_ALLOC(len);
00587
00588 if (!out)
00589 fail = true;
00590
00591
00592 if (fail)
00593 {
00594 for (int i=0; i<numentries; i++)
00595 {
00596 if (entries[i])
00597 OVR_FREE(entries[i]);
00598 }
00599 OVR_FREE(entries);
00600 return 0;
00601 }
00602
00603
00604 *out='[';
00605 ptr=out+1;
00606 *ptr=0;
00607 for (int i=0; i<numentries; i++)
00608 {
00609 OVR_strcpy(ptr, len - (ptr-out), entries[i]);
00610 ptr+=OVR_strlen(entries[i]);
00611 if (i!=numentries-1)
00612 {
00613 *ptr++=',';
00614 if (fmt)
00615 *ptr++=' ';
00616 *ptr=0;
00617 }
00618 OVR_FREE(entries[i]);
00619 }
00620 OVR_FREE(entries);
00621 *ptr++=']';
00622 *ptr++=0;
00623 return out;
00624 }
00625
00626
00627
00628
00629 const char* JSON::parseObject(const char* buff, const char** perror)
00630 {
00631 if (*buff!='{')
00632 {
00633 return AssignError(perror, "Syntax Error: Missing opening brace");
00634 }
00635
00636 Type=JSON_Object;
00637 buff=skip(buff+1);
00638 if (*buff=='}')
00639 return buff+1;
00640
00641 JSON* child = new JSON();
00642 Children.PushBack(child);
00643
00644 buff=skip(child->parseString(skip(buff), perror));
00645 if (!buff)
00646 return 0;
00647 child->Name = child->Value;
00648 child->Value.Clear();
00649
00650 if (*buff!=':')
00651 {
00652 return AssignError(perror, "Syntax Error: Missing colon");
00653 }
00654
00655 buff=skip(child->parseValue(skip(buff+1), perror));
00656 if (!buff)
00657 return 0;
00658
00659 while (*buff==',')
00660 {
00661 child = new JSON();
00662 if (!child)
00663 return 0;
00664
00665 Children.PushBack(child);
00666
00667 buff=skip(child->parseString(skip(buff+1), perror));
00668 if (!buff)
00669 return 0;
00670
00671 child->Name=child->Value;
00672 child->Value.Clear();
00673
00674 if (*buff!=':')
00675 {
00676 return AssignError(perror, "Syntax Error: Missing colon");
00677 }
00678
00679
00680 buff=skip(child->parseValue(skip(buff+1), perror));
00681 if (!buff)
00682 return 0;
00683 }
00684
00685 if (*buff=='}')
00686 return buff+1;
00687
00688 return AssignError(perror, "Syntax Error: Missing closing brace");
00689 }
00690
00691
00692
00693 char* JSON::PrintObject(int depth, bool fmt)
00694 {
00695 char** entries = 0, **names = 0;
00696 char* out = 0;
00697 char* ptr, *ret, *str;
00698 SPInt len = 7, i = 0, j;
00699 bool fail = false;
00700
00701
00702 int numentries = GetItemCount();
00703
00704
00705 if (numentries == 0)
00706 {
00707 out=(char*)OVR_ALLOC(fmt?depth+3:3);
00708 if (!out)
00709 return 0;
00710 ptr=out;
00711 *ptr++='{';
00712
00713 if (fmt)
00714 {
00715 *ptr++='\n';
00716 for (i=0;i<depth-1;i++)
00717 *ptr++='\t';
00718 }
00719 *ptr++='}';
00720 *ptr++=0;
00721 return out;
00722 }
00723
00724 entries=(char**)OVR_ALLOC(numentries*sizeof(char*));
00725 if (!entries)
00726 return 0;
00727 names=(char**)OVR_ALLOC(numentries*sizeof(char*));
00728
00729 if (!names)
00730 {
00731 OVR_FREE(entries);
00732 return 0;
00733 }
00734 memset(entries,0,sizeof(char*)*numentries);
00735 memset(names,0,sizeof(char*)*numentries);
00736
00737
00738 depth++;
00739 if (fmt)
00740 len+=depth;
00741
00742 JSON* child = Children.GetFirst();
00743 while (!Children.IsNull(child))
00744 {
00745 names[i] = str = PrintString(child->Name);
00746 entries[i++] = ret = child->PrintValue(depth, fmt);
00747
00748 if (str && ret)
00749 {
00750 len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?2+depth:0);
00751 }
00752 else
00753 {
00754 fail = true;
00755 break;
00756 }
00757
00758 child = Children.GetNext(child);
00759 }
00760
00761
00762 if (!fail)
00763 out=(char*)OVR_ALLOC(len);
00764 if (!out)
00765 fail=true;
00766
00767
00768 if (fail)
00769 {
00770 for (i=0;i<numentries;i++)
00771 {
00772 if (names[i])
00773 OVR_FREE(names[i]);
00774
00775 if (entries[i])
00776 OVR_FREE(entries[i]);}
00777
00778 OVR_FREE(names);
00779 OVR_FREE(entries);
00780 return 0;
00781 }
00782
00783
00784 *out = '{';
00785 ptr = out+1;
00786 if (fmt)
00787 *ptr++='\n';
00788 *ptr = 0;
00789
00790 for (i=0; i<numentries; i++)
00791 {
00792 if (fmt)
00793 {
00794 for (j=0; j<depth; j++)
00795 *ptr++ = '\t';
00796 }
00797 OVR_strcpy(ptr, len - (ptr-out), names[i]);
00798 ptr += OVR_strlen(names[i]);
00799 *ptr++ =':';
00800
00801 if (fmt)
00802 *ptr++='\t';
00803
00804 OVR_strcpy(ptr, len - (ptr-out), entries[i]);
00805 ptr+=OVR_strlen(entries[i]);
00806
00807 if (i!=numentries-1)
00808 *ptr++ = ',';
00809
00810 if (fmt)
00811 *ptr++ = '\n';
00812 *ptr = 0;
00813
00814 OVR_FREE(names[i]);
00815 OVR_FREE(entries[i]);
00816 }
00817
00818 OVR_FREE(names);
00819 OVR_FREE(entries);
00820
00821 if (fmt)
00822 {
00823 for (i=0;i<depth-1;i++)
00824 *ptr++='\t';
00825 }
00826 *ptr++='}';
00827 *ptr++=0;
00828
00829 return out;
00830 }
00831
00832
00833
00834
00835
00836 unsigned JSON::GetItemCount() const
00837 {
00838 unsigned count = 0;
00839 for(const JSON* p = Children.GetFirst(); !Children.IsNull(p); p = p->pNext)
00840 count++;
00841 return count;
00842 }
00843
00844 JSON* JSON::GetItemByIndex(unsigned index)
00845 {
00846 unsigned i = 0;
00847 JSON* child = 0;
00848
00849 if (!Children.IsEmpty())
00850 {
00851 child = Children.GetFirst();
00852
00853 while (i < index)
00854 {
00855 if (Children.IsNull(child->pNext))
00856 {
00857 child = 0;
00858 break;
00859 }
00860 child = child->pNext;
00861 i++;
00862 }
00863 }
00864
00865 return child;
00866 }
00867
00868
00869 JSON* JSON::GetItemByName(const char* name)
00870 {
00871 JSON* child = 0;
00872
00873 if (!Children.IsEmpty())
00874 {
00875 child = Children.GetFirst();
00876
00877 while (OVR_strcmp(child->Name, name) != 0)
00878 {
00879 if (Children.IsNull(child->pNext))
00880 {
00881 child = 0;
00882 break;
00883 }
00884 child = child->pNext;
00885 }
00886 }
00887
00888 return child;
00889 }
00890
00891
00892
00893 void JSON::AddItem(const char *string, JSON *item)
00894 {
00895 if (!item)
00896 return;
00897
00898 item->Name = string;
00899 Children.PushBack(item);
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 JSON* JSON::createHelper(JSONItemType itemType, double dval, const char* strVal)
00943 {
00944 JSON *item = new JSON(itemType);
00945 if (item)
00946 {
00947 item->dValue = dval;
00948 if (strVal)
00949 item->Value = strVal;
00950 }
00951 return item;
00952 }
00953
00954
00955
00956
00957 void JSON::AddArrayElement(JSON *item)
00958 {
00959 if (!item)
00960 return;
00961
00962 Children.PushBack(item);
00963 }
00964
00965
00966
00967 int JSON::GetArraySize()
00968 {
00969 if (Type == JSON_Array)
00970 return GetItemCount();
00971 else
00972 return 0;
00973 }
00974
00975
00976 double JSON::GetArrayNumber(int index)
00977 {
00978 if (Type == JSON_Array)
00979 {
00980 JSON* number = GetItemByIndex(index);
00981 return number ? number->dValue : 0.0;
00982 }
00983 else
00984 {
00985 return 0;
00986 }
00987 }
00988
00989
00990 const char* JSON::GetArrayString(int index)
00991 {
00992 if (Type == JSON_Array)
00993 {
00994 JSON* number = GetItemByIndex(index);
00995 return number ? number->Value : 0;
00996 }
00997 else
00998 {
00999 return 0;
01000 }
01001 }
01002
01003
01004
01005
01006 JSON* JSON::Load(const char* path, const char** perror)
01007 {
01008 SysFile f;
01009 if (!f.Open(path, File::Open_Read, File::Mode_Read))
01010 {
01011 AssignError(perror, "Failed to open file");
01012 return NULL;
01013 }
01014
01015 int len = f.GetLength();
01016 UByte* buff = (UByte*)OVR_ALLOC(len);
01017 int bytes = f.Read(buff, len);
01018 f.Close();
01019
01020 if (bytes == 0 || bytes != len)
01021 {
01022 OVR_FREE(buff);
01023 return NULL;
01024 }
01025
01026 JSON* json = JSON::Parse((char*)buff, perror);
01027 OVR_FREE(buff);
01028 return json;
01029 }
01030
01031
01032
01033 bool JSON::Save(const char* path)
01034 {
01035 SysFile f;
01036 if (!f.Open(path, File::Open_Write | File::Open_Create | File::Open_Truncate, File::Mode_Write))
01037 return false;
01038
01039 char* text = PrintValue(0, true);
01040 if (text)
01041 {
01042 SPInt len = OVR_strlen(text);
01043 OVR_ASSERT(len < (SPInt)(int)len);
01044
01045 int bytes = f.Write((UByte*)text, (int)len);
01046 f.Close();
01047 OVR_FREE(text);
01048 return (bytes == len);
01049 }
01050 else
01051 {
01052 return false;
01053 }
01054 }
01055
01056 }