aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DEPS13
-rw-r--r--build/config/BUILD.gn19
-rw-r--r--osp_base/BUILD.gn10
-rw-r--r--osp_base/DEPS1
-rw-r--r--osp_base/error.h3
-rw-r--r--osp_base/json/json_reader.cc40
-rw-r--r--osp_base/json/json_reader.h33
-rw-r--r--osp_base/json/json_reader_unittest.cc53
-rw-r--r--osp_base/json/json_writer.cc46
-rw-r--r--osp_base/json/json_writer.h34
-rw-r--r--osp_base/json/json_writer_unittest.cc32
-rw-r--r--third_party/.gitignore1
-rw-r--r--third_party/jsoncpp/BUILD.gn53
13 files changed, 334 insertions, 4 deletions
diff --git a/DEPS b/DEPS
index a28d160f..13626df1 100644
--- a/DEPS
+++ b/DEPS
@@ -14,7 +14,7 @@ vars = {
'chromium_git': 'https://chromium.googlesource.com',
# TODO(jophba): move to googlesource external for github repos.
- 'github': "https://github.com",
+ 'github': 'https://github.com',
# NOTE: Strangely enough, this will be overridden by any _parent_ DEPS, so
# in Chromium it will correctly be True.
@@ -34,11 +34,13 @@ deps = {
'@' + '703984f9d1674c2cfc259904a5a7fba4990cca4b',
'condition': 'checkout_openscreen_cast_internal',
},
+
'buildtools': {
'url': Var('chromium_git')+ '/chromium/src/buildtools' +
'@' + 'd5c58b84d50d256968271db459cd29b22bff1ba2',
'condition': 'not build_with_chromium',
},
+
'buildtools/linux64': {
'packages': [
{
@@ -49,6 +51,7 @@ deps = {
'dep_type': 'cipd',
'condition': 'checkout_linux',
},
+
'buildtools/mac': {
'packages': [
{
@@ -59,6 +62,14 @@ deps = {
'dep_type': 'cipd',
'condition': 'checkout_mac',
},
+
+ 'third_party/jsoncpp/src': {
+ 'url': Var('chromium_git') +
+ '/external/github.com/open-source-parsers/jsoncpp.git' +
+ '@' + '5b91551f3944d69e0090d6b6528852207de78078',
+ 'condition': 'not build_with_chromium',
+ },
+
'third_party/googletest/src': {
'url': Var('chromium_git') +
'/external/github.com/google/googletest.git' +
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index e486be03..708a2b8d 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -33,8 +33,23 @@ config("compiler_defaults") {
}
config("no_exceptions") {
- cflags_cc = [ "-fno-exceptions" ]
- cflags_objcc = [ "-fno-exceptions" ]
+ # -fno-exceptions causes the compiler to choose the implementation of the STL
+ # that uses abort() calls instead of throws, as well as issue compile errors
+ # for throw calls in user ccode. The no*unwind-tables flags disable generation
+ # of static unwind tables that are typically used for exceptions, resulting
+ # in typically smaller object sizes. For some information, see:
+ # https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-funwind-tables-1203
+ cflags_cc = [
+ "-fno-exceptions",
+ "-fno-unwind-tables",
+ "-fno-asynchronous-unwind-tables",
+ ]
+
+ cflags_objcc = [
+ "-fno-exceptions",
+ "-fno-unwind-tables",
+ "-fno-asynchronous-unwind-tables",
+ ]
}
config("no_rtti") {
diff --git a/osp_base/BUILD.gn b/osp_base/BUILD.gn
index 737e921f..d8b1e3c5 100644
--- a/osp_base/BUILD.gn
+++ b/osp_base/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright 2018 The Chromium Authors. All rights reserved.
+# Copyright 2019 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.
@@ -15,6 +15,10 @@ source_set("osp_base") {
"export.h",
"ip_address.cc",
"ip_address.h",
+ "json/json_reader.cc",
+ "json/json_reader.h",
+ "json/json_writer.cc",
+ "json/json_writer.h",
"location.cc",
"location.h",
"macros.h",
@@ -28,6 +32,7 @@ source_set("osp_base") {
deps = [
"../third_party/abseil",
"../third_party/boringssl",
+ "../third_party/jsoncpp",
]
configs += [ "../build:allow_build_from_embedder" ]
@@ -40,6 +45,8 @@ source_set("osp_base_unittests") {
"big_endian_unittest.cc",
"error_unittest.cc",
"ip_address_unittest.cc",
+ "json/json_reader_unittest.cc",
+ "json/json_writer_unittest.cc",
"location_unittest.cc",
"scoped_pipe_unittest.cc",
]
@@ -49,6 +56,7 @@ source_set("osp_base_unittests") {
"../third_party/abseil",
"../third_party/googletest:gmock",
"../third_party/googletest:gtest",
+ "../third_party/jsoncpp",
]
configs += [ "../build:allow_build_from_embedder" ]
diff --git a/osp_base/DEPS b/osp_base/DEPS
index 96d75425..eaaf2fef 100644
--- a/osp_base/DEPS
+++ b/osp_base/DEPS
@@ -5,4 +5,5 @@
include_rules = [
'-platform',
'+platform/api/logging.h',
+ '+json',
]
diff --git a/osp_base/error.h b/osp_base/error.h
index 5ad1792e..5c9ba2d5 100644
--- a/osp_base/error.h
+++ b/osp_base/error.h
@@ -73,6 +73,9 @@ class Error {
kAlreadyClosed,
kNoStartedPresentation,
kPresentationAlreadyStarted,
+
+ kJsonParseError,
+ kJsonWriteError,
};
Error();
diff --git a/osp_base/json/json_reader.cc b/osp_base/json/json_reader.cc
new file mode 100644
index 00000000..1750c2ad
--- /dev/null
+++ b/osp_base/json/json_reader.cc
@@ -0,0 +1,40 @@
+// Copyright 2019 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 "osp_base/json/json_reader.h"
+
+#include <memory>
+#include <string>
+
+#include "json/value.h"
+#include "osp_base/error.h"
+#include "platform/api/logging.h"
+
+namespace openscreen {
+namespace {
+// A reasonable maximum stack depth, may need to adjust as needs change.
+constexpr int kMaxStackDepth = 64;
+} // namespace
+
+JsonReader::JsonReader() {
+ builder_["stackLimit"] = kMaxStackDepth;
+}
+
+ErrorOr<Json::Value> JsonReader::Read(absl::string_view document) {
+ if (document.empty()) {
+ return ErrorOr<Json::Value>(Error::Code::kJsonParseError, "empty document");
+ }
+
+ Json::Value root_node;
+ std::string error_msg;
+ std::unique_ptr<Json::CharReader> reader(builder_.newCharReader());
+ const bool succeeded =
+ reader->parse(document.begin(), document.end(), &root_node, &error_msg);
+ if (!succeeded) {
+ return ErrorOr<Json::Value>(Error::Code::kJsonParseError, error_msg);
+ }
+
+ return root_node;
+}
+} // namespace openscreen
diff --git a/osp_base/json/json_reader.h b/osp_base/json/json_reader.h
new file mode 100644
index 00000000..be4a5e06
--- /dev/null
+++ b/osp_base/json/json_reader.h
@@ -0,0 +1,33 @@
+// Copyright 2019 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.
+
+#ifndef OSP_BASE_JSON_JSON_READER_H_
+#define OSP_BASE_JSON_JSON_READER_H_
+
+#include <memory>
+
+#include "absl/strings/string_view.h"
+#include "json/reader.h"
+
+namespace Json {
+class Value;
+}
+
+namespace openscreen {
+template <typename T>
+class ErrorOr;
+
+class JsonReader {
+ public:
+ JsonReader();
+
+ ErrorOr<Json::Value> Read(absl::string_view document);
+
+ private:
+ Json::CharReaderBuilder builder_;
+};
+
+} // namespace openscreen
+
+#endif // OSP_BASE_JSON_JSON_READER_H_ \ No newline at end of file
diff --git a/osp_base/json/json_reader_unittest.cc b/osp_base/json/json_reader_unittest.cc
new file mode 100644
index 00000000..21729ebf
--- /dev/null
+++ b/osp_base/json/json_reader_unittest.cc
@@ -0,0 +1,53 @@
+// Copyright 2019 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 "osp_base/json/json_reader.h"
+
+#include <string>
+
+#include "osp_base/error.h"
+#include "third_party/googletest/src/googlemock/include/gmock/gmock.h"
+#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
+
+namespace openscreen {
+namespace {
+template <typename Value>
+void AssertError(ErrorOr<Value> error_or, Error::Code code) {
+ EXPECT_EQ(error_or.error().code(), code);
+}
+} // namespace
+
+TEST(JsonReaderTest, MalformedDocumentReturnsParseError) {
+ JsonReader reader;
+
+ const std::array<std::string, 4> kMalformedDocuments{
+ {"", "{", "{ foo: bar }", R"({"foo": "bar", "foo": baz})"}};
+
+ for (auto& document : kMalformedDocuments) {
+ AssertError(reader.Read(document), Error::Code::kJsonParseError);
+ }
+}
+
+TEST(JsonReaderTest, ValidEmptyDocumentParsedCorrectly) {
+ JsonReader reader;
+
+ const auto actual = reader.Read("{}");
+
+ EXPECT_TRUE(actual.is_value());
+ EXPECT_EQ(actual.value().getMemberNames().size(), 0);
+}
+
+// Jsoncpp has its own suite of tests ensure that things are parsed correctly,
+// so we only do some rudimentary checks here to make sure we didn't mangle
+// the value.
+TEST(JsonReaderTest, ValidDocumentParsedCorrectly) {
+ JsonReader reader;
+
+ const auto actual = reader.Read(R"({"foo": "bar", "baz": 1337})");
+
+ EXPECT_TRUE(actual.is_value());
+ EXPECT_EQ(actual.value().getMemberNames().size(), 2);
+}
+
+} // namespace openscreen
diff --git a/osp_base/json/json_writer.cc b/osp_base/json/json_writer.cc
new file mode 100644
index 00000000..1d3d94f9
--- /dev/null
+++ b/osp_base/json/json_writer.cc
@@ -0,0 +1,46 @@
+// Copyright 2019 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 "osp_base/json/json_writer.h"
+
+#include <memory>
+#include <sstream>
+#include <string>
+#include <utility>
+
+#include "json/value.h"
+#include "osp_base/error.h"
+#include "platform/api/logging.h"
+
+namespace openscreen {
+JsonWriter::JsonWriter() {
+#ifndef _DEBUG
+ // Default is to "pretty print" the output JSON in a human readable
+ // format. On non-debug builds, we can remove pretty printing by simply
+ // getting rid of all indentation.
+ factory_["indentation"] = "";
+#endif
+}
+
+ErrorOr<std::string> JsonWriter::Write(const Json::Value& value) {
+ if (value.empty()) {
+ return ErrorOr<std::string>(Error::Code::kJsonWriteError, "Empty value");
+ }
+
+ std::unique_ptr<Json::StreamWriter> const writer(factory_.newStreamWriter());
+ std::stringstream stream;
+ writer->write(value, &stream);
+ stream << std::endl;
+
+ if (!stream) {
+ // Note: jsoncpp doesn't give us more information about what actually
+ // went wrong, just says to "check the stream". However, failures on
+ // the stream should be rare, as we do not throw any errors in the jsoncpp
+ // library.
+ return ErrorOr<std::string>(Error::Code::kJsonWriteError, "Invalid stream");
+ }
+
+ return stream.str();
+}
+} // namespace openscreen
diff --git a/osp_base/json/json_writer.h b/osp_base/json/json_writer.h
new file mode 100644
index 00000000..bad9484a
--- /dev/null
+++ b/osp_base/json/json_writer.h
@@ -0,0 +1,34 @@
+// Copyright 2019 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.
+
+#ifndef OSP_BASE_JSON_JSON_WRITER_H_
+#define OSP_BASE_JSON_JSON_WRITER_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/strings/string_view.h"
+#include "json/writer.h"
+
+namespace Json {
+class Value;
+}
+
+namespace openscreen {
+template <typename T>
+class ErrorOr;
+
+class JsonWriter {
+ public:
+ JsonWriter();
+
+ ErrorOr<std::string> Write(const Json::Value& value);
+
+ private:
+ Json::StreamWriterBuilder factory_;
+};
+
+} // namespace openscreen
+
+#endif // OSP_BASE_JSON_JSON_WRITER_H_
diff --git a/osp_base/json/json_writer_unittest.cc b/osp_base/json/json_writer_unittest.cc
new file mode 100644
index 00000000..6a4c00e1
--- /dev/null
+++ b/osp_base/json/json_writer_unittest.cc
@@ -0,0 +1,32 @@
+// Copyright 2019 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 "osp_base/json/json_writer.h"
+
+#include "osp_base/error.h"
+#include "third_party/googletest/src/googlemock/include/gmock/gmock.h"
+#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
+
+namespace openscreen {
+
+TEST(JsonWriterTest, NullValueReturnsError) {
+ JsonWriter writer;
+
+ const auto null_value = Json::Value();
+ const auto actual = writer.Write(null_value);
+
+ EXPECT_TRUE(actual.is_error());
+ EXPECT_EQ(actual.error().code(), Error::Code::kJsonWriteError);
+}
+
+TEST(JsonWriterTest, ValidValueReturnsString) {
+ JsonWriter writer;
+
+ const Json::Int64 value = 31337;
+ const auto actual = writer.Write(value);
+
+ EXPECT_TRUE(actual.is_value());
+ EXPECT_EQ(actual.value(), "31337\n");
+}
+} // namespace openscreen
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 78052e47..05b0106f 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -2,5 +2,6 @@ abseil/src/
boringssl/src/
chromium_quic/src/
googletest/src/
+jsoncpp/src/
mDNSResponder/src/
tinycbor/src/
diff --git a/third_party/jsoncpp/BUILD.gn b/third_party/jsoncpp/BUILD.gn
new file mode 100644
index 00000000..a889495c
--- /dev/null
+++ b/third_party/jsoncpp/BUILD.gn
@@ -0,0 +1,53 @@
+# Copyright 2018 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.
+
+import("//build_overrides/build.gni")
+
+if (build_with_chromium) {
+ source_set("jsoncpp") {
+ public_deps = [
+ "//third_party/jsoncpp",
+ ]
+ }
+} else {
+ config("jsoncpp_config") {
+ include_dirs = [ "//third_party/jsoncpp/src/include" ]
+ cflags_cc = [
+ "-Wno-exit-time-destructors",
+ "-Wno-implicit-fallthrough",
+ ]
+ }
+
+ source_set("jsoncpp") {
+ sources = [
+ "overrides.h",
+ "src/include/json/assertions.h",
+ "src/include/json/autolink.h",
+ "src/include/json/config.h",
+ "src/include/json/features.h",
+ "src/include/json/forwards.h",
+ "src/include/json/json.h",
+ "src/include/json/reader.h",
+ "src/include/json/value.h",
+ "src/include/json/writer.h",
+ "src/src/lib_json/json_batchallocator.h",
+ "src/src/lib_json/json_reader.cpp",
+ "src/src/lib_json/json_tool.h",
+ "src/src/lib_json/json_value.cpp",
+ "src/src/lib_json/json_writer.cpp",
+ ]
+
+ include_dirs = [ "src/src/lib_json" ]
+
+ defines = [ "JSON_USE_EXCEPTION=0" ]
+
+ # Need exceptions on for throwRuntimeError. This will result in an abort
+ # once it crosses into parent code (which is compiled without exceptions).
+ # TODO(jophba): remove once jsoncpp patch fixing JSON_USE_EXCEPTION
+ # is upstreamed and DEPS rolled.
+ configs -= [ "//build/config:no_exceptions" ]
+
+ public_configs = [ ":jsoncpp_config" ]
+ }
+}