File: input_reader.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (113 lines) | stat: -rw-r--r-- 3,182 bytes parent folder | download | duplicates (5)
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// 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 <optional>
#include <string_view>
#include <variant>

#include "base/containers/span.h"
#include "base/containers/span_reader.h"
#include "base/memory/stack_allocated.h"
#include "base/types/id_type.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,
  // kTag = 6,
  kSimpleValue = 7,
  // kFloatValue = 7,
};

struct CBORHeader {
  struct StringInfo {
    enum class StringType {
      kByteString,
      kTextString,
    } type;
    uint64_t byte_length;
  };
  struct ContainerInfo {
    enum class ContainerType {
      kArray,
      kMap,
    } type;
    uint64_t size;
  };

  const std::variant<bool, int64_t, StringInfo, ContainerInfo> data;
};

// 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 {
  STACK_ALLOCATED();

 public:
  explicit InputReader(base::span<const uint8_t> buf);

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

  ~InputReader();

  size_t CurrentOffset() const { return buf_.num_read(); }
  size_t Size() const { return buf_.remaining(); }

  std::optional<uint8_t> ReadByte();

  template <typename T>
    requires(std::is_integral_v<T> && std::is_unsigned_v<T>)
  bool ReadBigEndian(T* out) {
    if constexpr (sizeof(T) == 1) {
      return buf_.ReadU8BigEndian(*out);
    } else if constexpr (sizeof(T) == 2) {
      return buf_.ReadU16BigEndian(*out);
    } else if constexpr (sizeof(T) == 4) {
      return buf_.ReadU32BigEndian(*out);
    } else {
      static_assert(sizeof(T) == 8);
      return buf_.ReadU64BigEndian(*out);
    }
  }

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

  std::optional<std::string_view> 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.
  std::optional<uint64_t> ReadCBORHeader(CBORType expected_type);

  // Parses the type and argument of a CBOR item from the input head. If parsed
  // successfully, returns type and:
  //  * value for kUnsignedInt/kNegativeInt;
  //  * value_size for kTextString/kByteString/kMap/kArray.
  // Otherwise returns nullopt.
  std::optional<CBORHeader> ReadCBORHeader();

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

  base::SpanReader<const uint8_t> buf_;
};

}  // namespace web_package

#endif  // COMPONENTS_WEB_PACKAGE_INPUT_READER_H_