1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be
3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file.
4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/json/json_reader.h"
6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/json/json_parser.h"
8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/logging.h"
9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/values.h"
10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base {
12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Values 1000 and above are used by JSONFileValueSerializer::JsonFileError.
14cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkostatic_assert(JSONReader::JSON_PARSE_ERROR_COUNT < 1000,
15cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko              "JSONReader error out of bounds");
16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kInvalidEscape[] =
18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Invalid escape sequence.";
19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kSyntaxError[] =
20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Syntax error.";
21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kUnexpectedToken[] =
22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Unexpected token.";
23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kTrailingComma[] =
24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Trailing comma not allowed.";
25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kTooMuchNesting[] =
26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Too much nesting.";
27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kUnexpectedDataAfterRoot[] =
28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Unexpected data after root element.";
29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kUnsupportedEncoding[] =
30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Unsupported encoding. JSON must be UTF-8.";
31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratconst char JSONReader::kUnquotedDictionaryKey[] =
32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    "Dictionary keys must be quoted.";
33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratJSONReader::JSONReader()
35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    : JSONReader(JSON_PARSE_RFC) {
36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratJSONReader::JSONReader(int options)
39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    : parser_(new internal::JSONParser(options)) {
40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratJSONReader::~JSONReader() {
43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static
46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratscoped_ptr<Value> JSONReader::Read(const StringPiece& json) {
47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  internal::JSONParser parser(JSON_PARSE_RFC);
48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return make_scoped_ptr(parser.Parse(json));
49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static
52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratscoped_ptr<Value> JSONReader::Read(const StringPiece& json, int options) {
53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  internal::JSONParser parser(options);
54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return make_scoped_ptr(parser.Parse(json));
55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static
59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratscoped_ptr<Value> JSONReader::ReadAndReturnError(const StringPiece& json,
60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                                 int options,
61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat                                                 int* error_code_out,
62cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                                                 std::string* error_msg_out,
63cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                                                 int* error_line_out,
64cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko                                                 int* error_column_out) {
65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  internal::JSONParser parser(options);
66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  scoped_ptr<Value> root(parser.Parse(json));
67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  if (!root) {
68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (error_code_out)
69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      *error_code_out = parser.error_code();
70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    if (error_msg_out)
71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      *error_msg_out = parser.GetErrorMessage();
72cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (error_line_out)
73cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      *error_line_out = parser.error_line();
74cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko    if (error_column_out)
75cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko      *error_column_out = parser.error_column();
76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return root;
79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// static
82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string JSONReader::ErrorCodeToString(JsonParseError error_code) {
83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  switch (error_code) {
84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_NO_ERROR:
85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return std::string();
86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_INVALID_ESCAPE:
87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kInvalidEscape;
88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_SYNTAX_ERROR:
89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kSyntaxError;
90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_UNEXPECTED_TOKEN:
91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kUnexpectedToken;
92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_TRAILING_COMMA:
93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kTrailingComma;
94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_TOO_MUCH_NESTING:
95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kTooMuchNesting;
96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_UNEXPECTED_DATA_AFTER_ROOT:
97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kUnexpectedDataAfterRoot;
98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_UNSUPPORTED_ENCODING:
99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kUnsupportedEncoding;
100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    case JSON_UNQUOTED_DICTIONARY_KEY:
101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return kUnquotedDictionaryKey;
102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    default:
103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      NOTREACHED();
104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat      return std::string();
105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  }
106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratscoped_ptr<Value> JSONReader::ReadToValue(const std::string& json) {
109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return make_scoped_ptr(parser_->Parse(json));
110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratJSONReader::JsonParseError JSONReader::error_code() const {
113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return parser_->error_code();
114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string JSONReader::GetErrorMessage() const {
117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat  return parser_->GetErrorMessage();
118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}
119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat}  // namespace base
121