/* Copyright 2020 Istio Authors. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "json_util.h" #include #include "absl/strings/numbers.h" namespace Wasm { namespace Common { std::optional JsonParse(std::string_view str) { const auto result = JsonObject::parse(str, nullptr, false); if (result.is_discarded() || !result.is_object()) { return std::nullopt; } return result; } template <> std::pair, JsonParserResultDetail> JsonValueAs( const JsonObject& j) { if (j.is_number()) { return std::make_pair(j.get(), JsonParserResultDetail::OK); } else if (j.is_string()) { int64_t result = 0; if (absl::SimpleAtoi(j.get_ref(), &result)) { return std::make_pair(result, JsonParserResultDetail::OK); } else { return std::make_pair(std::nullopt, JsonParserResultDetail::INVALID_VALUE); } } return std::make_pair(std::nullopt, JsonParserResultDetail::TYPE_ERROR); } template <> std::pair, JsonParserResultDetail> JsonValueAs(const JsonObject& j) { if (j.is_number()) { return std::make_pair(j.get(), JsonParserResultDetail::OK); } else if (j.is_string()) { uint64_t result = 0; if (absl::SimpleAtoi(j.get_ref(), &result)) { return std::make_pair(result, JsonParserResultDetail::OK); } else { return std::make_pair(std::nullopt, JsonParserResultDetail::INVALID_VALUE); } } return std::make_pair(std::nullopt, JsonParserResultDetail::TYPE_ERROR); } template <> std::pair, JsonParserResultDetail> JsonValueAs(const JsonObject& j) { if (j.is_string()) { return std::make_pair(std::string_view(j.get_ref()), JsonParserResultDetail::OK); } return std::make_pair(std::nullopt, JsonParserResultDetail::TYPE_ERROR); } template <> std::pair, JsonParserResultDetail> JsonValueAs(const JsonObject& j) { if (j.is_string()) { return std::make_pair(j.get_ref(), JsonParserResultDetail::OK); } if (j.is_number_unsigned()) { return std::make_pair( std::to_string((unsigned long long)(j.get())), JsonParserResultDetail::OK); } return std::make_pair(std::nullopt, JsonParserResultDetail::TYPE_ERROR); } template <> std::pair, JsonParserResultDetail> JsonValueAs( const JsonObject& j) { if (j.is_boolean()) { return std::make_pair(j.get(), JsonParserResultDetail::OK); } if (j.is_string()) { const std::string& v = j.get_ref(); if (v == "true") { return std::make_pair(true, JsonParserResultDetail::OK); } else if (v == "false") { return std::make_pair(false, JsonParserResultDetail::OK); } else { return std::make_pair(std::nullopt, JsonParserResultDetail::INVALID_VALUE); } } return std::make_pair(std::nullopt, JsonParserResultDetail::TYPE_ERROR); } template <> std::pair>, JsonParserResultDetail> JsonValueAs>(const JsonObject& j) { std::pair>, JsonParserResultDetail> values = std::make_pair(std::nullopt, JsonParserResultDetail::OK); if (j.is_array()) { for (const auto& elt : j) { if (!elt.is_string()) { values.first = std::nullopt; values.second = JsonParserResultDetail::TYPE_ERROR; return values; } if (!values.first.has_value()) { values.first = std::vector(); } values.first->emplace_back(elt.get_ref()); } return values; } values.second = JsonParserResultDetail::TYPE_ERROR; return values; } template <> std::pair, JsonParserResultDetail> JsonValueAs(const JsonObject& j) { if (j.is_object()) { return std::make_pair(j.get(), JsonParserResultDetail::OK); } return std::make_pair(std::nullopt, JsonParserResultDetail::TYPE_ERROR); } bool JsonArrayIterate( const JsonObject& j, std::string_view field, const std::function& visitor) { auto it = j.find(field); if (it == j.end()) { return true; } if (!it.value().is_array()) { return false; } for (const auto& elt : it.value().items()) { if (!visitor(elt.value())) { return false; } } return true; } bool JsonObjectIterate(const JsonObject& j, std::string_view field, const std::function& visitor) { auto it = j.find(field); if (it == j.end()) { return true; } if (!it.value().is_object()) { return false; } for (const auto& elt : it.value().items()) { auto json_value = JsonValueAs(elt.key()); if (json_value.second != JsonParserResultDetail::OK) { return false; } if (!visitor(json_value.first.value())) { return false; } } return true; } bool JsonObjectIterate(const JsonObject& j, const std::function& visitor) { for (const auto& elt : j.items()) { auto json_value = JsonValueAs(elt.key()); if (json_value.second != JsonParserResultDetail::OK) { return false; } if (!visitor(json_value.first.value())) { return false; } } return true; } } // namespace Common } // namespace Wasm