Lift generic functionality from QuicDataReader/QuicDataWriter into Quiche The QUIC-specific functions stay in QuicDataReader/QuicDataWriter. Generally useful functions are moved into QuicheDataReader/QuicheDataWriter. gfe-relnote: n/a, no functional change PiperOrigin-RevId: 288584295 Change-Id: I53b102f56f43019a89db0aa624898ed44bb6ec11
diff --git a/quic/core/quic_data_reader.cc b/quic/core/quic_data_reader.cc index 3982cc9..882573d 100644 --- a/quic/core/quic_data_reader.cc +++ b/quic/core/quic_data_reader.cc
@@ -15,7 +15,7 @@ namespace quic { QuicDataReader::QuicDataReader(quiche::QuicheStringPiece data) - : QuicDataReader(data.data(), data.length(), quiche::NETWORK_BYTE_ORDER) {} + : quiche::QuicheDataReader(data) {} QuicDataReader::QuicDataReader(const char* data, const size_t len) : QuicDataReader(data, len, quiche::NETWORK_BYTE_ORDER) {} @@ -23,58 +23,7 @@ QuicDataReader::QuicDataReader(const char* data, const size_t len, quiche::Endianness endianness) - : data_(data), len_(len), pos_(0), endianness_(endianness) {} - -bool QuicDataReader::ReadUInt8(uint8_t* result) { - return ReadBytes(result, sizeof(*result)); -} - -bool QuicDataReader::ReadUInt16(uint16_t* result) { - if (!ReadBytes(result, sizeof(*result))) { - return false; - } - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { - *result = quiche::QuicheEndian::NetToHost16(*result); - } - return true; -} - -bool QuicDataReader::ReadUInt32(uint32_t* result) { - if (!ReadBytes(result, sizeof(*result))) { - return false; - } - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { - *result = quiche::QuicheEndian::NetToHost32(*result); - } - return true; -} - -bool QuicDataReader::ReadUInt64(uint64_t* result) { - if (!ReadBytes(result, sizeof(*result))) { - return false; - } - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { - *result = quiche::QuicheEndian::NetToHost64(*result); - } - return true; -} - -bool QuicDataReader::ReadBytesToUInt64(size_t num_bytes, uint64_t* result) { - *result = 0u; - if (num_bytes > sizeof(*result)) { - return false; - } - if (endianness_ == quiche::HOST_BYTE_ORDER) { - return ReadBytes(result, num_bytes); - } - - if (!ReadBytes(reinterpret_cast<char*>(result) + sizeof(*result) - num_bytes, - num_bytes)) { - return false; - } - *result = quiche::QuicheEndian::NetToHost64(*result); - return true; -} + : quiche::QuicheDataReader(data, len, endianness) {} bool QuicDataReader::ReadUFloat16(uint64_t* result) { uint16_t value; @@ -109,34 +58,6 @@ return true; } -bool QuicDataReader::ReadStringPiece16(quiche::QuicheStringPiece* result) { - // Read resultant length. - uint16_t result_len; - if (!ReadUInt16(&result_len)) { - // OnFailure() already called. - return false; - } - - return ReadStringPiece(result, result_len); -} - -bool QuicDataReader::ReadStringPiece(quiche::QuicheStringPiece* result, - size_t size) { - // Make sure that we have enough data to read. - if (!CanRead(size)) { - OnFailure(); - return false; - } - - // Set result. - *result = quiche::QuicheStringPiece(data_ + pos_, size); - - // Iterate. - pos_ += size; - - return true; -} - bool QuicDataReader::ReadConnectionId(QuicConnectionId* connection_id, uint8_t length) { if (!GetQuicRestartFlag(quic_allow_very_long_connection_ids)) { @@ -180,57 +101,10 @@ return ReadConnectionId(connection_id, connection_id_length); } -bool QuicDataReader::ReadTag(uint32_t* tag) { - return ReadBytes(tag, sizeof(*tag)); -} - -quiche::QuicheStringPiece QuicDataReader::ReadRemainingPayload() { - quiche::QuicheStringPiece payload = PeekRemainingPayload(); - pos_ = len_; - return payload; -} - -quiche::QuicheStringPiece QuicDataReader::PeekRemainingPayload() const { - return quiche::QuicheStringPiece(data_ + pos_, len_ - pos_); -} - -quiche::QuicheStringPiece QuicDataReader::FullPayload() const { - return quiche::QuicheStringPiece(data_, len_); -} - -bool QuicDataReader::ReadBytes(void* result, size_t size) { - // Make sure that we have enough data to read. - if (!CanRead(size)) { - OnFailure(); - return false; - } - - // Read into result. - memcpy(result, data_ + pos_, size); - - // Iterate. - pos_ += size; - - return true; -} - -bool QuicDataReader::Seek(size_t size) { - if (!CanRead(size)) { - OnFailure(); - return false; - } - pos_ += size; - return true; -} - -bool QuicDataReader::IsDoneReading() const { - return len_ == pos_; -} - QuicVariableLengthIntegerLength QuicDataReader::PeekVarInt62Length() { - DCHECK_EQ(endianness_, quiche::NETWORK_BYTE_ORDER); + DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER); const unsigned char* next = - reinterpret_cast<const unsigned char*>(data_ + pos_); + reinterpret_cast<const unsigned char*>(data() + pos()); if (BytesRemaining() == 0) { return VARIABLE_LENGTH_INTEGER_LENGTH_0; } @@ -238,37 +112,6 @@ 1 << ((*next & 0b11000000) >> 6)); } -size_t QuicDataReader::BytesRemaining() const { - return len_ - pos_; -} - -bool QuicDataReader::TruncateRemaining(size_t truncation_length) { - if (truncation_length > BytesRemaining()) { - return false; - } - len_ = pos_ + truncation_length; - return true; -} - -bool QuicDataReader::CanRead(size_t bytes) const { - return bytes <= (len_ - pos_); -} - -void QuicDataReader::OnFailure() { - // Set our iterator to the end of the buffer so that further reads fail - // immediately. - pos_ = len_; -} - -uint8_t QuicDataReader::PeekByte() const { - if (pos_ >= len_) { - QUIC_BUG << "Reading is done, cannot peek next byte. Tried to read pos = " - << pos_ << " buffer length = " << len_; - return 0; - } - return data_[pos_]; -} - // Read an IETF/QUIC formatted 62-bit Variable Length Integer. // // Performance notes @@ -286,11 +129,11 @@ // Low-level optimization is useful here because this function will be // called frequently, leading to outsize benefits. bool QuicDataReader::ReadVarInt62(uint64_t* result) { - DCHECK_EQ(endianness_, quiche::NETWORK_BYTE_ORDER); + DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER); size_t remaining = BytesRemaining(); const unsigned char* next = - reinterpret_cast<const unsigned char*>(data_ + pos_); + reinterpret_cast<const unsigned char*>(data() + pos()); if (remaining != 0) { switch (*next & 0xc0) { case 0xc0: @@ -304,7 +147,7 @@ (static_cast<uint64_t>(*(next + 5)) << 16) + (static_cast<uint64_t>(*(next + 6)) << 8) + (static_cast<uint64_t>(*(next + 7)) << 0); - pos_ += 8; + AdvancePos(8); return true; } return false; @@ -314,7 +157,7 @@ if (remaining >= 4) { *result = (((*(next)) & 0x3f) << 24) + (((*(next + 1)) << 16)) + (((*(next + 2)) << 8)) + (((*(next + 3)) << 0)); - pos_ += 4; + AdvancePos(4); return true; } return false; @@ -323,7 +166,7 @@ // Leading 0b01...... is 2 byte encoding if (remaining >= 2) { *result = (((*(next)) & 0x3f) << 8) + (*(next + 1)); - pos_ += 2; + AdvancePos(2); return true; } return false; @@ -331,7 +174,7 @@ case 0x00: // Leading 0b00...... is 1 byte encoding *result = (*next) & 0x3f; - pos_++; + AdvancePos(1); return true; } } @@ -352,9 +195,5 @@ return true; } -std::string QuicDataReader::DebugString() const { - return quiche::QuicheStrCat(" { length: ", len_, ", position: ", pos_, " }"); -} - #undef ENDPOINT // undef for jumbo builds } // namespace quic
diff --git a/quic/core/quic_data_reader.h b/quic/core/quic_data_reader.h index 40ad4fc..08366b9 100644 --- a/quic/core/quic_data_reader.h +++ b/quic/core/quic_data_reader.h
@@ -12,6 +12,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_data_reader.h" namespace quic { @@ -29,7 +30,7 @@ // trusted and it is up to the caller to throw away the failed instance and // handle the error as appropriate. None of the Read*() methods should ever be // called after failure, as they will also fail immediately. -class QUIC_EXPORT_PRIVATE QuicDataReader { +class QUIC_EXPORT_PRIVATE QuicDataReader : public quiche::QuicheDataReader { public: // Constructs a reader using NETWORK_BYTE_ORDER endianness. // Caller must provide an underlying buffer to work on. @@ -48,38 +49,11 @@ // Empty destructor. ~QuicDataReader() {} - // Reads an 8/16/32/64-bit unsigned integer into the given output - // parameter. Forwards the internal iterator on success. Returns true on - // success, false otherwise. - bool ReadUInt8(uint8_t* result); - bool ReadUInt16(uint16_t* result); - bool ReadUInt32(uint32_t* result); - bool ReadUInt64(uint64_t* result); - - // Set |result| to 0, then read |num_bytes| bytes in the correct byte order - // into least significant bytes of |result|. - bool ReadBytesToUInt64(size_t num_bytes, uint64_t* result); - // Reads a 16-bit unsigned float into the given output parameter. // Forwards the internal iterator on success. // Returns true on success, false otherwise. bool ReadUFloat16(uint64_t* result); - // Reads a string prefixed with 16-bit length into the given output parameter. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadStringPiece16(quiche::QuicheStringPiece* result); - - // Reads a given number of bytes into the given buffer. The buffer - // must be of adequate size. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadStringPiece(quiche::QuicheStringPiece* result, size_t len); - // Reads connection ID into the given output parameter. // Forwards the internal iterator on success. // Returns true on success, false otherwise. @@ -90,70 +64,10 @@ // Returns true on success, false otherwise. bool ReadLengthPrefixedConnectionId(QuicConnectionId* connection_id); - // Reads tag represented as 32-bit unsigned integer into given output - // parameter. Tags are in big endian on the wire (e.g., CHLO is - // 'C','H','L','O') and are read in byte order, so tags in memory are in big - // endian. - bool ReadTag(uint32_t* tag); - - // Returns the remaining payload as a quiche::QuicheStringPiece. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // Forwards the internal iterator. - quiche::QuicheStringPiece ReadRemainingPayload(); - - // Returns the remaining payload as a quiche::QuicheStringPiece. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // DOES NOT forward the internal iterator. - quiche::QuicheStringPiece PeekRemainingPayload() const; - - // Returns the entire payload as a quiche::QuicheStringPiece. - // - // NOTE: Does not copy but rather references strings in the underlying buffer. - // This should be kept in mind when handling memory management! - // - // DOES NOT forward the internal iterator. - quiche::QuicheStringPiece FullPayload() const; - - // Reads a given number of bytes into the given buffer. The buffer - // must be of adequate size. - // Forwards the internal iterator on success. - // Returns true on success, false otherwise. - bool ReadBytes(void* result, size_t size); - - // Skips over |size| bytes from the buffer and forwards the internal iterator. - // Returns true if there are at least |size| bytes remaining to read, false - // otherwise. - bool Seek(size_t size); - - // Returns true if the entirety of the underlying buffer has been read via - // Read*() calls. - bool IsDoneReading() const; - // Returns the length in bytes of a variable length integer based on the next // two bits available. Returns 1, 2, 4, or 8 on success, and 0 on failure. QuicVariableLengthIntegerLength PeekVarInt62Length(); - // Returns the number of bytes remaining to be read. - size_t BytesRemaining() const; - - // Truncates the reader down by reducing its internal length. - // If called immediately after calling this, BytesRemaining will - // return |truncation_length|. If truncation_length is less than the - // current value of BytesRemaining, this does nothing and returns false. - bool TruncateRemaining(size_t truncation_length); - - // Returns the next byte that to be read. Must not be called when there are no - // bytes to be read. - // - // DOES NOT forward the internal iterator. - uint8_t PeekByte() const; - // Read an IETF-encoded Variable Length Integer and place the result // in |*result|. // Returns true if it works, false if not. The only error is that @@ -168,29 +82,6 @@ // returns false if there is a read error or if the value is // greater than (2^32)-1. bool ReadVarIntU32(uint32_t* result); - - std::string DebugString() const; - - private: - // Returns true if the underlying buffer has enough room to read the given - // amount of bytes. - bool CanRead(size_t bytes) const; - - // To be called when a read fails for any reason. - void OnFailure(); - - // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not - // char. The data buffer that we're reading from. - const char* data_; - - // The length of the data buffer that we're reading from. - size_t len_; - - // The location of the next read from our data buffer. - size_t pos_; - - // The endianness to read integers and floating numbers. - quiche::Endianness endianness_; }; } // namespace quic
diff --git a/quic/core/quic_data_writer.cc b/quic/core/quic_data_writer.cc index 28af68b..41c374c 100644 --- a/quic/core/quic_data_writer.cc +++ b/quic/core/quic_data_writer.cc
@@ -18,57 +18,15 @@ namespace quic { QuicDataWriter::QuicDataWriter(size_t size, char* buffer) - : QuicDataWriter(size, buffer, quiche::NETWORK_BYTE_ORDER) {} + : quiche::QuicheDataWriter(size, buffer) {} QuicDataWriter::QuicDataWriter(size_t size, char* buffer, quiche::Endianness endianness) - : buffer_(buffer), capacity_(size), length_(0), endianness_(endianness) {} + : quiche::QuicheDataWriter(size, buffer, endianness) {} QuicDataWriter::~QuicDataWriter() {} -char* QuicDataWriter::data() { - return buffer_; -} - -bool QuicDataWriter::WriteUInt8(uint8_t value) { - return WriteBytes(&value, sizeof(value)); -} - -bool QuicDataWriter::WriteUInt16(uint16_t value) { - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { - value = quiche::QuicheEndian::HostToNet16(value); - } - return WriteBytes(&value, sizeof(value)); -} - -bool QuicDataWriter::WriteUInt32(uint32_t value) { - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { - value = quiche::QuicheEndian::HostToNet32(value); - } - return WriteBytes(&value, sizeof(value)); -} - -bool QuicDataWriter::WriteUInt64(uint64_t value) { - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { - value = quiche::QuicheEndian::HostToNet64(value); - } - return WriteBytes(&value, sizeof(value)); -} - -bool QuicDataWriter::WriteBytesToUInt64(size_t num_bytes, uint64_t value) { - if (num_bytes > sizeof(value)) { - return false; - } - if (endianness_ == quiche::HOST_BYTE_ORDER) { - return WriteBytes(&value, num_bytes); - } - - value = quiche::QuicheEndian::HostToNet64(value); - return WriteBytes(reinterpret_cast<char*>(&value) + sizeof(value) - num_bytes, - num_bytes); -} - bool QuicDataWriter::WriteUFloat16(uint64_t value) { uint16_t result; if (value < (UINT64_C(1) << kUFloat16MantissaEffectiveBits)) { @@ -105,79 +63,12 @@ result = static_cast<uint16_t>(value + (exponent << kUFloat16MantissaBits)); } - if (endianness_ == quiche::NETWORK_BYTE_ORDER) { + if (endianness() == quiche::NETWORK_BYTE_ORDER) { result = quiche::QuicheEndian::HostToNet16(result); } return WriteBytes(&result, sizeof(result)); } -bool QuicDataWriter::WriteStringPiece16(quiche::QuicheStringPiece val) { - if (val.size() > std::numeric_limits<uint16_t>::max()) { - return false; - } - if (!WriteUInt16(static_cast<uint16_t>(val.size()))) { - return false; - } - return WriteBytes(val.data(), val.size()); -} - -bool QuicDataWriter::WriteStringPiece(quiche::QuicheStringPiece val) { - return WriteBytes(val.data(), val.size()); -} - -char* QuicDataWriter::BeginWrite(size_t length) { - if (length_ > capacity_) { - return nullptr; - } - - if (capacity_ - length_ < length) { - return nullptr; - } - -#ifdef ARCH_CPU_64_BITS - DCHECK_LE(length, std::numeric_limits<uint32_t>::max()); -#endif - - return buffer_ + length_; -} - -bool QuicDataWriter::WriteBytes(const void* data, size_t data_len) { - char* dest = BeginWrite(data_len); - if (!dest) { - return false; - } - - memcpy(dest, data, data_len); - - length_ += data_len; - return true; -} - -bool QuicDataWriter::WriteRepeatedByte(uint8_t byte, size_t count) { - char* dest = BeginWrite(count); - if (!dest) { - return false; - } - - memset(dest, byte, count); - - length_ += count; - return true; -} - -void QuicDataWriter::WritePadding() { - DCHECK_LE(length_, capacity_); - if (length_ > capacity_) { - return; - } - memset(buffer_ + length_, 0x00, capacity_ - length_); - length_ = capacity_; -} - -bool QuicDataWriter::WritePaddingBytes(size_t count) { - return WriteRepeatedByte(0x00, count); -} - bool QuicDataWriter::WriteConnectionId(QuicConnectionId connection_id) { if (connection_id.IsEmpty()) { return true; @@ -190,10 +81,6 @@ return WriteUInt8(connection_id.length()) && WriteConnectionId(connection_id); } -bool QuicDataWriter::WriteTag(uint32_t tag) { - return WriteBytes(&tag, sizeof(tag)); -} - bool QuicDataWriter::WriteRandomBytes(QuicRandom* random, size_t length) { char* dest = BeginWrite(length); if (!dest) { @@ -201,17 +88,10 @@ } random->RandBytes(dest, length); - length_ += length; + IncreaseLength(length); return true; } -bool QuicDataWriter::Seek(size_t length) { - if (!BeginWrite(length)) { - return false; - } - length_ += length; - return true; -} // Converts a uint64_t into an IETF/Quic formatted Variable Length // Integer. IETF Variable Length Integers have 62 significant bits, so @@ -231,10 +111,10 @@ // Low-level optimization is useful here because this function will be // called frequently, leading to outsize benefits. bool QuicDataWriter::WriteVarInt62(uint64_t value) { - DCHECK_EQ(endianness_, quiche::NETWORK_BYTE_ORDER); + DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER); - size_t remaining = capacity_ - length_; - char* next = buffer_ + length_; + size_t remaining_bytes = remaining(); + char* next = buffer() + length(); if ((value & kVarInt62ErrorMask) == 0) { // We know the high 2 bits are 0 so |value| is legal. @@ -242,7 +122,7 @@ if ((value & kVarInt62Mask8Bytes) != 0) { // Someplace in the high-4 bytes is a 1-bit. Do an 8-byte // encoding. - if (remaining >= 8) { + if (remaining_bytes >= 8) { *(next + 0) = ((value >> 56) & 0x3f) + 0xc0; *(next + 1) = (value >> 48) & 0xff; *(next + 2) = (value >> 40) & 0xff; @@ -251,7 +131,7 @@ *(next + 5) = (value >> 16) & 0xff; *(next + 6) = (value >> 8) & 0xff; *(next + 7) = value & 0xff; - length_ += 8; + IncreaseLength(8); return true; } return false; @@ -261,12 +141,12 @@ if ((value & kVarInt62Mask4Bytes) != 0) { // The encoding will not fit into 2 bytes, Do a 4-byte // encoding. - if (remaining >= 4) { + if (remaining_bytes >= 4) { *(next + 0) = ((value >> 24) & 0x3f) + 0x80; *(next + 1) = (value >> 16) & 0xff; *(next + 2) = (value >> 8) & 0xff; *(next + 3) = value & 0xff; - length_ += 4; + IncreaseLength(4); return true; } return false; @@ -279,18 +159,18 @@ // are not 0) if ((value & kVarInt62Mask2Bytes) != 0) { // Do 2-byte encoding - if (remaining >= 2) { + if (remaining_bytes >= 2) { *(next + 0) = ((value >> 8) & 0x3f) + 0x40; *(next + 1) = (value)&0xff; - length_ += 2; + IncreaseLength(2); return true; } return false; } - if (remaining >= 1) { + if (remaining_bytes >= 1) { // Do 1-byte encoding *next = (value & 0x3f); - length_ += 1; + IncreaseLength(1); return true; } return false; @@ -302,10 +182,10 @@ bool QuicDataWriter::WriteVarInt62( uint64_t value, QuicVariableLengthIntegerLength write_length) { - DCHECK_EQ(endianness_, quiche::NETWORK_BYTE_ORDER); + DCHECK_EQ(endianness(), quiche::NETWORK_BYTE_ORDER); - size_t remaining = capacity_ - length_; - if (remaining < write_length) { + size_t remaining_bytes = remaining(); + if (remaining_bytes < write_length) { return false; } @@ -366,9 +246,4 @@ return true; } -std::string QuicDataWriter::DebugString() const { - return quiche::QuicheStrCat(" { capacity: ", capacity_, ", length: ", length_, - " }"); -} - } // namespace quic
diff --git a/quic/core/quic_data_writer.h b/quic/core/quic_data_writer.h index 7d90f39..3926c1a 100644 --- a/quic/core/quic_data_writer.h +++ b/quic/core/quic_data_writer.h
@@ -12,6 +12,7 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/common/platform/api/quiche_endian.h" #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h" +#include "net/third_party/quiche/src/common/quiche_data_writer.h" namespace quic { @@ -35,7 +36,7 @@ // The QuicDataWriter supports appending primitive values (int, string, etc) // to a frame instance. The internal memory buffer is exposed as the "data" // of the QuicDataWriter. -class QUIC_EXPORT_PRIVATE QuicDataWriter { +class QUIC_EXPORT_PRIVATE QuicDataWriter : public quiche::QuicheDataWriter { public: // Creates a QuicDataWriter where |buffer| is not owned // using NETWORK_BYTE_ORDER endianness. @@ -48,21 +49,9 @@ ~QuicDataWriter(); - // Returns the size of the QuicDataWriter's data. - size_t length() const { return length_; } - - // Retrieves the buffer from the QuicDataWriter without changing ownership. - char* data(); - // Methods for adding to the payload. These values are appended to the end // of the QuicDataWriter payload. - // Writes 8/16/32/64-bit unsigned integers. - bool WriteUInt8(uint8_t value); - bool WriteUInt16(uint16_t value); - bool WriteUInt32(uint32_t value); - bool WriteUInt64(uint64_t value); - // Write an unsigned-integer value per the IETF QUIC/Variable Length // Integer encoding rules (see draft-ietf-quic-transport-08.txt). // IETF Variable Length Integers have 62 significant bits, so the @@ -88,63 +77,18 @@ // is too large to encode. static QuicVariableLengthIntegerLength GetVarInt62Len(uint64_t value); - // Writes least significant |num_bytes| of a 64-bit unsigned integer in the - // correct byte order. - bool WriteBytesToUInt64(size_t num_bytes, uint64_t value); - // Write unsigned floating point corresponding to the value. Large values are // clamped to the maximum representable (kUFloat16MaxValue). Values that can // not be represented directly are rounded down. bool WriteUFloat16(uint64_t value); - bool WriteStringPiece(quiche::QuicheStringPiece val); - bool WriteStringPiece16(quiche::QuicheStringPiece val); - bool WriteBytes(const void* data, size_t data_len); - bool WriteRepeatedByte(uint8_t byte, size_t count); - // Fills the remaining buffer with null characters. - void WritePadding(); - // Write padding of |count| bytes. - bool WritePaddingBytes(size_t count); - // Write connection ID to the payload. bool WriteConnectionId(QuicConnectionId connection_id); // Write 8-bit length followed by connection ID to the payload. bool WriteLengthPrefixedConnectionId(QuicConnectionId connection_id); - // Write tag as a 32-bit unsigned integer to the payload. As tags are already - // converted to big endian (e.g., CHLO is 'C','H','L','O') in memory by TAG or - // MakeQuicTag and tags are written in byte order, so tags on the wire are - // in big endian. - bool WriteTag(uint32_t tag); - // Write |length| random bytes generated by |random|. bool WriteRandomBytes(QuicRandom* random, size_t length); - - // Advance the writer's position for writing by |length| bytes without writing - // anything. This method only makes sense to be used on a buffer that has - // already been written to (and is having certain parts rewritten). - bool Seek(size_t length); - - size_t capacity() const { return capacity_; } - - size_t remaining() const { return capacity_ - length_; } - - std::string DebugString() const; - - private: - // Returns the location that the data should be written at, or nullptr if - // there is not enough room. Call EndWrite with the returned offset and the - // given length to pad out for the next write. - char* BeginWrite(size_t length); - - // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not - // char. - char* buffer_; - size_t capacity_; // Allocation size of payload (or -1 if buffer is const). - size_t length_; // Current length of the buffer. - - // The endianness to write integers and floating numbers. - quiche::Endianness endianness_; }; } // namespace quic