1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "JSONObject.h" 18 19 #include <ctype.h> 20 #include <math.h> 21 #include <media/stagefright/foundation/ADebug.h> 22 #include <media/stagefright/foundation/AString.h> 23 #include <media/stagefright/MediaErrors.h> 24 25 namespace android { 26 27 // Returns ERROR_MALFORMED if the value overflows a signed int, returns 28 // 0 otherwise. 29 // This method will assert if it is asked to parse a character which is not 30 // a digit. 31 static ssize_t parseInt32(const char *data, size_t numDigits, int32_t *out) { 32 int32_t x = 0; 33 for (size_t i = 0; i < numDigits; ++i) { 34 int32_t old_x = x; 35 x *= 10; 36 x += data[i] - '0'; 37 38 CHECK(isdigit(data[i])); 39 40 if (x < old_x) { 41 // We've overflowed. 42 return ERROR_MALFORMED; 43 } 44 } 45 46 *out = x; 47 return 0; 48 } 49 50 // static 51 ssize_t JSONValue::Parse(const char *data, size_t size, JSONValue *out) { 52 size_t offset = 0; 53 while (offset < size && isspace(data[offset])) { 54 ++offset; 55 } 56 57 if (offset == size) { 58 return ERROR_MALFORMED; 59 } 60 61 if (data[offset] == '[') { 62 sp<JSONArray> array = new JSONArray; 63 ++offset; 64 65 for (;;) { 66 while (offset < size && isspace(data[offset])) { 67 ++offset; 68 } 69 70 if (offset == size) { 71 return ERROR_MALFORMED; 72 } 73 74 if (data[offset] == ']') { 75 ++offset; 76 break; 77 } 78 79 JSONValue val; 80 ssize_t n = Parse(&data[offset], size - offset, &val); 81 82 if (n < 0) { 83 return n; 84 } 85 86 array->addValue(val); 87 88 offset += n; 89 90 while (offset < size && isspace(data[offset])) { 91 ++offset; 92 } 93 94 if (offset == size) { 95 return ERROR_MALFORMED; 96 } 97 98 if (data[offset] == ',') { 99 ++offset; 100 } else if (data[offset] != ']') { 101 return ERROR_MALFORMED; 102 } 103 }; 104 105 out->setArray(array); 106 107 return offset; 108 } else if (data[offset] == '{') { 109 sp<JSONObject> obj = new JSONObject; 110 ++offset; 111 112 for (;;) { 113 while (offset < size && isspace(data[offset])) { 114 ++offset; 115 } 116 117 if (offset == size) { 118 return ERROR_MALFORMED; 119 } 120 121 if (data[offset] == '}') { 122 ++offset; 123 break; 124 } 125 126 JSONValue key; 127 ssize_t n = Parse(&data[offset], size - offset, &key); 128 129 if (n < 0) { 130 return n; 131 } 132 133 if (key.type() != TYPE_STRING) { 134 return ERROR_MALFORMED; 135 } 136 137 offset += n; 138 139 while (offset < size && isspace(data[offset])) { 140 ++offset; 141 } 142 143 if (offset == size || data[offset] != ':') { 144 return ERROR_MALFORMED; 145 } 146 147 ++offset; 148 149 JSONValue val; 150 n = Parse(&data[offset], size - offset, &val); 151 152 if (n < 0) { 153 return n; 154 } 155 156 AString keyVal; 157 CHECK(key.getString(&keyVal)); 158 159 obj->setValue(keyVal.c_str(), val); 160 161 offset += n; 162 163 while (offset < size && isspace(data[offset])) { 164 ++offset; 165 } 166 167 if (offset == size) { 168 return ERROR_MALFORMED; 169 } 170 171 if (data[offset] == ',') { 172 ++offset; 173 } else if (data[offset] != '}') { 174 return ERROR_MALFORMED; 175 } 176 }; 177 178 out->setObject(obj); 179 180 return offset; 181 } else if (data[offset] == '"') { 182 ++offset; 183 184 AString s; 185 bool escaped = false; 186 while (offset < size) { 187 if (escaped) { 188 char c; 189 switch (data[offset]) { 190 case '\"': 191 case '\\': 192 case '/': 193 c = data[offset]; 194 break; 195 case 'b': 196 c = '\x08'; 197 break; 198 case 'f': 199 c = '\x0c'; 200 break; 201 case 'n': 202 c = '\x0a'; 203 break; 204 case 'r': 205 c = '\x0d'; 206 break; 207 case 't': 208 c = '\x09'; 209 break; 210 default: 211 return ERROR_MALFORMED; 212 } 213 214 s.append(c); 215 ++offset; 216 217 escaped = false; 218 } else if (data[offset] == '\\') { 219 escaped = true; 220 } else if (data[offset] == '"') { 221 break; 222 } 223 224 s.append(data[offset++]); 225 } 226 227 if (offset == size) { 228 return ERROR_MALFORMED; 229 } 230 231 ++offset; 232 out->setString(s); 233 234 return offset; 235 } else if (isdigit(data[offset]) || data[offset] == '-') { 236 bool negate = false; 237 if (data[offset] == '-') { 238 negate = true; 239 ++offset; 240 241 if (offset == size) { 242 return ERROR_MALFORMED; 243 } 244 } 245 246 size_t firstDigitOffset = offset; 247 while (offset < size && isdigit(data[offset])) { 248 ++offset; 249 } 250 251 size_t numDigits = offset - firstDigitOffset; 252 if (numDigits > 1 && data[firstDigitOffset] == '0') { 253 // No leading zeros. 254 return ERROR_MALFORMED; 255 } 256 257 size_t firstFracDigitOffset = 0; 258 size_t numFracDigits = 0; 259 260 if (offset < size && data[offset] == '.') { 261 ++offset; 262 263 firstFracDigitOffset = offset; 264 while (offset < size && isdigit(data[offset])) { 265 ++offset; 266 } 267 268 numFracDigits = offset - firstFracDigitOffset; 269 if (numFracDigits == 0) { 270 return ERROR_MALFORMED; 271 } 272 } 273 274 bool negateExponent = false; 275 size_t firstExpDigitOffset = 0; 276 size_t numExpDigits = 0; 277 278 if (offset < size && (data[offset] == 'e' || data[offset] == 'E')) { 279 ++offset; 280 281 if (offset == size) { 282 return ERROR_MALFORMED; 283 } 284 285 if (data[offset] == '+' || data[offset] == '-') { 286 if (data[offset] == '-') { 287 negateExponent = true; 288 } 289 290 ++offset; 291 } 292 293 firstExpDigitOffset = offset; 294 while (offset < size && isdigit(data[offset])) { 295 ++offset; 296 } 297 298 numExpDigits = offset - firstExpDigitOffset; 299 if (numExpDigits == 0) { 300 return ERROR_MALFORMED; 301 } 302 } 303 304 if (numFracDigits == 0 && numExpDigits == 0) { 305 int32_t x; 306 if (parseInt32(&data[firstDigitOffset], numDigits, &x) != 0) { 307 return ERROR_MALFORMED; 308 } 309 310 out->setInt32(negate ? -x : x); 311 } else { 312 int32_t mantissa; 313 if (parseInt32(&data[firstDigitOffset], numDigits, &mantissa) != 0) { 314 return ERROR_MALFORMED; 315 } 316 317 int32_t fraction; 318 if (parseInt32(&data[firstFracDigitOffset], numFracDigits, &fraction) != 0) { 319 return ERROR_MALFORMED; 320 } 321 322 int32_t exponent; 323 if (parseInt32(&data[firstExpDigitOffset], numExpDigits, &exponent) != 0) { 324 return ERROR_MALFORMED; 325 } 326 327 if (negateExponent) { 328 exponent = -exponent; 329 } 330 331 float x = (float)mantissa; 332 x += (float)fraction * powf(10.0f, exponent - (int32_t)numFracDigits); 333 334 out->setFloat(negate ? -x : x); 335 } 336 337 return offset; 338 } else if (offset + 4 <= size && !strncmp("null", &data[offset], 4)) { 339 out->unset(); 340 return offset + 4; 341 } else if (offset + 4 <= size && !strncmp("true", &data[offset], 4)) { 342 out->setBoolean(true); 343 return offset + 4; 344 } else if (offset + 5 <= size && !strncmp("false", &data[offset], 5)) { 345 out->setBoolean(false); 346 return offset + 5; 347 } 348 349 return ERROR_MALFORMED; 350 } 351 352 JSONValue::JSONValue() 353 : mType(TYPE_NULL) { 354 } 355 356 JSONValue::JSONValue(const JSONValue &other) 357 : mType(TYPE_NULL) { 358 *this = other; 359 } 360 361 JSONValue &JSONValue::operator=(const JSONValue &other) { 362 if (&other != this) { 363 unset(); 364 mType = other.mType; 365 mValue = other.mValue; 366 367 switch (mType) { 368 case TYPE_STRING: 369 mValue.mString = new AString(*other.mValue.mString); 370 break; 371 case TYPE_OBJECT: 372 case TYPE_ARRAY: 373 mValue.mObjectOrArray->incStrong(this /* id */); 374 break; 375 376 default: 377 break; 378 } 379 } 380 381 return *this; 382 } 383 384 JSONValue::~JSONValue() { 385 unset(); 386 } 387 388 JSONValue::FieldType JSONValue::type() const { 389 return mType; 390 } 391 392 bool JSONValue::getInt32(int32_t *value) const { 393 if (mType != TYPE_INT32) { 394 return false; 395 } 396 397 *value = mValue.mInt32; 398 return true; 399 } 400 401 bool JSONValue::getFloat(float *value) const { 402 switch (mType) { 403 case TYPE_INT32: 404 { 405 *value = mValue.mInt32; 406 break; 407 } 408 409 case TYPE_FLOAT: 410 { 411 *value = mValue.mFloat; 412 break; 413 } 414 415 default: 416 return false; 417 } 418 419 return true; 420 } 421 422 bool JSONValue::getString(AString *value) const { 423 if (mType != TYPE_STRING) { 424 return false; 425 } 426 427 *value = *mValue.mString; 428 return true; 429 } 430 431 bool JSONValue::getBoolean(bool *value) const { 432 if (mType != TYPE_BOOLEAN) { 433 return false; 434 } 435 436 *value = mValue.mBoolean; 437 return true; 438 } 439 440 bool JSONValue::getObject(sp<JSONObject> *value) const { 441 if (mType != TYPE_OBJECT) { 442 return false; 443 } 444 445 *value = static_cast<JSONObject *>(mValue.mObjectOrArray); 446 return true; 447 } 448 449 bool JSONValue::getArray(sp<JSONArray> *value) const { 450 if (mType != TYPE_ARRAY) { 451 return false; 452 } 453 454 *value = static_cast<JSONArray *>(mValue.mObjectOrArray); 455 return true; 456 } 457 458 void JSONValue::setInt32(int32_t value) { 459 unset(); 460 461 mValue.mInt32 = value; 462 mType = TYPE_INT32; 463 } 464 465 void JSONValue::setFloat(float value) { 466 unset(); 467 468 mValue.mFloat = value; 469 mType = TYPE_FLOAT; 470 } 471 472 void JSONValue::setString(const AString &value) { 473 unset(); 474 475 mValue.mString = new AString(value); 476 mType = TYPE_STRING; 477 } 478 479 void JSONValue::setBoolean(bool value) { 480 unset(); 481 482 mValue.mBoolean = value; 483 mType = TYPE_BOOLEAN; 484 } 485 486 void JSONValue::setObject(const sp<JSONObject> &obj) { 487 unset(); 488 489 mValue.mObjectOrArray = obj.get(); 490 mValue.mObjectOrArray->incStrong(this /* id */); 491 492 mType = TYPE_OBJECT; 493 } 494 495 void JSONValue::setArray(const sp<JSONArray> &array) { 496 unset(); 497 498 mValue.mObjectOrArray = array.get(); 499 mValue.mObjectOrArray->incStrong(this /* id */); 500 501 mType = TYPE_ARRAY; 502 } 503 504 void JSONValue::unset() { 505 switch (mType) { 506 case TYPE_STRING: 507 delete mValue.mString; 508 break; 509 case TYPE_OBJECT: 510 case TYPE_ARRAY: 511 mValue.mObjectOrArray->decStrong(this /* id */); 512 break; 513 514 default: 515 break; 516 } 517 518 mType = TYPE_NULL; 519 } 520 521 static void EscapeString(const char *in, size_t inSize, AString *out) { 522 CHECK(in != out->c_str()); 523 out->clear(); 524 525 for (size_t i = 0; i < inSize; ++i) { 526 char c = in[i]; 527 switch (c) { 528 case '\"': 529 out->append("\\\""); 530 break; 531 case '\\': 532 out->append("\\\\"); 533 break; 534 case '/': 535 out->append("\\/"); 536 break; 537 case '\x08': 538 out->append("\\b"); 539 break; 540 case '\x0c': 541 out->append("\\f"); 542 break; 543 case '\x0a': 544 out->append("\\n"); 545 break; 546 case '\x0d': 547 out->append("\\r"); 548 break; 549 case '\x09': 550 out->append("\\t"); 551 break; 552 default: 553 out->append(c); 554 break; 555 } 556 } 557 } 558 559 AString JSONValue::toString(size_t depth, bool indentFirstLine) const { 560 static const char kIndent[] = " "; 561 562 AString out; 563 564 switch (mType) { 565 case TYPE_STRING: 566 { 567 AString escaped; 568 EscapeString( 569 mValue.mString->c_str(), mValue.mString->size(), &escaped); 570 571 out.append("\""); 572 out.append(escaped); 573 out.append("\""); 574 break; 575 } 576 577 case TYPE_INT32: 578 { 579 out = AStringPrintf("%d", mValue.mInt32); 580 break; 581 } 582 583 case TYPE_FLOAT: 584 { 585 out = AStringPrintf("%f", mValue.mFloat); 586 break; 587 } 588 589 case TYPE_BOOLEAN: 590 { 591 out = mValue.mBoolean ? "true" : "false"; 592 break; 593 } 594 595 case TYPE_NULL: 596 { 597 out = "null"; 598 break; 599 } 600 601 case TYPE_OBJECT: 602 case TYPE_ARRAY: 603 { 604 out = (mType == TYPE_OBJECT) ? "{\n" : "[\n"; 605 out.append(mValue.mObjectOrArray->internalToString(depth + 1)); 606 out.append("\n"); 607 out.append(kIndent, 2 * depth); 608 out.append(mType == TYPE_OBJECT ? "}" : "]"); 609 break; 610 } 611 612 default: 613 TRESPASS(); 614 } 615 616 if (indentFirstLine) { 617 out.insert(kIndent, 2 * depth, 0); 618 } 619 620 return out; 621 } 622 623 //////////////////////////////////////////////////////////////////////////////// 624 625 // static 626 sp<JSONCompound> JSONCompound::Parse(const char *data, size_t size) { 627 JSONValue value; 628 ssize_t result = JSONValue::Parse(data, size, &value); 629 630 if (result < 0) { 631 return NULL; 632 } 633 634 sp<JSONObject> obj; 635 if (value.getObject(&obj)) { 636 return obj; 637 } 638 639 sp<JSONArray> array; 640 if (value.getArray(&array)) { 641 return array; 642 } 643 644 return NULL; 645 } 646 647 AString JSONCompound::toString(size_t depth, bool indentFirstLine) const { 648 JSONValue val; 649 if (isObject()) { 650 val.setObject((JSONObject *)this); 651 } else { 652 val.setArray((JSONArray *)this); 653 } 654 655 return val.toString(depth, indentFirstLine); 656 } 657 658 //////////////////////////////////////////////////////////////////////////////// 659 660 JSONObject::JSONObject() {} 661 JSONObject::~JSONObject() {} 662 663 bool JSONObject::isObject() const { 664 return true; 665 } 666 667 bool JSONObject::getValue(const char *key, JSONValue *value) const { 668 ssize_t index = mValues.indexOfKey(key); 669 if (index < 0) { 670 return false; 671 } 672 673 *value = mValues.valueAt(index); 674 675 return true; 676 } 677 678 void JSONObject::setValue(const char *key, const JSONValue &value) { 679 mValues.add(AString(key), value); 680 } 681 682 AString JSONObject::internalToString(size_t depth) const { 683 static const char kIndent[] = " "; 684 685 AString out; 686 for (size_t i = 0; i < mValues.size(); ++i) { 687 AString key = mValues.keyAt(i); 688 AString escapedKey; 689 EscapeString(key.c_str(), key.size(), &escapedKey); 690 691 out.append(kIndent, 2 * depth); 692 out.append("\""); 693 out.append(escapedKey); 694 out.append("\": "); 695 696 out.append(mValues.valueAt(i).toString(depth + 1, false)); 697 698 if (i + 1 < mValues.size()) { 699 out.append(",\n"); 700 } 701 } 702 703 return out; 704 } 705 706 //////////////////////////////////////////////////////////////////////////////// 707 708 JSONArray::JSONArray() {} 709 710 JSONArray::~JSONArray() {} 711 712 bool JSONArray::isObject() const { 713 return false; 714 } 715 716 size_t JSONArray::size() const { 717 return mValues.size(); 718 } 719 720 bool JSONArray::getValue(size_t key, JSONValue *value) const { 721 if (key >= mValues.size()) { 722 return false; 723 } 724 725 *value = mValues.itemAt(key); 726 727 return true; 728 } 729 730 void JSONArray::addValue(const JSONValue &value) { 731 mValues.push_back(value); 732 } 733 734 AString JSONArray::internalToString(size_t depth) const { 735 AString out; 736 for (size_t i = 0; i < mValues.size(); ++i) { 737 out.append(mValues.itemAt(i).toString(depth)); 738 739 if (i + 1 < mValues.size()) { 740 out.append(",\n"); 741 } 742 } 743 744 return out; 745 } 746 747 //////////////////////////////////////////////////////////////////////////////// 748 749 } // namespace android 750 751