blob: f74f90d19e20aaa744e73ad25b408fe56d8e56d5 [file] [log] [blame]
dmcardle2b64f502020-01-07 15:22:36 -08001// Copyright (c) 2020 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
5#ifndef QUICHE_COMMON_QUICHE_DATA_READER_H_
6#define QUICHE_COMMON_QUICHE_DATA_READER_H_
7
8#include <cstddef>
9#include <cstdint>
10#include <limits>
11
12#include "net/third_party/quiche/src/common/platform/api/quiche_endian.h"
13#include "net/third_party/quiche/src/common/platform/api/quiche_export.h"
QUICHE team82ee4d32020-04-16 06:22:31 -070014#include "net/third_party/quiche/src/common/platform/api/quiche_logging.h"
dmcardle2b64f502020-01-07 15:22:36 -080015#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
16
17namespace quiche {
18
19// To use, simply construct a QuicheDataReader using the underlying buffer that
20// you'd like to read fields from, then call one of the Read*() methods to
21// actually do some reading.
22//
23// This class keeps an internal iterator to keep track of what's already been
24// read and each successive Read*() call automatically increments said iterator
25// on success. On failure, internal state of the QuicheDataReader should not be
26// trusted and it is up to the caller to throw away the failed instance and
27// handle the error as appropriate. None of the Read*() methods should ever be
28// called after failure, as they will also fail immediately.
29class QUICHE_EXPORT_PRIVATE QuicheDataReader {
30 public:
31 // Constructs a reader using NETWORK_BYTE_ORDER endianness.
32 // Caller must provide an underlying buffer to work on.
33 explicit QuicheDataReader(quiche::QuicheStringPiece data);
34 // Constructs a reader using NETWORK_BYTE_ORDER endianness.
35 // Caller must provide an underlying buffer to work on.
36 QuicheDataReader(const char* data, const size_t len);
37 // Constructs a reader using the specified endianness.
38 // Caller must provide an underlying buffer to work on.
39 QuicheDataReader(const char* data,
40 const size_t len,
41 quiche::Endianness endianness);
42 QuicheDataReader(const QuicheDataReader&) = delete;
43 QuicheDataReader& operator=(const QuicheDataReader&) = delete;
44
45 // Empty destructor.
46 ~QuicheDataReader() {}
47
48 // Reads an 8/16/32/64-bit unsigned integer into the given output
49 // parameter. Forwards the internal iterator on success. Returns true on
50 // success, false otherwise.
51 bool ReadUInt8(uint8_t* result);
52 bool ReadUInt16(uint16_t* result);
53 bool ReadUInt32(uint32_t* result);
54 bool ReadUInt64(uint64_t* result);
55
56 // Set |result| to 0, then read |num_bytes| bytes in the correct byte order
57 // into least significant bytes of |result|.
58 bool ReadBytesToUInt64(size_t num_bytes, uint64_t* result);
59
60 // Reads a string prefixed with 16-bit length into the given output parameter.
61 //
62 // NOTE: Does not copy but rather references strings in the underlying buffer.
63 // This should be kept in mind when handling memory management!
64 //
65 // Forwards the internal iterator on success.
66 // Returns true on success, false otherwise.
67 bool ReadStringPiece16(quiche::QuicheStringPiece* result);
68
dschinazia0aeda52020-04-10 16:57:18 -070069 // Reads a string prefixed with 8-bit length into the given output parameter.
70 //
71 // NOTE: Does not copy but rather references strings in the underlying buffer.
72 // This should be kept in mind when handling memory management!
73 //
74 // Forwards the internal iterator on success.
75 // Returns true on success, false otherwise.
76 bool ReadStringPiece8(quiche::QuicheStringPiece* result);
77
dmcardle2b64f502020-01-07 15:22:36 -080078 // Reads a given number of bytes into the given buffer. The buffer
79 // must be of adequate size.
80 // Forwards the internal iterator on success.
81 // Returns true on success, false otherwise.
82 bool ReadStringPiece(quiche::QuicheStringPiece* result, size_t size);
83
84 // Reads tag represented as 32-bit unsigned integer into given output
85 // parameter. Tags are in big endian on the wire (e.g., CHLO is
86 // 'C','H','L','O') and are read in byte order, so tags in memory are in big
87 // endian.
88 bool ReadTag(uint32_t* tag);
89
vasilvv52f24592020-06-02 17:32:16 -070090 // Reads a sequence of a fixed number of decimal digits, parses them as an
91 // unsigned integer and returns them as a uint64_t. Forwards internal
92 // iterator on success, may forward it even in case of failure.
93 bool ReadDecimal64(size_t num_digits, uint64_t* result);
94
dmcardle2b64f502020-01-07 15:22:36 -080095 // Returns the remaining payload as a quiche::QuicheStringPiece.
96 //
97 // NOTE: Does not copy but rather references strings in the underlying buffer.
98 // This should be kept in mind when handling memory management!
99 //
100 // Forwards the internal iterator.
101 quiche::QuicheStringPiece ReadRemainingPayload();
102
103 // Returns the remaining payload as a quiche::QuicheStringPiece.
104 //
105 // NOTE: Does not copy but rather references strings in the underlying buffer.
106 // This should be kept in mind when handling memory management!
107 //
108 // DOES NOT forward the internal iterator.
109 quiche::QuicheStringPiece PeekRemainingPayload() const;
110
111 // Returns the entire payload as a quiche::QuicheStringPiece.
112 //
113 // NOTE: Does not copy but rather references strings in the underlying buffer.
114 // This should be kept in mind when handling memory management!
115 //
116 // DOES NOT forward the internal iterator.
117 quiche::QuicheStringPiece FullPayload() const;
118
dschinazi278efae2020-01-28 17:03:09 -0800119 // Returns the part of the payload that has been already read as a
120 // quiche::QuicheStringPiece.
121 //
122 // NOTE: Does not copy but rather references strings in the underlying buffer.
123 // This should be kept in mind when handling memory management!
124 //
125 // DOES NOT forward the internal iterator.
126 quiche::QuicheStringPiece PreviouslyReadPayload() const;
127
dmcardle2b64f502020-01-07 15:22:36 -0800128 // Reads a given number of bytes into the given buffer. The buffer
129 // must be of adequate size.
130 // Forwards the internal iterator on success.
131 // Returns true on success, false otherwise.
132 bool ReadBytes(void* result, size_t size);
133
134 // Skips over |size| bytes from the buffer and forwards the internal iterator.
135 // Returns true if there are at least |size| bytes remaining to read, false
136 // otherwise.
137 bool Seek(size_t size);
138
139 // Returns true if the entirety of the underlying buffer has been read via
140 // Read*() calls.
141 bool IsDoneReading() const;
142
143 // Returns the number of bytes remaining to be read.
144 size_t BytesRemaining() const;
145
146 // Truncates the reader down by reducing its internal length.
147 // If called immediately after calling this, BytesRemaining will
148 // return |truncation_length|. If truncation_length is less than the
149 // current value of BytesRemaining, this does nothing and returns false.
150 bool TruncateRemaining(size_t truncation_length);
151
152 // Returns the next byte that to be read. Must not be called when there are no
153 // bytes to be read.
154 //
155 // DOES NOT forward the internal iterator.
156 uint8_t PeekByte() const;
157
158 std::string DebugString() const;
159
160 protected:
161 // Returns true if the underlying buffer has enough room to read the given
162 // amount of bytes.
163 bool CanRead(size_t bytes) const;
164
165 // To be called when a read fails for any reason.
166 void OnFailure();
167
168 const char* data() const { return data_; }
169
170 size_t pos() const { return pos_; }
171
172 void AdvancePos(size_t amount) {
173 DCHECK_LE(pos_, std::numeric_limits<size_t>::max() - amount);
174 DCHECK_LE(pos_, len_ - amount);
175 pos_ += amount;
176 }
177
178 quiche::Endianness endianness() const { return endianness_; }
179
180 private:
181 // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
182 // char. The data buffer that we're reading from.
183 const char* data_;
184
185 // The length of the data buffer that we're reading from.
186 size_t len_;
187
188 // The location of the next read from our data buffer.
189 size_t pos_;
190
191 // The endianness to read integers and floating numbers.
192 quiche::Endianness endianness_;
193};
194
195} // namespace quiche
196
197#endif // QUICHE_COMMON_QUICHE_DATA_READER_H_