blob: 48af8873a2c006ce5e119b48c117a76283680e5f [file] [log] [blame]
// 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.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_