diff options
Diffstat (limited to 'src/components/utils/src/json_utils.cc')
-rw-r--r-- | src/components/utils/src/json_utils.cc | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/src/components/utils/src/json_utils.cc b/src/components/utils/src/json_utils.cc new file mode 100644 index 0000000000..5c36f5e660 --- /dev/null +++ b/src/components/utils/src/json_utils.cc @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following + * disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * Neither the name of the Ford Motor Company nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "utils/json_utils.h" + +#include <iterator> + +namespace { + +Json::Value CreateStorage(const utils::json::ValueType::Type type) { + using namespace utils::json; + switch (type) { + case ValueType::OBJECT_VALUE: + return Json::Value(Json::objectValue); + case ValueType::ARRAY_VALUE: + return Json::Value(Json::arrayValue); + case ValueType::BOOL_VALUE: + return Json::Value(Json::booleanValue); + case ValueType::STRING_VALUE: + return Json::Value(Json::stringValue); + case ValueType::INT_VALUE: + return Json::Value(Json::intValue); + case ValueType::UINT_VALUE: + return Json::Value(Json::uintValue); + case ValueType::REAL_VALUE: + return Json::Value(Json::realValue); + default: + return Json::Value(); + } + DCHECK(type == ValueType::NULL_VALUE); + return Json::Value(); +} + +utils::json::ValueType::Type GetType(const Json::Value& value) { + using namespace utils::json; + const Json::ValueType type = value.type(); + switch (type) { + case Json::objectValue: + return ValueType::OBJECT_VALUE; + case Json::arrayValue: + return ValueType::ARRAY_VALUE; + case Json::booleanValue: + return ValueType::BOOL_VALUE; + case Json::stringValue: + return ValueType::STRING_VALUE; + case Json::intValue: + return ValueType::INT_VALUE; + case Json::uintValue: + return ValueType::UINT_VALUE; + case Json::realValue: + return ValueType::REAL_VALUE; + default: + return ValueType::NULL_VALUE; + } + DCHECK(type == Json::nullValue); + return ValueType::NULL_VALUE; +} + +utils::json::JsonValue::Storage& GetObjectItemByIndex( + utils::json::JsonValue::Storage& storage, + utils::json::JsonValue::ArrayIndex index) { + DCHECK(storage.isObject()); + DCHECK(storage.isValidIndex(index)); + utils::json::JsonValue::Storage::iterator itr = storage.begin(); + for (utils::json::JsonValue::ArrayIndex cnt = 0; cnt < index; ++cnt) { + ++itr; + } + return *itr; +} + +utils::json::JsonValue GetKeyByIndex( + const utils::json::JsonValue::Storage& storage, + utils::json::JsonValue::ArrayIndex index) { + DCHECK(storage.isObject()); + DCHECK(storage.isValidIndex(index)); + utils::json::JsonValue::Storage::iterator itr = storage.begin(); + for (utils::json::JsonValue::ArrayIndex cnt = 0; cnt < index; ++cnt) { + ++itr; + } + return itr.key(); +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +/// class utils::json::JsonValueRef +//////////////////////////////////////////////////////////////////////////////// + +utils::json::JsonValueRef::JsonValueRef(JsonValue::Storage& storage, + const char* key) + : storage_(&storage), kind_(Key) { + storage_ = &(storage[key]); +} + +utils::json::JsonValueRef::JsonValueRef(JsonValue::Storage& storage, + JsonValue::ArrayIndex index) + : storage_(&storage), kind_(Index) { + storage_ = &(storage[index]); +} + +utils::json::JsonValueRef::JsonValueRef(JsonValue::Storage& storage, + JsonValue::ArrayIndex index, + Kind kind) + : storage_(&storage), kind_(kind) { + // This ctor is used from iterators, thus Map\List should be already present + if (kind_ == Key) { + storage_ = &GetObjectItemByIndex(storage, index); + } else if (kind_ == Index) { + storage_ = &(storage[index]); + } else { + DCHECK(kind_ == None); + } +} + +void utils::json::JsonValueRef::Clear() { + DCHECK(IsValid()); + storage_->clear(); +} + +utils::json::JsonValueRef::Kind utils::json::JsonValueRef::GetKind( + const ValueType::Type type) { + JsonValueRef::Kind kind = JsonValueRef::None; + if (type == ValueType::ARRAY_VALUE) { + kind = JsonValueRef::Index; + } else if (type == ValueType::OBJECT_VALUE) { + kind = JsonValueRef::Key; + } + return kind; +} + +//////////////////////////////////////////////////////////////////////////////// +/// class utils::json::JsonValue +//////////////////////////////////////////////////////////////////////////////// + +utils::json::JsonValue::JsonValue(const std::string& value) : storage_(value) {} + +utils::json::JsonValue::JsonValue(ValueType::Type type) + : storage_(CreateStorage(type)) {} + +utils::json::JsonValue::ParseResult utils::json::JsonValue::Parse( + const std::string& document) { + Storage storage; + Json::Reader reader; + bool is_parsed = reader.parse(document, storage, false); + if (!is_parsed) { + return std::make_pair(JsonValue(ValueType::NULL_VALUE), false); + } + return std::make_pair(JsonValue(storage), true); +} + +bool utils::json::JsonValue::HasMember(const char* key) const { + return storage_.isMember(key); +} + +utils::json::JsonValue utils::json::JsonValue::Get( + const char* key, const JsonValue& default_value) const { + return storage_.get(key, default_value.storage_); +} + +std::string utils::json::JsonValue::AsString() const { + return storage_.asString(); +} + +utils::json::JsonValue::Int utils::json::JsonValue::AsInt() const { + return storage_.asInt64(); +} + +utils::json::JsonValue::UInt utils::json::JsonValue::AsUInt() const { + return storage_.asUInt64(); +} + +bool utils::json::JsonValue::AsBool() const { + return storage_.asBool(); +} + +double utils::json::JsonValue::AsDouble() const { + return storage_.asDouble(); +} + +utils::json::JsonValue::ArrayIndex utils::json::JsonValue::Size() const { + return storage_.size(); +} + +utils::json::ValueType::Type utils::json::JsonValue::Type() const { + return GetType(storage_); +} + +utils::json::JsonValue::Members utils::json::JsonValue::GetMemberNames() const { + return storage_.getMemberNames(); +} + +bool utils::json::JsonValue::IsEmpty() const { + return storage_.empty(); +} + +std::string utils::json::JsonValue::ToJson(const bool styled) const { + if (styled) { + return storage_.toStyledString(); + } + Json::FastWriter writer; + std::string result = writer.write(storage_); + // cut off the last '\n' which is added be jsoncpp + if (result[result.size() - 1] == '\n') { + result.erase(result.size() - 1, 1); + } + return result; +} + +void utils::json::JsonValue::Clear() { + storage_.clear(); +} + +//////////////////////////////////////////////////////////////////////////////// +/// class utils::json::JsonValue::iterator +//////////////////////////////////////////////////////////////////////////////// + +utils::json::JsonValue utils::json::JsonValue::iterator::key() const { + return GetKeyByIndex(*storage_, index_); +} + +//////////////////////////////////////////////////////////////////////////////// +/// class utils::json::JsonValue::const_iterator +//////////////////////////////////////////////////////////////////////////////// + +utils::json::JsonValue utils::json::JsonValue::const_iterator::key() const { + return GetKeyByIndex(*storage_, index_); +} |