diff options
Diffstat (limited to 'chromium/components/cbor/values.cc')
-rw-r--r-- | chromium/components/cbor/values.cc | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/chromium/components/cbor/values.cc b/chromium/components/cbor/values.cc new file mode 100644 index 00000000000..f495a7fd152 --- /dev/null +++ b/chromium/components/cbor/values.cc @@ -0,0 +1,281 @@ +// Copyright 2017 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 "components/cbor/values.h" + +#include <new> +#include <utility> + +#include "base/numerics/safe_conversions.h" +#include "base/strings/string_util.h" +#include "components/cbor/constants.h" + +namespace cbor { + +Value::Value() noexcept : type_(Type::NONE) {} + +Value::Value(Value&& that) noexcept { + InternalMoveConstructFrom(std::move(that)); +} + +Value::Value(Type type) : type_(type) { + // Initialize with the default value. + switch (type_) { + case Type::UNSIGNED: + case Type::NEGATIVE: + integer_value_ = 0; + return; + case Type::BYTE_STRING: + new (&bytestring_value_) BinaryValue(); + return; + case Type::STRING: + new (&string_value_) std::string(); + return; + case Type::ARRAY: + new (&array_value_) ArrayValue(); + return; + case Type::MAP: + new (&map_value_) MapValue(); + return; + case Type::TAG: + NOTREACHED() << constants::kUnsupportedMajorType; + return; + case Type::SIMPLE_VALUE: + simple_value_ = Value::SimpleValue::UNDEFINED; + return; + case Type::NONE: + return; + } + NOTREACHED(); +} + +Value::Value(SimpleValue in_simple) + : type_(Type::SIMPLE_VALUE), simple_value_(in_simple) { + CHECK(static_cast<int>(in_simple) >= 20 && static_cast<int>(in_simple) <= 23); +} + +Value::Value(bool boolean_value) : type_(Type::SIMPLE_VALUE) { + simple_value_ = boolean_value ? Value::SimpleValue::TRUE_VALUE + : Value::SimpleValue::FALSE_VALUE; +} + +Value::Value(int integer_value) + : Value(base::checked_cast<int64_t>(integer_value)) {} + +Value::Value(int64_t integer_value) : integer_value_(integer_value) { + type_ = integer_value >= 0 ? Type::UNSIGNED : Type::NEGATIVE; +} + +Value::Value(base::span<const uint8_t> in_bytes) + : type_(Type::BYTE_STRING), + bytestring_value_(in_bytes.begin(), in_bytes.end()) {} + +Value::Value(BinaryValue&& in_bytes) noexcept + : type_(Type::BYTE_STRING), bytestring_value_(std::move(in_bytes)) {} + +Value::Value(const char* in_string, Type type) + : Value(base::StringPiece(in_string), type) {} + +Value::Value(std::string&& in_string, Type type) noexcept : type_(type) { + switch (type_) { + case Type::STRING: + new (&string_value_) std::string(); + string_value_ = std::move(in_string); + DCHECK(base::IsStringUTF8(string_value_)); + break; + case Type::BYTE_STRING: + new (&bytestring_value_) BinaryValue(); + bytestring_value_ = BinaryValue(in_string.begin(), in_string.end()); + break; + default: + NOTREACHED(); + } +} + +Value::Value(base::StringPiece in_string, Type type) : type_(type) { + switch (type_) { + case Type::STRING: + new (&string_value_) std::string(); + string_value_ = in_string.as_string(); + DCHECK(base::IsStringUTF8(string_value_)); + break; + case Type::BYTE_STRING: + new (&bytestring_value_) BinaryValue(); + bytestring_value_ = BinaryValue(in_string.begin(), in_string.end()); + break; + default: + NOTREACHED(); + } +} + +Value::Value(const ArrayValue& in_array) : type_(Type::ARRAY), array_value_() { + array_value_.reserve(in_array.size()); + for (const auto& val : in_array) + array_value_.emplace_back(val.Clone()); +} + +Value::Value(ArrayValue&& in_array) noexcept + : type_(Type::ARRAY), array_value_(std::move(in_array)) {} + +Value::Value(const MapValue& in_map) : type_(Type::MAP), map_value_() { + map_value_.reserve(in_map.size()); + for (const auto& it : in_map) + map_value_.emplace_hint(map_value_.end(), it.first.Clone(), + it.second.Clone()); +} + +Value::Value(MapValue&& in_map) noexcept + : type_(Type::MAP), map_value_(std::move(in_map)) {} + +Value& Value::operator=(Value&& that) noexcept { + InternalCleanup(); + InternalMoveConstructFrom(std::move(that)); + + return *this; +} + +Value::~Value() { + InternalCleanup(); +} + +Value Value::Clone() const { + switch (type_) { + case Type::NONE: + return Value(); + case Type::UNSIGNED: + case Type::NEGATIVE: + return Value(integer_value_); + case Type::BYTE_STRING: + return Value(bytestring_value_); + case Type::STRING: + return Value(string_value_); + case Type::ARRAY: + return Value(array_value_); + case Type::MAP: + return Value(map_value_); + case Type::TAG: + NOTREACHED() << constants::kUnsupportedMajorType; + return Value(); + case Type::SIMPLE_VALUE: + return Value(simple_value_); + } + + NOTREACHED(); + return Value(); +} + +Value::SimpleValue Value::GetSimpleValue() const { + CHECK(is_simple()); + return simple_value_; +} + +bool Value::GetBool() const { + CHECK(is_bool()); + return simple_value_ == SimpleValue::TRUE_VALUE; +} + +const int64_t& Value::GetInteger() const { + CHECK(is_integer()); + return integer_value_; +} + +const int64_t& Value::GetUnsigned() const { + CHECK(is_unsigned()); + CHECK_GE(integer_value_, 0); + return integer_value_; +} + +const int64_t& Value::GetNegative() const { + CHECK(is_negative()); + CHECK_LT(integer_value_, 0); + return integer_value_; +} + +const std::string& Value::GetString() const { + CHECK(is_string()); + return string_value_; +} + +const Value::BinaryValue& Value::GetBytestring() const { + CHECK(is_bytestring()); + return bytestring_value_; +} + +base::StringPiece Value::GetBytestringAsString() const { + CHECK(is_bytestring()); + const auto& bytestring_value = GetBytestring(); + return base::StringPiece( + reinterpret_cast<const char*>(bytestring_value.data()), + bytestring_value.size()); +} + +const Value::ArrayValue& Value::GetArray() const { + CHECK(is_array()); + return array_value_; +} + +const Value::MapValue& Value::GetMap() const { + CHECK(is_map()); + return map_value_; +} + +void Value::InternalMoveConstructFrom(Value&& that) { + type_ = that.type_; + + switch (type_) { + case Type::UNSIGNED: + case Type::NEGATIVE: + integer_value_ = that.integer_value_; + return; + case Type::BYTE_STRING: + new (&bytestring_value_) BinaryValue(std::move(that.bytestring_value_)); + return; + case Type::STRING: + new (&string_value_) std::string(std::move(that.string_value_)); + return; + case Type::ARRAY: + new (&array_value_) ArrayValue(std::move(that.array_value_)); + return; + case Type::MAP: + new (&map_value_) MapValue(std::move(that.map_value_)); + return; + case Type::TAG: + NOTREACHED() << constants::kUnsupportedMajorType; + return; + case Type::SIMPLE_VALUE: + simple_value_ = that.simple_value_; + return; + case Type::NONE: + return; + } + NOTREACHED(); +} + +void Value::InternalCleanup() { + switch (type_) { + case Type::BYTE_STRING: + bytestring_value_.~BinaryValue(); + break; + case Type::STRING: + string_value_.~basic_string(); + break; + case Type::ARRAY: + array_value_.~ArrayValue(); + break; + case Type::MAP: + map_value_.~MapValue(); + break; + case Type::TAG: + NOTREACHED() << constants::kUnsupportedMajorType; + break; + case Type::NONE: + case Type::UNSIGNED: + case Type::NEGATIVE: + case Type::SIMPLE_VALUE: + break; + } + type_ = Type::NONE; +} + +} // namespace cbor |