input.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2015 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 NET_DER_INPUT_H_
  5. #define NET_DER_INPUT_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <string>
  9. #include "base/containers/span.h"
  10. #include "base/strings/string_piece.h"
  11. #include "net/base/net_export.h"
  12. namespace net::der {
  13. // An opaque class that represents a fixed buffer of data of a fixed length,
  14. // to be used as an input to other operations. An Input object does not own
  15. // the data it references, so callers are responsible for making sure that
  16. // the data outlives the Input object and any other associated objects.
  17. //
  18. // All data access for an Input should be done through the ByteReader class.
  19. // This class and associated classes are designed with safety in mind to make it
  20. // difficult to read memory outside of an Input. ByteReader provides a simple
  21. // API for reading through the Input sequentially. For more complicated uses,
  22. // multiple instances of a ByteReader for a particular Input can be created.
  23. class NET_EXPORT_PRIVATE Input {
  24. public:
  25. // Creates an empty Input, one from which no data can be read.
  26. constexpr Input() = default;
  27. // Creates an Input from a constant array |data|.
  28. template <size_t N>
  29. constexpr explicit Input(const uint8_t (&data)[N]) : data_(data), len_(N) {}
  30. // Creates an Input from the given |data| and |len|.
  31. constexpr explicit Input(const uint8_t* data, size_t len)
  32. : data_(data), len_(len) {}
  33. // Creates an Input from a base::StringPiece.
  34. explicit Input(const base::StringPiece& sp);
  35. // Creates an Input from a std::string. The lifetimes are a bit subtle when
  36. // using this function: The constructed Input is only valid so long as |s| is
  37. // still alive and not mutated.
  38. explicit Input(const std::string* s);
  39. // Returns the length in bytes of an Input's data.
  40. constexpr size_t Length() const { return len_; }
  41. // Returns a pointer to the Input's data. This method is marked as "unsafe"
  42. // because access to the Input's data should be done through ByteReader
  43. // instead. This method should only be used where using a ByteReader truly
  44. // is not an option.
  45. constexpr const uint8_t* UnsafeData() const { return data_; }
  46. // Returns a copy of the data represented by this object as a std::string.
  47. std::string AsString() const;
  48. // Returns a StringPiece pointing to the same data as the Input. The resulting
  49. // StringPiece must not outlive the data that was used to construct this
  50. // Input.
  51. base::StringPiece AsStringPiece() const;
  52. // Returns a base::span pointing to the same data as the Input. The resulting
  53. // base::span must not outlive the data that was used to construct this
  54. // Input.
  55. base::span<const uint8_t> AsSpan() const;
  56. private:
  57. // This constructor is deleted to prevent constructing an Input from a
  58. // std::string r-value. Since the Input points to memory owned by another
  59. // object, such an Input would point to invalid memory. Without this deleted
  60. // constructor, a std::string could be passed in to the base::StringPiece
  61. // constructor because of StringPiece's implicit constructor.
  62. Input(std::string) = delete;
  63. const uint8_t* data_ = nullptr;
  64. size_t len_ = 0;
  65. };
  66. // Return true if |lhs|'s data and |rhs|'s data are byte-wise equal.
  67. NET_EXPORT_PRIVATE bool operator==(const Input& lhs, const Input& rhs);
  68. // Return true if |lhs|'s data and |rhs|'s data are not byte-wise equal.
  69. NET_EXPORT_PRIVATE bool operator!=(const Input& lhs, const Input& rhs);
  70. // Returns true if |lhs|'s data is lexicographically less than |rhs|'s data.
  71. NET_EXPORT_PRIVATE constexpr bool operator<(const Input& lhs,
  72. const Input& rhs) {
  73. // This is `std::lexicographical_compare`, but that's not `constexpr` until
  74. // C++-20.
  75. auto* it1 = lhs.UnsafeData();
  76. auto* it2 = rhs.UnsafeData();
  77. const auto* end1 = lhs.UnsafeData() + lhs.Length();
  78. const auto* end2 = rhs.UnsafeData() + rhs.Length();
  79. for (; it1 != end1 && it2 != end2; ++it1, ++it2) {
  80. if (*it1 < *it2) {
  81. return true;
  82. } else if (*it2 < *it1) {
  83. return false;
  84. }
  85. }
  86. return it2 != end2;
  87. }
  88. // This class provides ways to read data from an Input in a bounds-checked way.
  89. // The ByteReader is designed to read through the input sequentially. Once a
  90. // byte has been read with a ByteReader, the caller can't go back and re-read
  91. // that byte with the same reader. Of course, the caller can create multiple
  92. // ByteReaders for the same input (or copy an existing ByteReader).
  93. //
  94. // For something simple like a single byte lookahead, the easiest way to do
  95. // that is to copy the ByteReader and call ReadByte() on the copy - the original
  96. // ByteReader will be unaffected and the peeked byte will be read through
  97. // ReadByte(). For other read patterns, it can be useful to mark where one is
  98. // in a ByteReader to be able to return to that spot.
  99. //
  100. // Some operations using Mark can also be done by creating a copy of the
  101. // ByteReader. By using a Mark instead, you use less memory, but more
  102. // importantly, you end up with an immutable object that matches the semantics
  103. // of what is intended.
  104. class NET_EXPORT_PRIVATE ByteReader {
  105. public:
  106. // Creates a ByteReader to read the data represented by an Input.
  107. explicit ByteReader(const Input& in);
  108. // Reads a single byte from the input source, putting the byte read in
  109. // |*byte_p|. If a byte cannot be read from the input (because there is
  110. // no input left), then this method returns false.
  111. [[nodiscard]] bool ReadByte(uint8_t* out);
  112. // Reads |len| bytes from the input source, and initializes an Input to
  113. // point to that data. If there aren't enough bytes left in the input source,
  114. // then this method returns false.
  115. [[nodiscard]] bool ReadBytes(size_t len, Input* out);
  116. // Returns how many bytes are left to read.
  117. size_t BytesLeft() const { return len_; }
  118. // Returns whether there is any more data to be read.
  119. bool HasMore();
  120. private:
  121. void Advance(size_t len);
  122. const uint8_t* data_;
  123. size_t len_;
  124. };
  125. } // namespace net::der
  126. #endif // NET_DER_INPUT_H_