blob: ce986df7d8150359bf38bb065b015376cea7e473 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/json/json_reader.h"
#include <utility>
#include "base/logging.h"
#include "base/parsing_buildflags.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(BUILD_RUST_JSON_PARSER)
#include "base/json/json_parser.rs.h"
#include "base/strings/string_piece_rust.h"
#else
#include "base/json/json_parser.h"
#endif
namespace base {
#if BUILDFLAG(BUILD_RUST_JSON_PARSER)
namespace {
base::JSONReader::ValueWithError DecodeJSONInRust(const base::StringPiece& json,
int options,
size_t max_depth) {
int32_t error_line;
int32_t error_column;
base::ffi::json::json_parser::JsonOptions rust_options;
rust_options.allow_trailing_commas =
options & base::JSON_ALLOW_TRAILING_COMMAS;
rust_options.replace_invalid_characters =
options & base::JSON_REPLACE_INVALID_CHARACTERS;
rust_options.allow_comments = options & base::JSON_ALLOW_COMMENTS;
rust_options.allow_vert_tab = options & base::JSON_ALLOW_VERT_TAB;
rust_options.allow_control_chars = options & base::JSON_ALLOW_CONTROL_CHARS;
rust_options.allow_x_escapes = options & base::JSON_ALLOW_X_ESCAPES;
rust_options.max_depth = max_depth;
base::JSONReader::ValueWithError ret;
bool ok = base::ffi::json::json_parser::decode_json_from_cpp(
base::StringPieceToRustSlice(json), rust_options, ret.value, error_line,
error_column, ret.error_message);
if (!ok) {
ret.value.reset();
ret.error_line = error_line;
ret.error_column = error_column;
}
return ret;
}
} // anonymous namespace
#endif // BUILDFLAG(BUILD_RUST_JSON_PARSER)
JSONReader::ValueWithError::ValueWithError() = default;
JSONReader::ValueWithError::ValueWithError(ValueWithError&& other) = default;
JSONReader::ValueWithError::~ValueWithError() = default;
JSONReader::ValueWithError& JSONReader::ValueWithError::operator=(
ValueWithError&& other) = default;
// static
absl::optional<Value> JSONReader::Read(StringPiece json,
int options,
size_t max_depth) {
#if BUILDFLAG(BUILD_RUST_JSON_PARSER)
ValueWithError result = DecodeJSONInRust(json, options, max_depth);
return std::move(result.value);
#else // BUILDFLAG(BUILD_RUST_JSON_PARSER)
internal::JSONParser parser(options, max_depth);
return parser.Parse(json);
#endif // BUILDFLAG(BUILD_RUST_JSON_PARSER)
}
// static
std::unique_ptr<Value> JSONReader::ReadDeprecated(StringPiece json,
int options,
size_t max_depth) {
absl::optional<Value> value = Read(json, options, max_depth);
return value ? Value::ToUniquePtrValue(std::move(*value)) : nullptr;
}
// static
JSONReader::ValueWithError JSONReader::ReadAndReturnValueWithError(
StringPiece json,
int options) {
#if BUILDFLAG(BUILD_RUST_JSON_PARSER)
return DecodeJSONInRust(json, options, internal::kAbsoluteMaxDepth);
#else // BUILDFLAG(BUILD_RUST_JSON_PARSER)
internal::JSONParser parser(options);
ValueWithError ret;
ret.value = parser.Parse(json);
if (!ret.value) {
ret.error_message = parser.GetErrorMessage();
ret.error_line = parser.error_line();
ret.error_column = parser.error_column();
}
return ret;
#endif // BUILDFLAG(BUILD_RUST_JSON_PARSER)
}
} // namespace base