15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_parser.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Values 1000 and above are used by JSONFileValueSerializer::JsonFileError.
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)COMPILE_ASSERT(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               json_reader_error_out_of_bounds);
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kInvalidEscape =
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Invalid escape sequence.";
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kSyntaxError =
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Syntax error.";
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kUnexpectedToken =
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Unexpected token.";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kTrailingComma =
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Trailing comma not allowed.";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kTooMuchNesting =
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Too much nesting.";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kUnexpectedDataAfterRoot =
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Unexpected data after root element.";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kUnsupportedEncoding =
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Unsupported encoding. JSON must be UTF-8.";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* JSONReader::kUnquotedDictionaryKey =
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "Dictionary keys must be quoted.";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JSONReader::JSONReader()
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : parser_(new internal::JSONParser(JSON_PARSE_RFC)) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JSONReader::JSONReader(int options)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : parser_(new internal::JSONParser(options)) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JSONReader::~JSONReader() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* JSONReader::Read(const StringPiece& json) {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::JSONParser parser(JSON_PARSE_RFC);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parser.Parse(json);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* JSONReader::Read(const StringPiece& json,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int options) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::JSONParser parser(options);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parser.Parse(json);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* JSONReader::ReadAndReturnError(const StringPiece& json,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int options,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      int* error_code_out,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      std::string* error_msg_out) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  internal::JSONParser parser(options);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Value* root = parser.Parse(json);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (root)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return root;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_code_out)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error_code_out = parser.error_code();
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_msg_out)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error_msg_out = parser.GetErrorMessage();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string JSONReader::ErrorCodeToString(JsonParseError error_code) {
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (error_code) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_NO_ERROR:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::string();
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_INVALID_ESCAPE:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kInvalidEscape;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_SYNTAX_ERROR:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kSyntaxError;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_UNEXPECTED_TOKEN:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kUnexpectedToken;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_TRAILING_COMMA:
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kTrailingComma;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_TOO_MUCH_NESTING:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kTooMuchNesting;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_UNEXPECTED_DATA_AFTER_ROOT:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kUnexpectedDataAfterRoot;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_UNSUPPORTED_ENCODING:
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kUnsupportedEncoding;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case JSON_UNQUOTED_DICTIONARY_KEY:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kUnquotedDictionaryKey;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::string();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Value* JSONReader::ReadToValue(const std::string& json) {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parser_->Parse(json);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)JSONReader::JsonParseError JSONReader::error_code() const {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parser_->error_code();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string JSONReader::GetErrorMessage() const {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return parser_->GetErrorMessage();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
115