blob: d85f631ab1ba86940264c024bb3ba3cdd6466e6c [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_WRITER_H_
6#define QUICHE_COMMON_QUICHE_DATA_WRITER_H_
7
8#include <cstddef>
9#include <cstdint>
vasilvv0a09b8f2020-04-27 08:08:55 -070010#include <cstring>
dmcardle2b64f502020-01-07 15:22:36 -080011#include <limits>
12
vasilvv652cd422020-10-09 15:50:02 -070013#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050014#include "common/platform/api/quiche_export.h"
15#include "common/platform/api/quiche_logging.h"
16#include "common/quiche_endian.h"
dmcardle2b64f502020-01-07 15:22:36 -080017
18namespace quiche {
19
20// This class provides facilities for packing binary data.
21//
22// The QuicheDataWriter supports appending primitive values (int, string, etc)
23// to a frame instance. The internal memory buffer is exposed as the "data"
24// of the QuicheDataWriter.
25class QUICHE_EXPORT_PRIVATE QuicheDataWriter {
26 public:
27 // Creates a QuicheDataWriter where |buffer| is not owned
28 // using NETWORK_BYTE_ORDER endianness.
29 QuicheDataWriter(size_t size, char* buffer);
30 // Creates a QuicheDataWriter where |buffer| is not owned
31 // using the specified endianness.
32 QuicheDataWriter(size_t size, char* buffer, quiche::Endianness endianness);
33 QuicheDataWriter(const QuicheDataWriter&) = delete;
34 QuicheDataWriter& operator=(const QuicheDataWriter&) = delete;
35
36 ~QuicheDataWriter();
37
38 // Returns the size of the QuicheDataWriter's data.
39 size_t length() const { return length_; }
40
41 // Retrieves the buffer from the QuicheDataWriter without changing ownership.
42 char* data();
43
44 // Methods for adding to the payload. These values are appended to the end
45 // of the QuicheDataWriter payload.
46
47 // Writes 8/16/32/64-bit unsigned integers.
48 bool WriteUInt8(uint8_t value);
49 bool WriteUInt16(uint16_t value);
50 bool WriteUInt32(uint32_t value);
51 bool WriteUInt64(uint64_t value);
52
53 // Writes least significant |num_bytes| of a 64-bit unsigned integer in the
54 // correct byte order.
55 bool WriteBytesToUInt64(size_t num_bytes, uint64_t value);
56
vasilvv652cd422020-10-09 15:50:02 -070057 bool WriteStringPiece(absl::string_view val);
58 bool WriteStringPiece16(absl::string_view val);
dmcardle2b64f502020-01-07 15:22:36 -080059 bool WriteBytes(const void* data, size_t data_len);
60 bool WriteRepeatedByte(uint8_t byte, size_t count);
61 // Fills the remaining buffer with null characters.
62 void WritePadding();
63 // Write padding of |count| bytes.
64 bool WritePaddingBytes(size_t count);
65
66 // Write tag as a 32-bit unsigned integer to the payload. As tags are already
67 // converted to big endian (e.g., CHLO is 'C','H','L','O') in memory by TAG or
68 // MakeQuicTag and tags are written in byte order, so tags on the wire are
69 // in big endian.
70 bool WriteTag(uint32_t tag);
71
72 // Advance the writer's position for writing by |length| bytes without writing
73 // anything. This method only makes sense to be used on a buffer that has
74 // already been written to (and is having certain parts rewritten).
75 bool Seek(size_t length);
76
77 size_t capacity() const { return capacity_; }
78
79 size_t remaining() const { return capacity_ - length_; }
80
81 std::string DebugString() const;
82
83 protected:
84 // Returns the location that the data should be written at, or nullptr if
85 // there is not enough room. Call EndWrite with the returned offset and the
86 // given length to pad out for the next write.
87 char* BeginWrite(size_t length);
88
89 quiche::Endianness endianness() const { return endianness_; }
90
91 char* buffer() const { return buffer_; }
92
93 void IncreaseLength(size_t delta) {
vasilvvb38e0232021-02-02 15:20:07 -080094 QUICHE_DCHECK_LE(length_, std::numeric_limits<size_t>::max() - delta);
95 QUICHE_DCHECK_LE(length_, capacity_ - delta);
dmcardle2b64f502020-01-07 15:22:36 -080096 length_ += delta;
97 }
98
99 private:
100 // TODO(fkastenholz, b/73004262) change buffer_, et al, to be uint8_t, not
101 // char.
102 char* buffer_;
103 size_t capacity_; // Allocation size of payload (or -1 if buffer is const).
104 size_t length_; // Current length of the buffer.
105
106 // The endianness to write integers and floating numbers.
107 quiche::Endianness endianness_;
108};
109
110} // namespace quiche
111
112#endif // QUICHE_COMMON_QUICHE_DATA_WRITER_H_