summaryrefslogtreecommitdiff
path: root/chromium/components/web_package/input_reader.h
blob: 3eee96216d4720e8eb9e5417d5b0e5d8d625df8c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_WEB_PACKAGE_INPUT_READER_H_
#define COMPONENTS_WEB_PACKAGE_INPUT_READER_H_

#include "base/big_endian.h"
#include "base/containers/span.h"
#include "base/strings/string_piece_forward.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace web_package {

// https://datatracker.ietf.org/doc/html/rfc8949.html#section-3.1
enum class CBORType {
  // kUnsignedInt = 0,
  // kNegativeInt = 1,
  kByteString = 2,
  kTextString = 3,
  kArray = 4,
  kMap = 5,
};

// The maximum length of the CBOR item header (type and argument).
// https://datatracker.ietf.org/doc/html/rfc8949.html#section-3
// When the additional information (the low-order 5 bits of the first
// byte) is 27, the argument's value is held in the following 8 bytes.
constexpr uint64_t kMaxCBORItemHeaderSize = 9;

// A utility class for reading various values from input buffer.
class InputReader {
 public:
  explicit InputReader(base::span<const uint8_t> buf) : buf_(buf) {}

  InputReader(const InputReader&) = delete;
  InputReader& operator=(const InputReader&) = delete;

  uint64_t CurrentOffset() const { return current_offset_; }
  size_t Size() const { return buf_.size(); }

  absl::optional<uint8_t> ReadByte();

  template <typename T>
  bool ReadBigEndian(T* out) {
    auto bytes = ReadBytes(sizeof(T));
    if (!bytes)
      return false;
    base::ReadBigEndian(bytes->data(), out);
    return true;
  }

  absl::optional<base::span<const uint8_t>> ReadBytes(size_t n);

  absl::optional<base::StringPiece> ReadString(size_t n);

  // Parses the type and argument of a CBOR item from the input head. If parsed
  // successfully and the type matches |expected_type|, returns the argument.
  // Otherwise returns nullopt.
  absl::optional<uint64_t> ReadCBORHeader(CBORType expected_type);

 private:
  absl::optional<std::pair<CBORType, uint64_t>> ReadTypeAndArgument();

  void Advance(size_t n);

  base::span<const uint8_t> buf_;
  uint64_t current_offset_ = 0;
};

}  // namespace web_package

#endif  // COMPONENTS_WEB_PACKAGE_INPUT_READER_H_