123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // 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.
- #ifndef COMPONENTS_CBOR_WRITER_H_
- #define COMPONENTS_CBOR_WRITER_H_
- #include <stddef.h>
- #include <stdint.h>
- #include <vector>
- #include "base/memory/raw_ptr.h"
- #include "components/cbor/cbor_export.h"
- #include "components/cbor/values.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- // A basic Concise Binary Object Representation (CBOR) encoder as defined by
- // https://tools.ietf.org/html/rfc7049. This is a generic encoder that supplies
- // canonical, well-formed CBOR values but does not guarantee their validity
- // (see https://tools.ietf.org/html/rfc7049#section-3.2).
- // Supported:
- // * Major types:
- // * 0: Unsigned integers, up to INT64_MAX.
- // * 1: Negative integers, to INT64_MIN.
- // * 2: Byte strings.
- // * 3: UTF-8 strings.
- // * 4: Arrays, with the number of elements known at the start.
- // * 5: Maps, with the number of elements known at the start
- // of the container.
- // * 7: Simple values.
- //
- // Unsupported:
- // * Floating-point numbers.
- // * Indefinite-length encodings.
- // * Parsing.
- //
- // Requirements for canonical CBOR as suggested by RFC 7049 are:
- // 1) All major data types for the CBOR values must be as short as possible.
- // * Unsigned integer between 0 to 23 must be expressed in same byte as
- // the major type.
- // * 24 to 255 must be expressed only with an additional uint8_t.
- // * 256 to 65535 must be expressed only with an additional uint16_t.
- // * 65536 to 4294967295 must be expressed only with an additional
- // uint32_t. * The rules for expression of length in major types
- // 2 to 5 follow the above rule for integers.
- // 2) Keys in every map must be sorted (first by major type, then by key
- // length, then by value in byte-wise lexical order).
- // 3) Indefinite length items must be converted to definite length items.
- // 4) All maps must not have duplicate keys.
- //
- // Current implementation of Writer encoder meets all the requirements of
- // canonical CBOR.
- namespace cbor {
- class CBOR_EXPORT Writer {
- public:
- // Default that should be sufficiently large for most use cases.
- static constexpr size_t kDefaultMaxNestingDepth = 16;
- struct CBOR_EXPORT Config {
- // Controls the maximum depth of CBOR nesting that will be permitted in a
- // Value. Nesting depth is defined as the number of arrays/maps that have to
- // be traversed to reach the most nested contained Value. Primitive values
- // and empty containers have nesting depths of 0.
- int max_nesting_level = kDefaultMaxNestingDepth;
- // Controls whether the Writer allows writing string values of type
- // Value::Type::INVALID_UTF8. Regular CBOR strings must be valid UTF-8.
- // Writers with this setting will produce invalid CBOR, so it may only be
- // enabled in tests.
- bool allow_invalid_utf8_for_testing = false;
- };
- Writer(const Writer&) = delete;
- Writer& operator=(const Writer&) = delete;
- ~Writer();
- // Returns the CBOR byte string representation of |node|, unless its nesting
- // depth is greater than |max_nesting_level|, in which case an empty optional
- // value is returned.
- static absl::optional<std::vector<uint8_t>> Write(
- const Value& node,
- size_t max_nesting_level = kDefaultMaxNestingDepth);
- // A version of |Write| above that takes a Config.
- static absl::optional<std::vector<uint8_t>> Write(const Value& node,
- const Config& config);
- private:
- explicit Writer(std::vector<uint8_t>* cbor);
- // Called recursively to build the CBOR bytestring. When completed,
- // |encoded_cbor_| will contain the CBOR.
- bool EncodeCBOR(const Value& node,
- int max_nesting_level,
- bool allow_invalid_utf8);
- // Encodes the type and size of the data being added.
- void StartItem(Value::Type type, uint64_t size);
- // Encodes the additional information for the data.
- void SetAdditionalInformation(uint8_t additional_information);
- // Encodes an unsigned integer value. This is used to both write
- // unsigned integers and to encode the lengths of other major types.
- void SetUint(uint64_t value);
- // Returns the number of bytes needed to store the unsigned integer.
- size_t GetNumUintBytes(uint64_t value);
- // Holds the encoded CBOR data.
- raw_ptr<std::vector<uint8_t>> encoded_cbor_;
- };
- } // namespace cbor
- #endif // COMPONENTS_CBOR_WRITER_H_
|