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 #include "ultrajson.h"
00035 #include <math.h>
00036 #include <assert.h>
00037 #include <string.h>
00038 #include <limits.h>
00039 #include <wchar.h>
00040
00041 struct DecoderState
00042 {
00043 char *start;
00044 char *end;
00045 wchar_t *escStart;
00046 wchar_t *escEnd;
00047 int escHeap;
00048 int lastType;
00049 JSONObjectDecoder *dec;
00050 };
00051
00052 JSOBJ FASTCALL_MSVC decode_any( struct DecoderState *ds) FASTCALL_ATTR;
00053 typedef JSOBJ (*PFN_DECODER)( struct DecoderState *ds);
00054 #define RETURN_JSOBJ_NULLCHECK(_expr) return(_expr);
00055
00056 double createDouble(double intNeg, double intValue, double frcValue, int frcDecimalCount)
00057 {
00058 static const double g_pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000};
00059
00060 return (intValue + (frcValue / g_pow10[frcDecimalCount])) * intNeg;
00061 }
00062
00063 static JSOBJ SetError( struct DecoderState *ds, int offset, const char *message)
00064 {
00065 ds->dec->errorOffset = ds->start + offset;
00066 ds->dec->errorStr = (char *) message;
00067 return NULL;
00068 }
00069
00070 static void ClearError( struct DecoderState *ds)
00071 {
00072 ds->dec->errorOffset = 0;
00073 ds->dec->errorStr = NULL;
00074 }
00075
00076 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_numeric ( struct DecoderState *ds)
00077 {
00078 #ifdef JSON_DECODE_NUMERIC_AS_DOUBLE
00079 double intNeg = 1;
00080 double intValue;
00081 #else
00082 int intNeg = 1;
00083 JSLONG intValue;
00084 #endif
00085
00086 double expNeg;
00087 int chr;
00088 int decimalCount = 0;
00089 double frcValue = 0.0;
00090 double expValue;
00091 char *offset = ds->start;
00092
00093 if (*(offset) == '-')
00094 {
00095 offset ++;
00096 intNeg = -1;
00097 }
00098
00099
00100 intValue = 0;
00101
00102 while (1)
00103 {
00104 chr = (int) (unsigned char) *(offset);
00105
00106 switch (chr)
00107 {
00108 case '0':
00109 case '1':
00110 case '2':
00111 case '3':
00112 case '4':
00113 case '5':
00114 case '6':
00115 case '7':
00116 case '8':
00117 case '9':
00118
00119
00120 #ifdef JSON_DECODE_NUMERIC_AS_DOUBLE
00121 intValue = intValue * 10.0 + (double) (chr - 48);
00122 #else
00123 intValue = intValue * 10LL + (JSLONG) (chr - 48);
00124 #endif
00125 offset ++;
00126 break;
00127
00128 case '.':
00129 offset ++;
00130 goto DECODE_FRACTION;
00131 break;
00132
00133 case 'e':
00134 case 'E':
00135 offset ++;
00136 goto DECODE_EXPONENT;
00137 break;
00138
00139 default:
00140 goto BREAK_INT_LOOP;
00141 break;
00142 }
00143 }
00144
00145 BREAK_INT_LOOP:
00146
00147 ds->lastType = JT_INT;
00148 ds->start = offset;
00149
00150
00151
00152 #ifdef JSON_DECODE_NUMERIC_AS_DOUBLE
00153 #else
00154 if (intValue < 0)
00155 {
00156 intNeg = 1;
00157 }
00158 #endif
00159
00160
00161
00162
00163 #ifdef JSON_DECODE_NUMERIC_AS_DOUBLE
00164 if (intValue > (double) INT_MAX || intValue < (double) INT_MIN)
00165 #else
00166 if ( (intValue >> 31))
00167 #endif
00168 {
00169 RETURN_JSOBJ_NULLCHECK(ds->dec->newLong( (JSINT64) (intValue * (JSINT64) intNeg)));
00170 }
00171 else
00172 {
00173 RETURN_JSOBJ_NULLCHECK(ds->dec->newInt( (JSINT32) (intValue * intNeg)));
00174 }
00175
00176
00177
00178 DECODE_FRACTION:
00179
00180
00181 frcValue = 0.0;
00182 while (1)
00183 {
00184 chr = (int) (unsigned char) *(offset);
00185
00186 switch (chr)
00187 {
00188 case '0':
00189 case '1':
00190 case '2':
00191 case '3':
00192 case '4':
00193 case '5':
00194 case '6':
00195 case '7':
00196 case '8':
00197 case '9':
00198 if (decimalCount < JSON_DOUBLE_MAX_DECIMALS)
00199 {
00200 frcValue = frcValue * 10.0 + (double) (chr - 48);
00201 decimalCount ++;
00202 }
00203 offset ++;
00204 break;
00205
00206 case 'e':
00207 case 'E':
00208 offset ++;
00209 goto DECODE_EXPONENT;
00210 break;
00211
00212 default:
00213 goto BREAK_FRC_LOOP;
00214 }
00215 }
00216
00217 BREAK_FRC_LOOP:
00218
00219 if (intValue < 0)
00220 {
00221 intNeg = 1;
00222 }
00223
00224
00225 ds->lastType = JT_DOUBLE;
00226 ds->start = offset;
00227 RETURN_JSOBJ_NULLCHECK(ds->dec->newDouble (createDouble( (double) intNeg, (double) intValue, frcValue, decimalCount)));
00228
00229 DECODE_EXPONENT:
00230 expNeg = 1.0;
00231
00232 if (*(offset) == '-')
00233 {
00234 expNeg = -1.0;
00235 offset ++;
00236 }
00237 else
00238 if (*(offset) == '+')
00239 {
00240 expNeg = +1.0;
00241 offset ++;
00242 }
00243
00244 expValue = 0.0;
00245
00246 while (1)
00247 {
00248 chr = (int) (unsigned char) *(offset);
00249
00250 switch (chr)
00251 {
00252 case '0':
00253 case '1':
00254 case '2':
00255 case '3':
00256 case '4':
00257 case '5':
00258 case '6':
00259 case '7':
00260 case '8':
00261 case '9':
00262 expValue = expValue * 10.0 + (double) (chr - 48);
00263 offset ++;
00264 break;
00265
00266 default:
00267 goto BREAK_EXP_LOOP;
00268
00269 }
00270 }
00271
00272 BREAK_EXP_LOOP:
00273
00274 #ifdef JSON_DECODE_NUMERIC_AS_DOUBLE
00275 #else
00276 if (intValue < 0)
00277 {
00278 intNeg = 1;
00279 }
00280 #endif
00281
00282
00283 ds->lastType = JT_DOUBLE;
00284 ds->start = offset;
00285 RETURN_JSOBJ_NULLCHECK(ds->dec->newDouble (createDouble( (double) intNeg, (double) intValue , frcValue, decimalCount) * pow(10.0, expValue * expNeg)));
00286 }
00287
00288 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_true ( struct DecoderState *ds)
00289 {
00290 char *offset = ds->start;
00291 offset ++;
00292
00293 if (*(offset++) != 'r')
00294 goto SETERROR;
00295 if (*(offset++) != 'u')
00296 goto SETERROR;
00297 if (*(offset++) != 'e')
00298 goto SETERROR;
00299
00300 ds->lastType = JT_TRUE;
00301 ds->start = offset;
00302 RETURN_JSOBJ_NULLCHECK(ds->dec->newTrue());
00303
00304 SETERROR:
00305 return SetError(ds, -1, "Unexpected character found when decoding 'true'");
00306 }
00307
00308 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_false ( struct DecoderState *ds)
00309 {
00310 char *offset = ds->start;
00311 offset ++;
00312
00313 if (*(offset++) != 'a')
00314 goto SETERROR;
00315 if (*(offset++) != 'l')
00316 goto SETERROR;
00317 if (*(offset++) != 's')
00318 goto SETERROR;
00319 if (*(offset++) != 'e')
00320 goto SETERROR;
00321
00322 ds->lastType = JT_FALSE;
00323 ds->start = offset;
00324 RETURN_JSOBJ_NULLCHECK(ds->dec->newFalse());
00325
00326 SETERROR:
00327 return SetError(ds, -1, "Unexpected character found when decoding 'false'");
00328
00329 }
00330
00331
00332 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_null ( struct DecoderState *ds)
00333 {
00334 char *offset = ds->start;
00335 offset ++;
00336
00337 if (*(offset++) != 'u')
00338 goto SETERROR;
00339 if (*(offset++) != 'l')
00340 goto SETERROR;
00341 if (*(offset++) != 'l')
00342 goto SETERROR;
00343
00344 ds->lastType = JT_NULL;
00345 ds->start = offset;
00346 RETURN_JSOBJ_NULLCHECK(ds->dec->newNull());
00347
00348 SETERROR:
00349 return SetError(ds, -1, "Unexpected character found when decoding 'null'");
00350 }
00351
00352 FASTCALL_ATTR void FASTCALL_MSVC SkipWhitespace(struct DecoderState *ds)
00353 {
00354 char *offset = ds->start;
00355
00356 while (1)
00357 {
00358 switch (*offset)
00359 {
00360 case ' ':
00361 case '\t':
00362 case '\r':
00363 case '\n':
00364 offset ++;
00365 break;
00366
00367 default:
00368 ds->start = offset;
00369 return;
00370 }
00371 }
00372 }
00373
00374
00375 enum DECODESTRINGSTATE
00376 {
00377 DS_ISNULL = 0x32,
00378 DS_ISQUOTE,
00379 DS_ISESCAPE,
00380 DS_UTFLENERROR,
00381
00382 };
00383
00384 static const JSUINT8 g_decoderLookup[256] =
00385 {
00386 DS_ISNULL, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00387 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00388 1, 1, DS_ISQUOTE, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00389 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00390 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00391 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, DS_ISESCAPE, 1, 1, 1,
00392 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00393 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00394 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00395 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00396 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00397 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
00398 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00399 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00400 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
00401 4, 4, 4, 4, 4, 4, 4, 4, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR, DS_UTFLENERROR,
00402 };
00403
00404
00405 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_string ( struct DecoderState *ds)
00406 {
00407 JSUTF16 sur[2] = { 0 };
00408 int iSur = 0;
00409 int index;
00410 wchar_t *escOffset;
00411 size_t escLen = (ds->escEnd - ds->escStart);
00412 JSUINT8 *inputOffset;
00413 JSUINT8 oct;
00414 JSUTF32 ucs;
00415 ds->lastType = JT_INVALID;
00416 ds->start ++;
00417
00418 if ( (ds->end - ds->start) > escLen)
00419 {
00420 size_t newSize = (ds->end - ds->start);
00421
00422 if (ds->escHeap)
00423 {
00424 ds->escStart = (wchar_t *) ds->dec->realloc (ds->escStart, newSize * sizeof(wchar_t));
00425 if (!ds->escStart)
00426 {
00427 return SetError(ds, -1, "Could not reserve memory block");
00428 }
00429 }
00430 else
00431 {
00432 wchar_t *oldStart = ds->escStart;
00433 ds->escHeap = 1;
00434 ds->escStart = (wchar_t *) ds->dec->malloc (newSize * sizeof(wchar_t));
00435 if (!ds->escStart)
00436 {
00437 return SetError(ds, -1, "Could not reserve memory block");
00438 }
00439 memcpy (ds->escStart, oldStart, escLen * sizeof(wchar_t));
00440 }
00441
00442 ds->escEnd = ds->escStart + newSize;
00443 }
00444
00445 escOffset = ds->escStart;
00446 inputOffset = ds->start;
00447
00448 while(1)
00449 {
00450 switch (g_decoderLookup[(JSUINT8)(*inputOffset)])
00451 {
00452 case DS_ISNULL:
00453 return SetError(ds, -1, "Unmatched ''\"' when when decoding 'string'");
00454
00455 case DS_ISQUOTE:
00456 ds->lastType = JT_UTF8;
00457 inputOffset ++;
00458 ds->start += ( (char *) inputOffset - (ds->start));
00459 RETURN_JSOBJ_NULLCHECK(ds->dec->newString(ds->escStart, escOffset));
00460
00461 case DS_UTFLENERROR:
00462 return SetError (ds, -1, "Invalid UTF-8 sequence length when decoding 'string'");
00463
00464 case DS_ISESCAPE:
00465 inputOffset ++;
00466 switch (*inputOffset)
00467 {
00468 case '\\': *(escOffset++) = L'\\'; inputOffset++; continue;
00469 case '\"': *(escOffset++) = L'\"'; inputOffset++; continue;
00470 case '/': *(escOffset++) = L'/'; inputOffset++; continue;
00471 case 'b': *(escOffset++) = L'\b'; inputOffset++; continue;
00472 case 'f': *(escOffset++) = L'\f'; inputOffset++; continue;
00473 case 'n': *(escOffset++) = L'\n'; inputOffset++; continue;
00474 case 'r': *(escOffset++) = L'\r'; inputOffset++; continue;
00475 case 't': *(escOffset++) = L'\t'; inputOffset++; continue;
00476
00477 case 'u':
00478 {
00479 int index;
00480 inputOffset ++;
00481
00482 for (index = 0; index < 4; index ++)
00483 {
00484 switch (*inputOffset)
00485 {
00486 case '\0': return SetError (ds, -1, "Unterminated unicode escape sequence when decoding 'string'");
00487 default: return SetError (ds, -1, "Unexpected character in unicode escape sequence when decoding 'string'");
00488
00489 case '0':
00490 case '1':
00491 case '2':
00492 case '3':
00493 case '4':
00494 case '5':
00495 case '6':
00496 case '7':
00497 case '8':
00498 case '9':
00499 sur[iSur] = (sur[iSur] << 4) + (JSUTF16) (*inputOffset - '0');
00500 break;
00501
00502 case 'a':
00503 case 'b':
00504 case 'c':
00505 case 'd':
00506 case 'e':
00507 case 'f':
00508 sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'a');
00509 break;
00510
00511 case 'A':
00512 case 'B':
00513 case 'C':
00514 case 'D':
00515 case 'E':
00516 case 'F':
00517 sur[iSur] = (sur[iSur] << 4) + 10 + (JSUTF16) (*inputOffset - 'A');
00518 break;
00519 }
00520
00521 inputOffset ++;
00522 }
00523
00524
00525 if (iSur == 0)
00526 {
00527 if((sur[iSur] & 0xfc00) == 0xd800)
00528 {
00529
00530 iSur ++;
00531 break;
00532 }
00533 (*escOffset++) = (wchar_t) sur[iSur];
00534 iSur = 0;
00535 }
00536 else
00537 {
00538
00539 if ((sur[1] & 0xfc00) != 0xdc00)
00540 {
00541 return SetError (ds, -1, "Unpaired high surrogate when decoding 'string'");
00542 }
00543
00544 #if WCHAR_MAX == 0xffff
00545 (*escOffset++) = (wchar_t) sur[0];
00546 (*escOffset++) = (wchar_t) sur[1];
00547 #else
00548 (*escOffset++) = (wchar_t) 0x10000 + (((sur[0] - 0xd800) << 10) | (sur[1] - 0xdc00));
00549 #endif
00550 iSur = 0;
00551 }
00552 break;
00553 }
00554
00555 case '\0': return SetError(ds, -1, "Unterminated escape sequence when decoding 'string'");
00556 default: return SetError(ds, -1, "Unrecognized escape sequence when decoding 'string'");
00557 }
00558 break;
00559
00560 case 1:
00561 *(escOffset++) = (wchar_t) (*inputOffset++);
00562 break;
00563
00564 case 2:
00565 {
00566 ucs = (*inputOffset++) & 0x1f;
00567 ucs <<= 6;
00568 if (((*inputOffset) & 0x80) != 0x80)
00569 {
00570 return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'");
00571 }
00572 ucs |= (*inputOffset++) & 0x3f;
00573 if (ucs < 0x80) return SetError (ds, -1, "Overlong 2 byte UTF-8 sequence detected when decoding 'string'");
00574 *(escOffset++) = (wchar_t) ucs;
00575 break;
00576 }
00577
00578 case 3:
00579 {
00580 JSUTF32 ucs = 0;
00581 ucs |= (*inputOffset++) & 0x0f;
00582
00583 for (index = 0; index < 2; index ++)
00584 {
00585 ucs <<= 6;
00586 oct = (*inputOffset++);
00587
00588 if ((oct & 0x80) != 0x80)
00589 {
00590 return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'");
00591 }
00592
00593 ucs |= oct & 0x3f;
00594 }
00595
00596 if (ucs < 0x800) return SetError (ds, -1, "Overlong 3 byte UTF-8 sequence detected when encoding string");
00597 *(escOffset++) = (wchar_t) ucs;
00598 break;
00599 }
00600
00601 case 4:
00602 {
00603 JSUTF32 ucs = 0;
00604 ucs |= (*inputOffset++) & 0x07;
00605
00606 for (index = 0; index < 3; index ++)
00607 {
00608 ucs <<= 6;
00609 oct = (*inputOffset++);
00610
00611 if ((oct & 0x80) != 0x80)
00612 {
00613 return SetError(ds, -1, "Invalid octet in UTF-8 sequence when decoding 'string'");
00614 }
00615
00616 ucs |= oct & 0x3f;
00617 }
00618
00619 if (ucs < 0x10000) return SetError (ds, -1, "Overlong 4 byte UTF-8 sequence detected when decoding 'string'");
00620
00621 #if WCHAR_MAX == 0xffff
00622 if (ucs >= 0x10000)
00623 {
00624 ucs -= 0x10000;
00625 *(escOffset++) = (ucs >> 10) + 0xd800;
00626 *(escOffset++) = (ucs & 0x3ff) + 0xdc00;
00627 }
00628 else
00629 {
00630 *(escOffset++) = (wchar_t) ucs;
00631 }
00632 #else
00633 *(escOffset++) = (wchar_t) ucs;
00634 #endif
00635 break;
00636 }
00637 }
00638 }
00639 }
00640
00641 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_array( struct DecoderState *ds)
00642 {
00643 JSOBJ itemValue;
00644 JSOBJ newObj = ds->dec->newArray();
00645 int len = 0;
00646
00647 ds->lastType = JT_INVALID;
00648 ds->start ++;
00649
00650
00651 while (1)
00652 {
00653 SkipWhitespace(ds);
00654
00655 itemValue = decode_any(ds);
00656
00657 if (itemValue == NULL)
00658 {
00659 switch (*(ds->start++))
00660 {
00661 case ']':
00662 if (len > 0)
00663 {
00664 ds->dec->releaseObject(newObj);
00665 return SetError(ds, -1, "Unexpected trailing comma in array");
00666 }
00667
00668 ClearError(ds);
00669 return newObj;
00670
00671 default:
00672 ds->dec->releaseObject(newObj);
00673 return SetError(ds, -1, "Unexpected character in found when decoding array value");
00674 }
00675
00676
00677 ds->dec->releaseObject(newObj);
00678 return NULL;
00679 }
00680
00681 ds->dec->arrayAddItem (newObj, itemValue);
00682
00683 SkipWhitespace(ds);
00684
00685 switch (*(ds->start++))
00686 {
00687 case ']':
00688 return newObj;
00689
00690 case ',':
00691 break;
00692
00693 default:
00694 ds->dec->releaseObject(newObj);
00695 return SetError(ds, -1, "Unexpected character in found when decoding array value");
00696 }
00697
00698 len ++;
00699 }
00700
00701 ds->dec->releaseObject(newObj);
00702 return SetError(ds, -1, "Unmatched ']' when decoding 'array'");
00703 }
00704
00705
00706
00707 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_object( struct DecoderState *ds)
00708 {
00709 JSOBJ itemName;
00710 JSOBJ itemValue;
00711 JSOBJ newObj = ds->dec->newObject();
00712
00713 ds->start ++;
00714
00715 while (1)
00716 {
00717 SkipWhitespace(ds);
00718
00719 if ((*ds->start) == '}')
00720 {
00721 ds->start ++;
00722 return newObj;
00723 }
00724
00725 ds->lastType = JT_INVALID;
00726 itemName = decode_any(ds);
00727
00728 if (itemName == NULL)
00729 {
00730 ds->dec->releaseObject(newObj);
00731 return NULL;
00732 }
00733
00734 if (ds->lastType != JT_UTF8)
00735 {
00736 ds->dec->releaseObject(newObj);
00737 ds->dec->releaseObject(itemName);
00738 return SetError(ds, -1, "Key name of object must be 'string' when decoding 'object'");
00739 }
00740
00741 SkipWhitespace(ds);
00742
00743 if (*(ds->start++) != ':')
00744 {
00745 ds->dec->releaseObject(newObj);
00746 ds->dec->releaseObject(itemName);
00747 return SetError(ds, -1, "No ':' found when decoding object value");
00748 }
00749
00750 SkipWhitespace(ds);
00751
00752 itemValue = decode_any(ds);
00753
00754 if (itemValue == NULL)
00755 {
00756 ds->dec->releaseObject(newObj);
00757 ds->dec->releaseObject(itemName);
00758 return NULL;
00759 }
00760
00761 ds->dec->objectAddKey (newObj, itemName, itemValue);
00762
00763 SkipWhitespace(ds);
00764
00765 switch (*(ds->start++))
00766 {
00767 case '}':
00768 return newObj;
00769
00770 case ',':
00771 break;
00772
00773 default:
00774 ds->dec->releaseObject(newObj);
00775 return SetError(ds, -1, "Unexpected character in found when decoding object value");
00776 }
00777 }
00778
00779 ds->dec->releaseObject(newObj);
00780 return SetError(ds, -1, "Unmatched '}' when decoding object");
00781 }
00782
00783 FASTCALL_ATTR JSOBJ FASTCALL_MSVC decode_any(struct DecoderState *ds)
00784 {
00785 while (1)
00786 {
00787 switch (*ds->start)
00788 {
00789 case '\"':
00790 return decode_string (ds);
00791 case '0':
00792 case '1':
00793 case '2':
00794 case '3':
00795 case '4':
00796 case '5':
00797 case '6':
00798 case '7':
00799 case '8':
00800 case '9':
00801 case '-':
00802 return decode_numeric (ds);
00803
00804 case '[': return decode_array (ds);
00805 case '{': return decode_object (ds);
00806 case 't': return decode_true (ds);
00807 case 'f': return decode_false (ds);
00808 case 'n': return decode_null (ds);
00809
00810 case ' ':
00811 case '\t':
00812 case '\r':
00813 case '\n':
00814
00815 ds->start ++;
00816 break;
00817
00818 default:
00819 return SetError(ds, -1, "Expected object or value");
00820 }
00821 }
00822 }
00823
00824
00825 JSOBJ JSON_DecodeObject(JSONObjectDecoder *dec, const char *buffer, size_t cbBuffer)
00826 {
00827
00828
00829
00830 struct DecoderState ds;
00831 wchar_t escBuffer[(JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t))];
00832 JSOBJ ret;
00833
00834 ds.start = (char *) buffer;
00835 ds.end = ds.start + cbBuffer;
00836
00837 ds.escStart = escBuffer;
00838 ds.escEnd = ds.escStart + (JSON_MAX_STACK_BUFFER_SIZE / sizeof(wchar_t));
00839 ds.escHeap = 0;
00840 ds.dec = dec;
00841 ds.dec->errorStr = NULL;
00842 ds.dec->errorOffset = NULL;
00843
00844 ds.dec = dec;
00845
00846 ret = decode_any (&ds);
00847
00848 if (ds.escHeap)
00849 {
00850 dec->free(ds.escStart);
00851 }
00852
00853 if (ds.start != ds.end && ret)
00854 {
00855 dec->releaseObject(ret);
00856 return SetError(&ds, -1, "Trailing data");
00857 }
00858
00859 return ret;
00860 }