diff --git a/SConstruct b/SConstruct index 9d985ab696..6e5f31d921 100644 --- a/SConstruct +++ b/SConstruct @@ -37,7 +37,7 @@ assert arch in [ "Darwin", # macOS arm64 (x86 not supported) ] -pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'libjpeg', 'libyuv', 'ncurses', 'zeromq', 'zstd'] +pkg_names = ['acados', 'bzip2', 'capnproto', 'catch2', 'eigen', 'ffmpeg', 'json11', 'libjpeg', 'libyuv', 'ncurses', 'zeromq', 'zstd'] pkgs = [importlib.import_module(name) for name in pkg_names] acados = pkgs[pkg_names.index('acados')] acados_include_dirs = [ @@ -112,7 +112,6 @@ env = Environment( "#", "#msgq", "#third_party", - "#third_party/json11", acados_include_dirs, [x.INCLUDE_DIR for x in pkgs], ], @@ -242,9 +241,6 @@ SConscript([ if arch == "larch64": SConscript(['system/camerad/SConscript']) -# Build openpilot -SConscript(['third_party/SConscript']) - # Build selfdrive SConscript([ 'selfdrive/pandad/SConscript', diff --git a/common/swaglog.cc b/common/swaglog.cc index 62a405a2b6..df7ce94c14 100644 --- a/common/swaglog.cc +++ b/common/swaglog.cc @@ -11,7 +11,7 @@ #include #include -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" #include "common/version.h" #include "system/hardware/hw.h" diff --git a/common/tests/test_swaglog.cc b/common/tests/test_swaglog.cc index 09bc4c3795..8142f8d63e 100644 --- a/common/tests/test_swaglog.cc +++ b/common/tests/test_swaglog.cc @@ -7,7 +7,7 @@ #include "common/util.h" #include "common/version.h" #include "system/hardware/hw.h" -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" std::string daemon_name = "testy"; std::string dongle_id = "test_dongle_id"; diff --git a/third_party/SConscript b/third_party/SConscript deleted file mode 100644 index 3a7497d162..0000000000 --- a/third_party/SConscript +++ /dev/null @@ -1,3 +0,0 @@ -Import('env') - -env.Library('json11', ['json11/json11.cpp'], CCFLAGS=env['CCFLAGS'] + ['-Wno-unqualified-std-cast-call']) diff --git a/third_party/build.sh b/third_party/build.sh deleted file mode 100755 index d3a9c6579c..0000000000 --- a/third_party/build.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env bash -set -e - -DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" - -# Reproducible builds: pin timestamps to epoch -export SOURCE_DATE_EPOCH=0 -export ZERO_AR_DATE=1 - -pids=() -names=() -logs=() - -for script in "$DIR"/*/build.sh; do - [ -f "$script" ] || continue - name=$(basename "$(dirname "$script")") - log=$(mktemp) - names+=("$name") - logs+=("$log") - (cd "$(dirname "$script")" && bash "$(basename "$script")") >"$log" 2>&1 & - pids+=($!) -done - -failed=0 -for i in "${!pids[@]}"; do - echo "--- ${names[$i]} ---" - if wait "${pids[$i]}"; then - echo "OK" - else - echo "FAILED (exit $?)" - failed=1 - fi - cat "${logs[$i]}" - rm -f "${logs[$i]}" - echo -done - -[ $failed -ne 0 ] && exit $failed - -# Repack ar archives with deterministic headers (zero timestamps/uid/gid) -# Skip foreign-platform archives that ar can't read (e.g. Mach-O on Linux) -while IFS= read -r -d '' lib; do - tmpdir=$(mktemp -d) - lib=$(realpath "$lib") - if (cd "$tmpdir" && ar x "$lib" 2>/dev/null); then - (cd "$tmpdir" && ar Drcs repacked.a * && mv repacked.a "$lib") - fi - rm -rf "$tmpdir" -done < <(find "$DIR" -name '*.a' \ - \( -path '*/x86_64/*' -o -path '*/Darwin/*' -o -path '*/larch64/*' -o -path '*/aarch64/*' \) \ - -print0) - -echo -e "\033[32mAll third_party builds succeeded.\033[0m" diff --git a/third_party/json11/json11.cpp b/third_party/json11/json11.cpp deleted file mode 100644 index 3bd4fde2f2..0000000000 --- a/third_party/json11/json11.cpp +++ /dev/null @@ -1,785 +0,0 @@ -/* Copyright (c) 2013 Dropbox, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "json11.hpp" -#include -#include -#include -#include -#include -#include - -namespace json11 { - -static const int max_depth = 200; - -using std::string; -using std::vector; -using std::map; -using std::make_shared; -using std::initializer_list; -using std::move; - -/* Helper for representing null - just a do-nothing struct, plus comparison - * operators so the helpers in JsonValue work. We can't use nullptr_t because - * it may not be orderable. - */ -struct NullStruct { - bool operator==(NullStruct) const { return true; } - bool operator<(NullStruct) const { return false; } -}; - -/* * * * * * * * * * * * * * * * * * * * - * Serialization - */ - -static void dump(NullStruct, string &out) { - out += "null"; -} - -static void dump(double value, string &out) { - if (std::isfinite(value)) { - char buf[32]; - snprintf(buf, sizeof buf, "%.17g", value); - out += buf; - } else { - out += "null"; - } -} - -static void dump(int value, string &out) { - char buf[32]; - snprintf(buf, sizeof buf, "%d", value); - out += buf; -} - -static void dump(bool value, string &out) { - out += value ? "true" : "false"; -} - -static void dump(const string &value, string &out) { - out += '"'; - for (size_t i = 0; i < value.length(); i++) { - const char ch = value[i]; - if (ch == '\\') { - out += "\\\\"; - } else if (ch == '"') { - out += "\\\""; - } else if (ch == '\b') { - out += "\\b"; - } else if (ch == '\f') { - out += "\\f"; - } else if (ch == '\n') { - out += "\\n"; - } else if (ch == '\r') { - out += "\\r"; - } else if (ch == '\t') { - out += "\\t"; - } else if (static_cast(ch) <= 0x1f) { - char buf[8]; - snprintf(buf, sizeof buf, "\\u%04x", ch); - out += buf; - } else if (static_cast(ch) == 0xe2 && static_cast(value[i+1]) == 0x80 - && static_cast(value[i+2]) == 0xa8) { - out += "\\u2028"; - i += 2; - } else if (static_cast(ch) == 0xe2 && static_cast(value[i+1]) == 0x80 - && static_cast(value[i+2]) == 0xa9) { - out += "\\u2029"; - i += 2; - } else { - out += ch; - } - } - out += '"'; -} - -static void dump(const Json::array &values, string &out) { - bool first = true; - out += "["; - for (const auto &value : values) { - if (!first) - out += ", "; - value.dump(out); - first = false; - } - out += "]"; -} - -static void dump(const Json::object &values, string &out) { - bool first = true; - out += "{"; - for (const auto &kv : values) { - if (!first) - out += ", "; - dump(kv.first, out); - out += ": "; - kv.second.dump(out); - first = false; - } - out += "}"; -} - -void Json::dump(string &out) const { - m_ptr->dump(out); -} - -/* * * * * * * * * * * * * * * * * * * * - * Value wrappers - */ - -template -class Value : public JsonValue { -protected: - - // Constructors - explicit Value(const T &value) : m_value(value) {} - explicit Value(T &&value) : m_value(move(value)) {} - - // Get type tag - Json::Type type() const override { - return tag; - } - - // Comparisons - bool equals(const JsonValue * other) const override { - return m_value == static_cast *>(other)->m_value; - } - bool less(const JsonValue * other) const override { - return m_value < static_cast *>(other)->m_value; - } - - const T m_value; - void dump(string &out) const override { json11::dump(m_value, out); } -}; - -class JsonDouble final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return static_cast(m_value); } - bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } - bool less(const JsonValue * other) const override { return m_value < other->number_value(); } -public: - explicit JsonDouble(double value) : Value(value) {} -}; - -class JsonInt final : public Value { - double number_value() const override { return m_value; } - int int_value() const override { return m_value; } - bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } - bool less(const JsonValue * other) const override { return m_value < other->number_value(); } -public: - explicit JsonInt(int value) : Value(value) {} -}; - -class JsonBoolean final : public Value { - bool bool_value() const override { return m_value; } -public: - explicit JsonBoolean(bool value) : Value(value) {} -}; - -class JsonString final : public Value { - const string &string_value() const override { return m_value; } -public: - explicit JsonString(const string &value) : Value(value) {} - explicit JsonString(string &&value) : Value(move(value)) {} -}; - -class JsonArray final : public Value { - const Json::array &array_items() const override { return m_value; } - const Json & operator[](size_t i) const override; -public: - explicit JsonArray(const Json::array &value) : Value(value) {} - explicit JsonArray(Json::array &&value) : Value(move(value)) {} -}; - -class JsonObject final : public Value { - const Json::object &object_items() const override { return m_value; } - const Json & operator[](const string &key) const override; -public: - explicit JsonObject(const Json::object &value) : Value(value) {} - explicit JsonObject(Json::object &&value) : Value(move(value)) {} -}; - -class JsonNull final : public Value { -public: - JsonNull() : Value({}) {} -}; - -/* * * * * * * * * * * * * * * * * * * * - * Static globals - static-init-safe - */ -struct Statics { - const std::shared_ptr null = make_shared(); - const std::shared_ptr t = make_shared(true); - const std::shared_ptr f = make_shared(false); - const string empty_string; - const vector empty_vector; - const map empty_map; - Statics() {} -}; - -static const Statics & statics() { - static const Statics s {}; - return s; -} - -static const Json & static_null() { - // This has to be separate, not in Statics, because Json() accesses statics().null. - static const Json json_null; - return json_null; -} - -/* * * * * * * * * * * * * * * * * * * * - * Constructors - */ - -Json::Json() noexcept : m_ptr(statics().null) {} -Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {} -Json::Json(double value) : m_ptr(make_shared(value)) {} -Json::Json(int value) : m_ptr(make_shared(value)) {} -Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {} -Json::Json(const string &value) : m_ptr(make_shared(value)) {} -Json::Json(string &&value) : m_ptr(make_shared(move(value))) {} -Json::Json(const char * value) : m_ptr(make_shared(value)) {} -Json::Json(const Json::array &values) : m_ptr(make_shared(values)) {} -Json::Json(Json::array &&values) : m_ptr(make_shared(move(values))) {} -Json::Json(const Json::object &values) : m_ptr(make_shared(values)) {} -Json::Json(Json::object &&values) : m_ptr(make_shared(move(values))) {} - -/* * * * * * * * * * * * * * * * * * * * - * Accessors - */ - -Json::Type Json::type() const { return m_ptr->type(); } -double Json::number_value() const { return m_ptr->number_value(); } -int Json::int_value() const { return m_ptr->int_value(); } -bool Json::bool_value() const { return m_ptr->bool_value(); } -const string & Json::string_value() const { return m_ptr->string_value(); } -const vector & Json::array_items() const { return m_ptr->array_items(); } -const map & Json::object_items() const { return m_ptr->object_items(); } -const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; } -const Json & Json::operator[] (const string &key) const { return (*m_ptr)[key]; } - -double JsonValue::number_value() const { return 0; } -int JsonValue::int_value() const { return 0; } -bool JsonValue::bool_value() const { return false; } -const string & JsonValue::string_value() const { return statics().empty_string; } -const vector & JsonValue::array_items() const { return statics().empty_vector; } -const map & JsonValue::object_items() const { return statics().empty_map; } -const Json & JsonValue::operator[] (size_t) const { return static_null(); } -const Json & JsonValue::operator[] (const string &) const { return static_null(); } - -const Json & JsonObject::operator[] (const string &key) const { - auto iter = m_value.find(key); - return (iter == m_value.end()) ? static_null() : iter->second; -} -const Json & JsonArray::operator[] (size_t i) const { - if (i >= m_value.size()) return static_null(); - else return m_value[i]; -} - -/* * * * * * * * * * * * * * * * * * * * - * Comparison - */ - -bool Json::operator== (const Json &other) const { - if (m_ptr->type() != other.m_ptr->type()) - return false; - - return m_ptr->equals(other.m_ptr.get()); -} - -bool Json::operator< (const Json &other) const { - if (m_ptr->type() != other.m_ptr->type()) - return m_ptr->type() < other.m_ptr->type(); - - return m_ptr->less(other.m_ptr.get()); -} - -/* * * * * * * * * * * * * * * * * * * * - * Parsing - */ - -/* esc(c) - * - * Format char c suitable for printing in an error message. - */ -static inline string esc(char c) { - char buf[12]; - if (static_cast(c) >= 0x20 && static_cast(c) <= 0x7f) { - snprintf(buf, sizeof buf, "'%c' (%d)", c, c); - } else { - snprintf(buf, sizeof buf, "(%d)", c); - } - return string(buf); -} - -static inline bool in_range(long x, long lower, long upper) { - return (x >= lower && x <= upper); -} - -namespace { -/* JsonParser - * - * Object that tracks all state of an in-progress parse. - */ -struct JsonParser final { - - /* State - */ - const string &str; - size_t i; - string &err; - bool failed; - const JsonParse strategy; - - /* fail(msg, err_ret = Json()) - * - * Mark this parse as failed. - */ - Json fail(string &&msg) { - return fail(move(msg), Json()); - } - - template - T fail(string &&msg, const T err_ret) { - if (!failed) - err = std::move(msg); - failed = true; - return err_ret; - } - - /* consume_whitespace() - * - * Advance until the current character is non-whitespace. - */ - void consume_whitespace() { - while (str[i] == ' ' || str[i] == '\r' || str[i] == '\n' || str[i] == '\t') - i++; - } - - /* consume_comment() - * - * Advance comments (c-style inline and multiline). - */ - bool consume_comment() { - bool comment_found = false; - if (str[i] == '/') { - i++; - if (i == str.size()) - return fail("unexpected end of input after start of comment", false); - if (str[i] == '/') { // inline comment - i++; - // advance until next line, or end of input - while (i < str.size() && str[i] != '\n') { - i++; - } - comment_found = true; - } - else if (str[i] == '*') { // multiline comment - i++; - if (i > str.size()-2) - return fail("unexpected end of input inside multi-line comment", false); - // advance until closing tokens - while (!(str[i] == '*' && str[i+1] == '/')) { - i++; - if (i > str.size()-2) - return fail( - "unexpected end of input inside multi-line comment", false); - } - i += 2; - comment_found = true; - } - else - return fail("malformed comment", false); - } - return comment_found; - } - - /* consume_garbage() - * - * Advance until the current character is non-whitespace and non-comment. - */ - void consume_garbage() { - consume_whitespace(); - if(strategy == JsonParse::COMMENTS) { - bool comment_found = false; - do { - comment_found = consume_comment(); - if (failed) return; - consume_whitespace(); - } - while(comment_found); - } - } - - /* get_next_token() - * - * Return the next non-whitespace character. If the end of the input is reached, - * flag an error and return 0. - */ - char get_next_token() { - consume_garbage(); - if (failed) return (char)0; - if (i == str.size()) - return fail("unexpected end of input", (char)0); - - return str[i++]; - } - - /* encode_utf8(pt, out) - * - * Encode pt as UTF-8 and add it to out. - */ - void encode_utf8(long pt, string & out) { - if (pt < 0) - return; - - if (pt < 0x80) { - out += static_cast(pt); - } else if (pt < 0x800) { - out += static_cast((pt >> 6) | 0xC0); - out += static_cast((pt & 0x3F) | 0x80); - } else if (pt < 0x10000) { - out += static_cast((pt >> 12) | 0xE0); - out += static_cast(((pt >> 6) & 0x3F) | 0x80); - out += static_cast((pt & 0x3F) | 0x80); - } else { - out += static_cast((pt >> 18) | 0xF0); - out += static_cast(((pt >> 12) & 0x3F) | 0x80); - out += static_cast(((pt >> 6) & 0x3F) | 0x80); - out += static_cast((pt & 0x3F) | 0x80); - } - } - - /* parse_string() - * - * Parse a string, starting at the current position. - */ - string parse_string() { - string out; - long last_escaped_codepoint = -1; - while (true) { - if (i == str.size()) - return fail("unexpected end of input in string", ""); - - char ch = str[i++]; - - if (ch == '"') { - encode_utf8(last_escaped_codepoint, out); - return out; - } - - if (in_range(ch, 0, 0x1f)) - return fail("unescaped " + esc(ch) + " in string", ""); - - // The usual case: non-escaped characters - if (ch != '\\') { - encode_utf8(last_escaped_codepoint, out); - last_escaped_codepoint = -1; - out += ch; - continue; - } - - // Handle escapes - if (i == str.size()) - return fail("unexpected end of input in string", ""); - - ch = str[i++]; - - if (ch == 'u') { - // Extract 4-byte escape sequence - string esc = str.substr(i, 4); - // Explicitly check length of the substring. The following loop - // relies on std::string returning the terminating NUL when - // accessing str[length]. Checking here reduces brittleness. - if (esc.length() < 4) { - return fail("bad \\u escape: " + esc, ""); - } - for (size_t j = 0; j < 4; j++) { - if (!in_range(esc[j], 'a', 'f') && !in_range(esc[j], 'A', 'F') - && !in_range(esc[j], '0', '9')) - return fail("bad \\u escape: " + esc, ""); - } - - long codepoint = strtol(esc.data(), nullptr, 16); - - // JSON specifies that characters outside the BMP shall be encoded as a pair - // of 4-hex-digit \u escapes encoding their surrogate pair components. Check - // whether we're in the middle of such a beast: the previous codepoint was an - // escaped lead (high) surrogate, and this is a trail (low) surrogate. - if (in_range(last_escaped_codepoint, 0xD800, 0xDBFF) - && in_range(codepoint, 0xDC00, 0xDFFF)) { - // Reassemble the two surrogate pairs into one astral-plane character, per - // the UTF-16 algorithm. - encode_utf8((((last_escaped_codepoint - 0xD800) << 10) - | (codepoint - 0xDC00)) + 0x10000, out); - last_escaped_codepoint = -1; - } else { - encode_utf8(last_escaped_codepoint, out); - last_escaped_codepoint = codepoint; - } - - i += 4; - continue; - } - - encode_utf8(last_escaped_codepoint, out); - last_escaped_codepoint = -1; - - if (ch == 'b') { - out += '\b'; - } else if (ch == 'f') { - out += '\f'; - } else if (ch == 'n') { - out += '\n'; - } else if (ch == 'r') { - out += '\r'; - } else if (ch == 't') { - out += '\t'; - } else if (ch == '"' || ch == '\\' || ch == '/') { - out += ch; - } else { - return fail("invalid escape character " + esc(ch), ""); - } - } - } - - /* parse_number() - * - * Parse a double. - */ - Json parse_number() { - size_t start_pos = i; - - if (str[i] == '-') - i++; - - // Integer part - if (str[i] == '0') { - i++; - if (in_range(str[i], '0', '9')) - return fail("leading 0s not permitted in numbers"); - } else if (in_range(str[i], '1', '9')) { - i++; - while (in_range(str[i], '0', '9')) - i++; - } else { - return fail("invalid " + esc(str[i]) + " in number"); - } - - if (str[i] != '.' && str[i] != 'e' && str[i] != 'E' - && (i - start_pos) <= static_cast(std::numeric_limits::digits10)) { - return std::atoi(str.c_str() + start_pos); - } - - // Decimal part - if (str[i] == '.') { - i++; - if (!in_range(str[i], '0', '9')) - return fail("at least one digit required in fractional part"); - - while (in_range(str[i], '0', '9')) - i++; - } - - // Exponent part - if (str[i] == 'e' || str[i] == 'E') { - i++; - - if (str[i] == '+' || str[i] == '-') - i++; - - if (!in_range(str[i], '0', '9')) - return fail("at least one digit required in exponent"); - - while (in_range(str[i], '0', '9')) - i++; - } - - return std::strtod(str.c_str() + start_pos, nullptr); - } - - /* expect(str, res) - * - * Expect that 'str' starts at the character that was just read. If it does, advance - * the input and return res. If not, flag an error. - */ - Json expect(const string &expected, Json res) { - assert(i != 0); - i--; - if (str.compare(i, expected.length(), expected) == 0) { - i += expected.length(); - return res; - } else { - return fail("parse error: expected " + expected + ", got " + str.substr(i, expected.length())); - } - } - - /* parse_json() - * - * Parse a JSON object. - */ - Json parse_json(int depth) { - if (depth > max_depth) { - return fail("exceeded maximum nesting depth"); - } - - char ch = get_next_token(); - if (failed) - return Json(); - - if (ch == '-' || (ch >= '0' && ch <= '9')) { - i--; - return parse_number(); - } - - if (ch == 't') - return expect("true", true); - - if (ch == 'f') - return expect("false", false); - - if (ch == 'n') - return expect("null", Json()); - - if (ch == '"') - return parse_string(); - - if (ch == '{') { - map data; - ch = get_next_token(); - if (ch == '}') - return data; - - while (1) { - if (ch != '"') - return fail("expected '\"' in object, got " + esc(ch)); - - string key = parse_string(); - if (failed) - return Json(); - - ch = get_next_token(); - if (ch != ':') - return fail("expected ':' in object, got " + esc(ch)); - - data[std::move(key)] = parse_json(depth + 1); - if (failed) - return Json(); - - ch = get_next_token(); - if (ch == '}') - break; - if (ch != ',') - return fail("expected ',' in object, got " + esc(ch)); - - ch = get_next_token(); - } - return data; - } - - if (ch == '[') { - vector data; - ch = get_next_token(); - if (ch == ']') - return data; - - while (1) { - i--; - data.push_back(parse_json(depth + 1)); - if (failed) - return Json(); - - ch = get_next_token(); - if (ch == ']') - break; - if (ch != ',') - return fail("expected ',' in list, got " + esc(ch)); - - ch = get_next_token(); - (void)ch; - } - return data; - } - - return fail("expected value, got " + esc(ch)); - } -}; -}//namespace { - -Json Json::parse(const string &in, string &err, JsonParse strategy) { - JsonParser parser { in, 0, err, false, strategy }; - Json result = parser.parse_json(0); - - // Check for any trailing garbage - parser.consume_garbage(); - if (parser.failed) - return Json(); - if (parser.i != in.size()) - return parser.fail("unexpected trailing " + esc(in[parser.i])); - - return result; -} - -// Documented in json11.hpp -vector Json::parse_multi(const string &in, - std::string::size_type &parser_stop_pos, - string &err, - JsonParse strategy) { - JsonParser parser { in, 0, err, false, strategy }; - parser_stop_pos = 0; - vector json_vec; - while (parser.i != in.size() && !parser.failed) { - json_vec.push_back(parser.parse_json(0)); - if (parser.failed) - break; - - // Check for another object - parser.consume_garbage(); - if (parser.failed) - break; - parser_stop_pos = parser.i; - } - return json_vec; -} - -/* * * * * * * * * * * * * * * * * * * * - * Shape-checking - */ - -bool Json::has_shape(const shape & types, string & err) const { - if (!is_object()) { - err = "expected JSON object, got " + dump(); - return false; - } - - for (auto & item : types) { - if ((*this)[item.first].type() != item.second) { - err = "bad type for " + item.first + " in " + dump(); - return false; - } - } - - return true; -} - -} // namespace json11 diff --git a/third_party/json11/json11.hpp b/third_party/json11/json11.hpp deleted file mode 100644 index 5202ef9323..0000000000 --- a/third_party/json11/json11.hpp +++ /dev/null @@ -1,232 +0,0 @@ -/* json11 - * - * json11 is a tiny JSON library for C++11, providing JSON parsing and serialization. - * - * The core object provided by the library is json11::Json. A Json object represents any JSON - * value: null, bool, number (int or double), string (std::string), array (std::vector), or - * object (std::map). - * - * Json objects act like values: they can be assigned, copied, moved, compared for equality or - * order, etc. There are also helper methods Json::dump, to serialize a Json to a string, and - * Json::parse (static) to parse a std::string as a Json object. - * - * Internally, the various types of Json object are represented by the JsonValue class - * hierarchy. - * - * A note on numbers - JSON specifies the syntax of number formatting but not its semantics, - * so some JSON implementations distinguish between integers and floating-point numbers, while - * some don't. In json11, we choose the latter. Because some JSON implementations (namely - * Javascript itself) treat all numbers as the same type, distinguishing the two leads - * to JSON that will be *silently* changed by a round-trip through those implementations. - * Dangerous! To avoid that risk, json11 stores all numbers as double internally, but also - * provides integer helpers. - * - * Fortunately, double-precision IEEE754 ('double') can precisely store any integer in the - * range +/-2^53, which includes every 'int' on most systems. (Timestamps often use int64 - * or long long to avoid the Y2038K problem; a double storing microseconds since some epoch - * will be exact for +/- 275 years.) - */ - -/* Copyright (c) 2013 Dropbox, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#include -#include -#include -#include -#include - -#ifdef _MSC_VER - #if _MSC_VER <= 1800 // VS 2013 - #ifndef noexcept - #define noexcept throw() - #endif - - #ifndef snprintf - #define snprintf _snprintf_s - #endif - #endif -#endif - -namespace json11 { - -enum JsonParse { - STANDARD, COMMENTS -}; - -class JsonValue; - -class Json final { -public: - // Types - enum Type { - NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT - }; - - // Array and object typedefs - typedef std::vector array; - typedef std::map object; - - // Constructors for the various types of JSON value. - Json() noexcept; // NUL - Json(std::nullptr_t) noexcept; // NUL - Json(double value); // NUMBER - Json(int value); // NUMBER - Json(bool value); // BOOL - Json(const std::string &value); // STRING - Json(std::string &&value); // STRING - Json(const char * value); // STRING - Json(const array &values); // ARRAY - Json(array &&values); // ARRAY - Json(const object &values); // OBJECT - Json(object &&values); // OBJECT - - // Implicit constructor: anything with a to_json() function. - template - Json(const T & t) : Json(t.to_json()) {} - - // Implicit constructor: map-like objects (std::map, std::unordered_map, etc) - template ::value - && std::is_constructible::value, - int>::type = 0> - Json(const M & m) : Json(object(m.begin(), m.end())) {} - - // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc) - template ::value, - int>::type = 0> - Json(const V & v) : Json(array(v.begin(), v.end())) {} - - // This prevents Json(some_pointer) from accidentally producing a bool. Use - // Json(bool(some_pointer)) if that behavior is desired. - Json(void *) = delete; - - // Accessors - Type type() const; - - bool is_null() const { return type() == NUL; } - bool is_number() const { return type() == NUMBER; } - bool is_bool() const { return type() == BOOL; } - bool is_string() const { return type() == STRING; } - bool is_array() const { return type() == ARRAY; } - bool is_object() const { return type() == OBJECT; } - - // Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not - // distinguish between integer and non-integer numbers - number_value() and int_value() - // can both be applied to a NUMBER-typed object. - double number_value() const; - int int_value() const; - - // Return the enclosed value if this is a boolean, false otherwise. - bool bool_value() const; - // Return the enclosed string if this is a string, "" otherwise. - const std::string &string_value() const; - // Return the enclosed std::vector if this is an array, or an empty vector otherwise. - const array &array_items() const; - // Return the enclosed std::map if this is an object, or an empty map otherwise. - const object &object_items() const; - - // Return a reference to arr[i] if this is an array, Json() otherwise. - const Json & operator[](size_t i) const; - // Return a reference to obj[key] if this is an object, Json() otherwise. - const Json & operator[](const std::string &key) const; - - // Serialize. - void dump(std::string &out) const; - std::string dump() const { - std::string out; - dump(out); - return out; - } - - // Parse. If parse fails, return Json() and assign an error message to err. - static Json parse(const std::string & in, - std::string & err, - JsonParse strategy = JsonParse::STANDARD); - static Json parse(const char * in, - std::string & err, - JsonParse strategy = JsonParse::STANDARD) { - if (in) { - return parse(std::string(in), err, strategy); - } else { - err = "null input"; - return nullptr; - } - } - // Parse multiple objects, concatenated or separated by whitespace - static std::vector parse_multi( - const std::string & in, - std::string::size_type & parser_stop_pos, - std::string & err, - JsonParse strategy = JsonParse::STANDARD); - - static inline std::vector parse_multi( - const std::string & in, - std::string & err, - JsonParse strategy = JsonParse::STANDARD) { - std::string::size_type parser_stop_pos; - return parse_multi(in, parser_stop_pos, err, strategy); - } - - bool operator== (const Json &rhs) const; - bool operator< (const Json &rhs) const; - bool operator!= (const Json &rhs) const { return !(*this == rhs); } - bool operator<= (const Json &rhs) const { return !(rhs < *this); } - bool operator> (const Json &rhs) const { return (rhs < *this); } - bool operator>= (const Json &rhs) const { return !(*this < rhs); } - - /* has_shape(types, err) - * - * Return true if this is a JSON object and, for each item in types, has a field of - * the given type. If not, return false and set err to a descriptive message. - */ - typedef std::initializer_list> shape; - bool has_shape(const shape & types, std::string & err) const; - -private: - std::shared_ptr m_ptr; -}; - -// Internal class hierarchy - JsonValue objects are not exposed to users of this API. -class JsonValue { -protected: - friend class Json; - friend class JsonInt; - friend class JsonDouble; - virtual Json::Type type() const = 0; - virtual bool equals(const JsonValue * other) const = 0; - virtual bool less(const JsonValue * other) const = 0; - virtual void dump(std::string &out) const = 0; - virtual double number_value() const; - virtual int int_value() const; - virtual bool bool_value() const; - virtual const std::string &string_value() const; - virtual const Json::array &array_items() const; - virtual const Json &operator[](size_t i) const; - virtual const Json::object &object_items() const; - virtual const Json &operator[](const std::string &key) const; - virtual ~JsonValue() {} -}; - -} // namespace json11 diff --git a/tools/jotpluggler/app.cc b/tools/jotpluggler/app.cc index efc848494c..22a9f9021c 100644 --- a/tools/jotpluggler/app.cc +++ b/tools/jotpluggler/app.cc @@ -27,7 +27,7 @@ #include #include -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" namespace fs = std::filesystem; diff --git a/tools/jotpluggler/custom_series.cc b/tools/jotpluggler/custom_series.cc index 568f7e97c3..aabf78a0db 100644 --- a/tools/jotpluggler/custom_series.cc +++ b/tools/jotpluggler/custom_series.cc @@ -11,7 +11,7 @@ #include #include -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" namespace fs = std::filesystem; diff --git a/tools/jotpluggler/layout_io.cc b/tools/jotpluggler/layout_io.cc index f984c0f0e8..5c70f7a42a 100644 --- a/tools/jotpluggler/layout_io.cc +++ b/tools/jotpluggler/layout_io.cc @@ -6,7 +6,7 @@ #include #include -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" namespace fs = std::filesystem; diff --git a/tools/jotpluggler/map.cc b/tools/jotpluggler/map.cc index 8725908ea0..fb4e03c912 100644 --- a/tools/jotpluggler/map.cc +++ b/tools/jotpluggler/map.cc @@ -25,7 +25,7 @@ extern "C" { #include #include "common/util.h" -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" namespace fs = std::filesystem; diff --git a/tools/jotpluggler/sketch_layout.cc b/tools/jotpluggler/sketch_layout.cc index c44a4e93cd..2091280169 100644 --- a/tools/jotpluggler/sketch_layout.cc +++ b/tools/jotpluggler/sketch_layout.cc @@ -23,7 +23,7 @@ #include #include "common/util.h" -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" #include "tools/replay/logreader.h" #include "tools/replay/py_downloader.h" diff --git a/tools/replay/route.cc b/tools/replay/route.cc index e7b8ed6bba..df4fa813cf 100644 --- a/tools/replay/route.cc +++ b/tools/replay/route.cc @@ -4,7 +4,7 @@ #include #include -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" #include "system/hardware/hw.h" #include "tools/replay/py_downloader.h" #include "tools/replay/replay.h" diff --git a/tools/replay/route.h b/tools/replay/route.h index 119a81152e..50f3eba854 100644 --- a/tools/replay/route.h +++ b/tools/replay/route.h @@ -8,7 +8,7 @@ #include #include -#include "third_party/json11/json11.hpp" +#include "json11/json11.hpp" #include "tools/replay/framereader.h" #include "tools/replay/logreader.h" #include "tools/replay/util.h"