writer.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. #ifndef COMPONENTS_CBOR_WRITER_H_
  5. #define COMPONENTS_CBOR_WRITER_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <vector>
  9. #include "base/memory/raw_ptr.h"
  10. #include "components/cbor/cbor_export.h"
  11. #include "components/cbor/values.h"
  12. #include "third_party/abseil-cpp/absl/types/optional.h"
  13. // A basic Concise Binary Object Representation (CBOR) encoder as defined by
  14. // https://tools.ietf.org/html/rfc7049. This is a generic encoder that supplies
  15. // canonical, well-formed CBOR values but does not guarantee their validity
  16. // (see https://tools.ietf.org/html/rfc7049#section-3.2).
  17. // Supported:
  18. // * Major types:
  19. // * 0: Unsigned integers, up to INT64_MAX.
  20. // * 1: Negative integers, to INT64_MIN.
  21. // * 2: Byte strings.
  22. // * 3: UTF-8 strings.
  23. // * 4: Arrays, with the number of elements known at the start.
  24. // * 5: Maps, with the number of elements known at the start
  25. // of the container.
  26. // * 7: Simple values.
  27. //
  28. // Unsupported:
  29. // * Floating-point numbers.
  30. // * Indefinite-length encodings.
  31. // * Parsing.
  32. //
  33. // Requirements for canonical CBOR as suggested by RFC 7049 are:
  34. // 1) All major data types for the CBOR values must be as short as possible.
  35. // * Unsigned integer between 0 to 23 must be expressed in same byte as
  36. // the major type.
  37. // * 24 to 255 must be expressed only with an additional uint8_t.
  38. // * 256 to 65535 must be expressed only with an additional uint16_t.
  39. // * 65536 to 4294967295 must be expressed only with an additional
  40. // uint32_t. * The rules for expression of length in major types
  41. // 2 to 5 follow the above rule for integers.
  42. // 2) Keys in every map must be sorted (first by major type, then by key
  43. // length, then by value in byte-wise lexical order).
  44. // 3) Indefinite length items must be converted to definite length items.
  45. // 4) All maps must not have duplicate keys.
  46. //
  47. // Current implementation of Writer encoder meets all the requirements of
  48. // canonical CBOR.
  49. namespace cbor {
  50. class CBOR_EXPORT Writer {
  51. public:
  52. // Default that should be sufficiently large for most use cases.
  53. static constexpr size_t kDefaultMaxNestingDepth = 16;
  54. struct CBOR_EXPORT Config {
  55. // Controls the maximum depth of CBOR nesting that will be permitted in a
  56. // Value. Nesting depth is defined as the number of arrays/maps that have to
  57. // be traversed to reach the most nested contained Value. Primitive values
  58. // and empty containers have nesting depths of 0.
  59. int max_nesting_level = kDefaultMaxNestingDepth;
  60. // Controls whether the Writer allows writing string values of type
  61. // Value::Type::INVALID_UTF8. Regular CBOR strings must be valid UTF-8.
  62. // Writers with this setting will produce invalid CBOR, so it may only be
  63. // enabled in tests.
  64. bool allow_invalid_utf8_for_testing = false;
  65. };
  66. Writer(const Writer&) = delete;
  67. Writer& operator=(const Writer&) = delete;
  68. ~Writer();
  69. // Returns the CBOR byte string representation of |node|, unless its nesting
  70. // depth is greater than |max_nesting_level|, in which case an empty optional
  71. // value is returned.
  72. static absl::optional<std::vector<uint8_t>> Write(
  73. const Value& node,
  74. size_t max_nesting_level = kDefaultMaxNestingDepth);
  75. // A version of |Write| above that takes a Config.
  76. static absl::optional<std::vector<uint8_t>> Write(const Value& node,
  77. const Config& config);
  78. private:
  79. explicit Writer(std::vector<uint8_t>* cbor);
  80. // Called recursively to build the CBOR bytestring. When completed,
  81. // |encoded_cbor_| will contain the CBOR.
  82. bool EncodeCBOR(const Value& node,
  83. int max_nesting_level,
  84. bool allow_invalid_utf8);
  85. // Encodes the type and size of the data being added.
  86. void StartItem(Value::Type type, uint64_t size);
  87. // Encodes the additional information for the data.
  88. void SetAdditionalInformation(uint8_t additional_information);
  89. // Encodes an unsigned integer value. This is used to both write
  90. // unsigned integers and to encode the lengths of other major types.
  91. void SetUint(uint64_t value);
  92. // Returns the number of bytes needed to store the unsigned integer.
  93. size_t GetNumUintBytes(uint64_t value);
  94. // Holds the encoded CBOR data.
  95. raw_ptr<std::vector<uint8_t>> encoded_cbor_;
  96. };
  97. } // namespace cbor
  98. #endif // COMPONENTS_CBOR_WRITER_H_