values.cc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/cbor/values.h"
  5. #include <new>
  6. #include <ostream>
  7. #include <utility>
  8. #include "base/check_op.h"
  9. #include "base/notreached.h"
  10. #include "base/numerics/safe_conversions.h"
  11. #include "base/strings/string_piece.h"
  12. #include "base/strings/string_util.h"
  13. #include "components/cbor/constants.h"
  14. namespace cbor {
  15. // static
  16. Value Value::InvalidUTF8StringValueForTesting(base::StringPiece in_string) {
  17. return Value(
  18. base::span<const uint8_t>(
  19. reinterpret_cast<const uint8_t*>(in_string.data()), in_string.size()),
  20. Type::INVALID_UTF8);
  21. }
  22. Value::Value() noexcept : type_(Type::NONE) {}
  23. Value::Value(Value&& that) noexcept {
  24. InternalMoveConstructFrom(std::move(that));
  25. }
  26. Value::Value(Type type) : type_(type) {
  27. // Initialize with the default value.
  28. switch (type_) {
  29. case Type::UNSIGNED:
  30. case Type::NEGATIVE:
  31. integer_value_ = 0;
  32. return;
  33. case Type::INVALID_UTF8:
  34. case Type::BYTE_STRING:
  35. new (&bytestring_value_) BinaryValue();
  36. return;
  37. case Type::STRING:
  38. new (&string_value_) std::string();
  39. return;
  40. case Type::ARRAY:
  41. new (&array_value_) ArrayValue();
  42. return;
  43. case Type::MAP:
  44. new (&map_value_) MapValue();
  45. return;
  46. case Type::TAG:
  47. NOTREACHED() << constants::kUnsupportedMajorType;
  48. return;
  49. case Type::SIMPLE_VALUE:
  50. simple_value_ = Value::SimpleValue::UNDEFINED;
  51. return;
  52. case Type::NONE:
  53. return;
  54. }
  55. NOTREACHED();
  56. }
  57. Value::Value(SimpleValue in_simple)
  58. : type_(Type::SIMPLE_VALUE), simple_value_(in_simple) {
  59. CHECK(static_cast<int>(in_simple) >= 20 && static_cast<int>(in_simple) <= 23);
  60. }
  61. Value::Value(bool boolean_value) : type_(Type::SIMPLE_VALUE) {
  62. simple_value_ = boolean_value ? Value::SimpleValue::TRUE_VALUE
  63. : Value::SimpleValue::FALSE_VALUE;
  64. }
  65. Value::Value(int integer_value)
  66. : Value(base::checked_cast<int64_t>(integer_value)) {}
  67. Value::Value(int64_t integer_value) : integer_value_(integer_value) {
  68. type_ = integer_value >= 0 ? Type::UNSIGNED : Type::NEGATIVE;
  69. }
  70. Value::Value(base::span<const uint8_t> in_bytes)
  71. : type_(Type::BYTE_STRING),
  72. bytestring_value_(in_bytes.begin(), in_bytes.end()) {}
  73. Value::Value(base::span<const uint8_t> in_bytes, Type type)
  74. : type_(type), bytestring_value_(in_bytes.begin(), in_bytes.end()) {
  75. DCHECK(type_ == Type::BYTE_STRING || type_ == Type::INVALID_UTF8);
  76. }
  77. Value::Value(BinaryValue&& in_bytes) noexcept
  78. : type_(Type::BYTE_STRING), bytestring_value_(std::move(in_bytes)) {}
  79. Value::Value(const char* in_string, Type type)
  80. : Value(base::StringPiece(in_string), type) {}
  81. Value::Value(std::string&& in_string, Type type) noexcept : type_(type) {
  82. switch (type_) {
  83. case Type::STRING:
  84. new (&string_value_) std::string();
  85. string_value_ = std::move(in_string);
  86. DCHECK(base::IsStringUTF8(string_value_));
  87. break;
  88. case Type::BYTE_STRING:
  89. new (&bytestring_value_) BinaryValue();
  90. bytestring_value_ = BinaryValue(in_string.begin(), in_string.end());
  91. break;
  92. default:
  93. NOTREACHED();
  94. }
  95. }
  96. Value::Value(base::StringPiece in_string, Type type) : type_(type) {
  97. switch (type_) {
  98. case Type::STRING:
  99. new (&string_value_) std::string();
  100. string_value_ = std::string(in_string);
  101. DCHECK(base::IsStringUTF8(string_value_));
  102. break;
  103. case Type::BYTE_STRING:
  104. new (&bytestring_value_) BinaryValue();
  105. bytestring_value_ = BinaryValue(in_string.begin(), in_string.end());
  106. break;
  107. default:
  108. NOTREACHED();
  109. }
  110. }
  111. Value::Value(const ArrayValue& in_array) : type_(Type::ARRAY), array_value_() {
  112. array_value_.reserve(in_array.size());
  113. for (const auto& val : in_array)
  114. array_value_.emplace_back(val.Clone());
  115. }
  116. Value::Value(ArrayValue&& in_array) noexcept
  117. : type_(Type::ARRAY), array_value_(std::move(in_array)) {}
  118. Value::Value(const MapValue& in_map) : type_(Type::MAP), map_value_() {
  119. map_value_.reserve(in_map.size());
  120. for (const auto& it : in_map)
  121. map_value_.emplace_hint(map_value_.end(), it.first.Clone(),
  122. it.second.Clone());
  123. }
  124. Value::Value(MapValue&& in_map) noexcept
  125. : type_(Type::MAP), map_value_(std::move(in_map)) {}
  126. Value& Value::operator=(Value&& that) noexcept {
  127. InternalCleanup();
  128. InternalMoveConstructFrom(std::move(that));
  129. return *this;
  130. }
  131. Value::~Value() {
  132. InternalCleanup();
  133. }
  134. Value Value::Clone() const {
  135. switch (type_) {
  136. case Type::NONE:
  137. return Value();
  138. case Type::INVALID_UTF8:
  139. return Value(bytestring_value_, Type::INVALID_UTF8);
  140. case Type::UNSIGNED:
  141. case Type::NEGATIVE:
  142. return Value(integer_value_);
  143. case Type::BYTE_STRING:
  144. return Value(bytestring_value_);
  145. case Type::STRING:
  146. return Value(string_value_);
  147. case Type::ARRAY:
  148. return Value(array_value_);
  149. case Type::MAP:
  150. return Value(map_value_);
  151. case Type::TAG:
  152. NOTREACHED() << constants::kUnsupportedMajorType;
  153. return Value();
  154. case Type::SIMPLE_VALUE:
  155. return Value(simple_value_);
  156. }
  157. NOTREACHED();
  158. return Value();
  159. }
  160. Value::SimpleValue Value::GetSimpleValue() const {
  161. CHECK(is_simple());
  162. return simple_value_;
  163. }
  164. bool Value::GetBool() const {
  165. CHECK(is_bool());
  166. return simple_value_ == SimpleValue::TRUE_VALUE;
  167. }
  168. const int64_t& Value::GetInteger() const {
  169. CHECK(is_integer());
  170. return integer_value_;
  171. }
  172. const int64_t& Value::GetUnsigned() const {
  173. CHECK(is_unsigned());
  174. CHECK_GE(integer_value_, 0);
  175. return integer_value_;
  176. }
  177. const int64_t& Value::GetNegative() const {
  178. CHECK(is_negative());
  179. CHECK_LT(integer_value_, 0);
  180. return integer_value_;
  181. }
  182. const std::string& Value::GetString() const {
  183. CHECK(is_string());
  184. return string_value_;
  185. }
  186. const Value::BinaryValue& Value::GetBytestring() const {
  187. CHECK(is_bytestring());
  188. return bytestring_value_;
  189. }
  190. base::StringPiece Value::GetBytestringAsString() const {
  191. CHECK(is_bytestring());
  192. const auto& bytestring_value = GetBytestring();
  193. return base::StringPiece(
  194. reinterpret_cast<const char*>(bytestring_value.data()),
  195. bytestring_value.size());
  196. }
  197. const Value::ArrayValue& Value::GetArray() const {
  198. CHECK(is_array());
  199. return array_value_;
  200. }
  201. const Value::MapValue& Value::GetMap() const {
  202. CHECK(is_map());
  203. return map_value_;
  204. }
  205. const Value::BinaryValue& Value::GetInvalidUTF8() const {
  206. CHECK(is_invalid_utf8());
  207. return bytestring_value_;
  208. }
  209. void Value::InternalMoveConstructFrom(Value&& that) {
  210. type_ = that.type_;
  211. switch (type_) {
  212. case Type::UNSIGNED:
  213. case Type::NEGATIVE:
  214. integer_value_ = that.integer_value_;
  215. return;
  216. case Type::INVALID_UTF8:
  217. case Type::BYTE_STRING:
  218. new (&bytestring_value_) BinaryValue(std::move(that.bytestring_value_));
  219. return;
  220. case Type::STRING:
  221. new (&string_value_) std::string(std::move(that.string_value_));
  222. return;
  223. case Type::ARRAY:
  224. new (&array_value_) ArrayValue(std::move(that.array_value_));
  225. return;
  226. case Type::MAP:
  227. new (&map_value_) MapValue(std::move(that.map_value_));
  228. return;
  229. case Type::TAG:
  230. NOTREACHED() << constants::kUnsupportedMajorType;
  231. return;
  232. case Type::SIMPLE_VALUE:
  233. simple_value_ = that.simple_value_;
  234. return;
  235. case Type::NONE:
  236. return;
  237. }
  238. NOTREACHED();
  239. }
  240. void Value::InternalCleanup() {
  241. switch (type_) {
  242. case Type::BYTE_STRING:
  243. case Type::INVALID_UTF8:
  244. bytestring_value_.~BinaryValue();
  245. break;
  246. case Type::STRING:
  247. string_value_.~basic_string();
  248. break;
  249. case Type::ARRAY:
  250. array_value_.~ArrayValue();
  251. break;
  252. case Type::MAP:
  253. map_value_.~MapValue();
  254. break;
  255. case Type::TAG:
  256. NOTREACHED() << constants::kUnsupportedMajorType;
  257. break;
  258. case Type::NONE:
  259. case Type::UNSIGNED:
  260. case Type::NEGATIVE:
  261. case Type::SIMPLE_VALUE:
  262. break;
  263. }
  264. type_ = Type::NONE;
  265. }
  266. } // namespace cbor