LLDB mainline
DataEncoder.h
Go to the documentation of this file.
1//===-- DataEncoder.h -------------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_UTILITY_DATAENCODER_H
10#define LLDB_UTILITY_DATAENCODER_H
11
12#include "lldb/lldb-defines.h"
14#include "lldb/lldb-forward.h"
15#include "lldb/lldb-types.h"
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/StringRef.h"
19
20#include <cstddef>
21#include <cstdint>
22
23namespace lldb_private {
24
25/// \class DataEncoder
26///
27/// An binary data encoding class.
28///
29/// DataEncoder is a class that can encode binary data (swapping if needed) to
30/// a data buffer. The DataEncoder can be constructed with data that will be
31/// copied into the internally owned buffer. This allows data to be modified
32/// in the internal buffer. The DataEncoder object can also be constructed with
33/// just a byte order and address size and data can be appended to the
34/// internally owned buffer.
35///
36/// Clients can get a shared pointer to the data buffer when done modifying or
37/// creating the data to keep the data around after the lifetime of a
38/// DataEncoder object. \see GetDataBuffer
39///
40/// Client can get a reference to the object owned data as an array by calling
41/// the GetData method. \see GetData
43public:
44 /// Default constructor.
45 ///
46 /// Initialize all members to a default empty state and create a empty memory
47 /// buffer that can be appended to. The ByteOrder and address size will be set
48 /// to match the current host system.
50
51 /// Construct an encoder that copies the specified data into the object owned
52 /// data buffer.
53 ///
54 /// This constructor is designed to be used when you have a data buffer and
55 /// want to modify values within the buffer. A copy of the data will be made
56 /// in the internally owned buffer and that data can be fixed up and appended
57 /// to.
58 ///
59 /// \param[in] data
60 /// A pointer to caller owned data.
61 ///
62 /// \param[in] data_length
63 /// The length in bytes of \a data.
64 ///
65 /// \param[in] byte_order
66 /// A byte order for the data that will be encoded.
67 ///
68 /// \param[in] addr_size
69 /// A size of an address in bytes. \see PutAddress, AppendAddress
70 DataEncoder(const void *data, uint32_t data_length,
71 lldb::ByteOrder byte_order, uint8_t addr_size);
72
73 /// Construct an encoder that owns a heap based memory buffer.
74 ///
75 /// This allows clients to create binary data from scratch by appending values
76 /// with the methods that start with "Append".
77 ///
78 /// \param[in] byte_order
79 /// A byte order for the data that will be encoded.
80 ///
81 /// \param[in] addr_size
82 /// A size of an address in bytes. \see PutAddress, AppendAddress
83 DataEncoder(lldb::ByteOrder byte_order, uint8_t addr_size);
84
86
87 /// Encode an unsigned integer of size \a byte_size to \a offset.
88 ///
89 /// Encode a single integer value at \a offset and return the offset that
90 /// follows the newly encoded integer when the data is successfully encoded
91 /// into the existing data. There must be enough room in the existing data,
92 /// else UINT32_MAX will be returned to indicate that encoding failed.
93 ///
94 /// \param[in] offset
95 /// The offset within the contained data at which to put the encoded
96 /// integer.
97 ///
98 /// \param[in] byte_size
99 /// The size in byte of the integer to encode.
100 ///
101 /// \param[in] value
102 /// The integer value to write. The least significant bytes of
103 /// the integer value will be written if the size is less than
104 /// 8 bytes.
105 ///
106 /// \return
107 /// The next offset in the bytes of this data if the integer
108 /// was successfully encoded, UINT32_MAX if the encoding failed.
109 uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value);
110
111 /// Encode an unsigned integer at offset \a offset.
112 ///
113 /// Encode a single unsigned integer value at \a offset and return the offset
114 /// that follows the newly encoded integer when the data is successfully
115 /// encoded into the existing data. There must be enough room in the data,
116 /// else UINT32_MAX will be returned to indicate that encoding failed.
117 ///
118 /// \param[in] offset
119 /// The offset within the contained data at which to put the encoded
120 /// integer.
121 ///
122 /// \param[in] value
123 /// The integer value to write.
124 ///
125 /// \return
126 /// The next offset in the bytes of this data if the integer was
127 /// successfully encoded, UINT32_MAX if the encoding failed.
128 uint32_t PutU8(uint32_t offset, uint8_t value);
129 uint32_t PutU16(uint32_t offset, uint16_t value);
130 uint32_t PutU32(uint32_t offset, uint32_t value);
131 uint32_t PutU64(uint32_t offset, uint64_t value);
132
133 /// Append a unsigned integer to the end of the owned data.
134 ///
135 /// \param value
136 /// A unsigned integer value to append.
137 void AppendU8(uint8_t value);
138 void AppendU16(uint16_t value);
139 void AppendU32(uint32_t value);
140 void AppendU64(uint64_t value);
141
142 /// Append an address sized integer to the end of the owned data.
143 ///
144 /// \param addr
145 /// A unsigned integer address value to append. The size of the address
146 /// will be determined by the address size specified in the constructor.
147 void AppendAddress(lldb::addr_t addr);
148
149 /// Append a bytes to the end of the owned data.
150 ///
151 /// Append the bytes contained in the string reference. This function will
152 /// not append a NULL termination character for a C string. Use the
153 /// AppendCString function for this purpose.
154 ///
155 /// \param data
156 /// A string reference that contains bytes to append.
157 void AppendData(llvm::StringRef data);
158
159 /// Append a bytes to the end of the owned data.
160 ///
161 /// Append the bytes contained in the array reference.
162 ///
163 /// \param data
164 /// A array reference that contains bytes to append.
165 void AppendData(llvm::ArrayRef<uint8_t> data);
166
167 /// Append a C string to the end of the owned data.
168 ///
169 /// Append the bytes contained in the string reference along with an extra
170 /// NULL termination character if the StringRef bytes doesn't include one as
171 /// the last byte.
172 ///
173 /// \param data
174 /// A string reference that contains bytes to append.
175 void AppendCString(llvm::StringRef data);
176
177 /// Encode an arbitrary number of bytes.
178 ///
179 /// \param[in] offset
180 /// The offset in bytes into the contained data at which to
181 /// start encoding.
182 ///
183 /// \param[in] src
184 /// The buffer that contains the bytes to encode.
185 ///
186 /// \param[in] src_len
187 /// The number of bytes to encode.
188 ///
189 /// \return
190 /// The next valid offset within data if the put operation
191 /// was successful, else UINT32_MAX to indicate the put failed.
192 uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len);
193
194 /// Encode an address in the existing buffer at \a offset bytes into the
195 /// buffer.
196 ///
197 /// Encode a single address to the data and return the next offset where
198 /// subsequent data would go. The size of the address comes from the \a
199 /// m_addr_size member variable and should be set correctly prior to encoding
200 /// any address values.
201 ///
202 /// \param[in] offset
203 /// The offset where to encode the address.
204 ///
205 /// \param[in] addr
206 /// The address to encode.
207 ///
208 /// \return
209 /// The next valid offset within data if the put operation
210 /// was successful, else UINT32_MAX to indicate the put failed.
211 uint32_t PutAddress(uint32_t offset, lldb::addr_t addr);
212
213 /// Put a C string to \a offset.
214 ///
215 /// Encodes a C string into the existing data including the terminating. If
216 /// there is not enough room in the buffer to fit the entire C string and the
217 /// NULL terminator in the existing buffer bounds, then this function will
218 /// fail.
219 ///
220 /// \param[in] offset
221 /// The offset where to encode the string.
222 ///
223 /// \param[in] cstr
224 /// The string to encode.
225 ///
226 /// \return
227 /// The next valid offset within data if the put operation was successful,
228 /// else UINT32_MAX to indicate the put failed.
229 uint32_t PutCString(uint32_t offset, const char *cstr);
230
231 /// Get a shared copy of the heap based memory buffer owned by this object.
232 ///
233 /// This allows a data encoder to be used to create a data buffer that can
234 /// be extracted and used elsewhere after this object is destroyed.
235 ///
236 /// \return
237 /// A shared pointer to the DataBufferHeap that contains the data that was
238 /// encoded into this object.
239 std::shared_ptr<lldb_private::DataBufferHeap> GetDataBuffer() {
240 return m_data_sp;
241 }
242
243 /// Get a access to the bytes that this references.
244 ///
245 /// This value will always return the data that this object references even if
246 /// the object was constructed with caller owned data.
247 ///
248 /// \return
249 /// A array reference to the data that this object references.
250 llvm::ArrayRef<uint8_t> GetData() const;
251
252 /// Get the number of bytes contained in this object.
253 ///
254 /// \return
255 /// The total number of bytes of data this object refers to.
256 size_t GetByteSize() const;
257
259
260 /// The address size to use when encoding pointers or addresses.
261 uint8_t GetAddressByteSize() const { return m_addr_size; }
262
263private:
264 uint32_t BytesLeft(uint32_t offset) const {
265 const uint32_t size = GetByteSize();
266 if (size > offset)
267 return size - offset;
268 return 0;
269 }
270
271 /// Test the availability of \a length bytes of data from \a offset.
272 ///
273 /// \return
274 /// \b true if \a offset is a valid offset and there are \a
275 /// length bytes available at that offset, \b false otherwise.
276 bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
277 return length <= BytesLeft(offset);
278 }
279
280 /// Test the validity of \a offset.
281 ///
282 /// \return
283 /// \b true if \a offset is a valid offset into the data in this
284 /// object, \b false otherwise.
285 bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
286
287 /// The shared pointer to data that can grow as data is added
288 std::shared_ptr<lldb_private::DataBufferHeap> m_data_sp;
289
290 /// The byte order of the data we are encoding to.
292
293 /// The address size to use when encoding pointers or addresses.
294 const uint8_t m_addr_size;
295
296 DataEncoder(const DataEncoder &) = delete;
297 const DataEncoder &operator=(const DataEncoder &) = delete;
298};
299
300} // namespace lldb_private
301
302#endif // LLDB_UTILITY_DATAENCODER_H
An binary data encoding class.
Definition: DataEncoder.h:42
DataEncoder()
Default constructor.
Definition: DataEncoder.cpp:25
const lldb::ByteOrder m_byte_order
The byte order of the data we are encoding to.
Definition: DataEncoder.h:291
lldb::ByteOrder GetByteOrder() const
Definition: DataEncoder.h:258
uint32_t BytesLeft(uint32_t offset) const
Definition: DataEncoder.h:264
uint32_t PutU8(uint32_t offset, uint8_t value)
Encode an unsigned integer at offset offset.
Definition: DataEncoder.cpp:50
void AppendCString(llvm::StringRef data)
Append a C string to the end of the owned data.
std::shared_ptr< lldb_private::DataBufferHeap > GetDataBuffer()
Get a shared copy of the heap based memory buffer owned by this object.
Definition: DataEncoder.h:239
uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value)
Encode an unsigned integer of size byte_size to offset.
Definition: DataEncoder.cpp:94
uint32_t PutAddress(uint32_t offset, lldb::addr_t addr)
Encode an address in the existing buffer at offset bytes into the buffer.
llvm::ArrayRef< uint8_t > GetData() const
Get a access to the bytes that this references.
Definition: DataEncoder.cpp:40
void AppendAddress(lldb::addr_t addr)
Append an address sized integer to the end of the owned data.
void AppendU32(uint32_t value)
uint32_t PutU64(uint32_t offset, uint64_t value)
Definition: DataEncoder.cpp:82
uint32_t PutCString(uint32_t offset, const char *cstr)
Put a C string to offset.
std::shared_ptr< lldb_private::DataBufferHeap > m_data_sp
The shared pointer to data that can grow as data is added.
Definition: DataEncoder.h:288
const uint8_t m_addr_size
The address size to use when encoding pointers or addresses.
Definition: DataEncoder.h:294
bool ValidOffset(uint32_t offset) const
Test the validity of offset.
Definition: DataEncoder.h:285
size_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataEncoder.cpp:44
uint32_t PutU32(uint32_t offset, uint32_t value)
Definition: DataEncoder.cpp:70
void AppendU8(uint8_t value)
Append a unsigned integer to the end of the owned data.
DataEncoder(const DataEncoder &)=delete
void AppendData(llvm::StringRef data)
Append a bytes to the end of the owned data.
void AppendU16(uint16_t value)
void AppendU64(uint64_t value)
uint8_t GetAddressByteSize() const
The address size to use when encoding pointers or addresses.
Definition: DataEncoder.h:261
const DataEncoder & operator=(const DataEncoder &)=delete
bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const
Test the availability of length bytes of data from offset.
Definition: DataEncoder.h:276
uint32_t PutU16(uint32_t offset, uint16_t value)
Definition: DataEncoder.cpp:58
uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len)
Encode an arbitrary number of bytes.
A class that represents a running process on the host machine.
ByteOrder
Byte ordering definitions.
uint64_t addr_t
Definition: lldb-types.h:80