blob: 19b7cef9f0ca30d62781702a3411d25bdcb550ca [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===-- 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 liblldb_DataEncoder_h_
10#define liblldb_DataEncoder_h_
11
12#if defined(__cplusplus)
13
14#include "lldb/lldb-defines.h"
15#include "lldb/lldb-enumerations.h"
16#include "lldb/lldb-forward.h"
17#include "lldb/lldb-types.h"
18
19#include <stddef.h>
20#include <stdint.h>
21
22namespace lldb_private {
23
24/// \class DataEncoder DataEncoder.h "lldb/Core/DataEncoder.h" An binary data
25/// encoding class.
26///
27/// DataEncoder is a class that can encode binary data (swapping if needed) to
28/// a data buffer. The data buffer can be caller owned, or can be shared data
29/// that can be shared between multiple DataEncoder or DataEncoder instances.
30///
31/// \see DataBuffer
32class DataEncoder {
33public:
34 /// Default constructor.
35 ///
36 /// Initialize all members to a default empty state.
37 DataEncoder();
38
39 /// Construct with a buffer that is owned by the caller.
40 ///
41 /// This constructor allows us to use data that is owned by the caller. The
42 /// data must stay around as long as this object is valid.
43 ///
44 /// \param[in] data
45 /// A pointer to caller owned data.
46 ///
47 /// \param[in] data_length
48 /// The length in bytes of \a data.
49 ///
50 /// \param[in] byte_order
51 /// A byte order of the data that we are extracting from.
52 ///
53 /// \param[in] addr_size
54 /// A new address byte size value.
55 DataEncoder(void *data, uint32_t data_length, lldb::ByteOrder byte_order,
56 uint8_t addr_size);
57
58 /// Construct with shared data.
59 ///
60 /// Copies the data shared pointer which adds a reference to the contained
61 /// in \a data_sp. The shared data reference is reference counted to ensure
62 /// the data lives as long as anyone still has a valid shared pointer to the
63 /// data in \a data_sp.
64 ///
65 /// \param[in] data_sp
66 /// A shared pointer to data.
67 ///
68 /// \param[in] byte_order
69 /// A byte order of the data that we are extracting from.
70 ///
71 /// \param[in] addr_size
72 /// A new address byte size value.
73 DataEncoder(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order,
74 uint8_t addr_size);
75
76 /// Destructor
77 ///
78 /// If this object contains a valid shared data reference, the reference
79 /// count on the data will be decremented, and if zero, the data will be
80 /// freed.
81 ~DataEncoder();
82
83 /// Clears the object state.
84 ///
85 /// Clears the object contents back to a default invalid state, and release
86 /// any references to shared data that this object may contain.
87 void Clear();
88
89 /// Get the current address size.
90 ///
91 /// Return the size in bytes of any address values this object will extract.
92 ///
93 /// \return
94 /// The size in bytes of address values that will be extracted.
95 uint8_t GetAddressByteSize() const { return m_addr_size; }
96
97 /// Get the number of bytes contained in this object.
98 ///
99 /// \return
100 /// The total number of bytes of data this object refers to.
101 size_t GetByteSize() const { return m_end - m_start; }
102
103 /// Get the data end pointer.
104 ///
105 /// \return
106 /// Returns a pointer to the next byte contained in this
107 /// object's data, or NULL of there is no data in this object.
108 uint8_t *GetDataEnd() { return m_end; }
109
110 const uint8_t *GetDataEnd() const { return m_end; }
111
112 /// Get the shared data offset.
113 ///
114 /// Get the offset of the first byte of data in the shared data (if any).
115 ///
116 /// \return
117 /// If this object contains shared data, this function returns
118 /// the offset in bytes into that shared data, zero otherwise.
119 size_t GetSharedDataOffset() const;
120
121 /// Get the current byte order value.
122 ///
123 /// \return
124 /// The current byte order value from this object's internal
125 /// state.
126 lldb::ByteOrder GetByteOrder() const { return m_byte_order; }
127
128 /// Get the data start pointer.
129 ///
130 /// \return
131 /// Returns a pointer to the first byte contained in this
132 /// object's data, or NULL of there is no data in this object.
133 uint8_t *GetDataStart() { return m_start; }
134
135 const uint8_t *GetDataStart() const { return m_start; }
136
137 /// Encode unsigned integer values into the data at \a offset.
138 ///
139 /// \param[in] offset
140 /// The offset within the contained data at which to put the
141 /// data.
142 ///
143 /// \param[in] value
144 /// The value to encode into the data.
145 ///
146 /// \return
147 /// The next offset in the bytes of this data if the data
148 /// was successfully encoded, UINT32_MAX if the encoding failed.
149 uint32_t PutU8(uint32_t offset, uint8_t value);
150
151 uint32_t PutU16(uint32_t offset, uint16_t value);
152
153 uint32_t PutU32(uint32_t offset, uint32_t value);
154
155 uint32_t PutU64(uint32_t offset, uint64_t value);
156
157 /// Encode an unsigned integer of size \a byte_size to \a offset.
158 ///
159 /// Encode a single integer value at \a offset and return the offset that
160 /// follows the newly encoded integer when the data is successfully encoded
161 /// into the existing data. There must be enough room in the data, else
162 /// UINT32_MAX will be returned to indicate that encoding failed.
163 ///
164 /// \param[in] offset
165 /// The offset within the contained data at which to put the
166 /// encoded integer.
167 ///
168 /// \param[in] byte_size
169 /// The size in byte of the integer to encode.
170 ///
171 /// \param[in] value
172 /// The integer value to write. The least significant bytes of
173 /// the integer value will be written if the size is less than
174 /// 8 bytes.
175 ///
176 /// \return
177 /// The next offset in the bytes of this data if the integer
178 /// was successfully encoded, UINT32_MAX if the encoding failed.
179 uint32_t PutMaxU64(uint32_t offset, uint32_t byte_size, uint64_t value);
180
181 /// Encode an arbitrary number of bytes.
182 ///
183 /// \param[in] offset
184 /// The offset in bytes into the contained data at which to
185 /// start encoding.
186 ///
187 /// \param[in] src
188 /// The buffer that contains the bytes to encode.
189 ///
190 /// \param[in] src_len
191 /// The number of bytes to encode.
192 ///
193 /// \return
194 /// The next valid offset within data if the put operation
195 /// was successful, else UINT32_MAX to indicate the put failed.
196 uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len);
197
198 /// Encode an address in the existing buffer at \a offset bytes into the
199 /// buffer.
200 ///
201 /// Encode a single address (honoring the m_addr_size member) to the data
202 /// and return the next offset where subsequent data would go. pointed to by
203 /// \a offset_ptr. The size of the extracted address comes from the \a
204 /// m_addr_size member variable and should be set correctly prior to
205 /// extracting any address values.
206 ///
207 /// \param[in,out] offset_ptr
208 /// A pointer to an offset within the data that will be advanced
209 /// by the appropriate number of bytes if the value is extracted
210 /// correctly. If the offset is out of bounds or there are not
211 /// enough bytes to extract this value, the offset will be left
212 /// unmodified.
213 ///
214 /// \return
215 /// The next valid offset within data if the put operation
216 /// was successful, else UINT32_MAX to indicate the put failed.
217 uint32_t PutAddress(uint32_t offset, lldb::addr_t addr);
218
219 /// Put a C string to \a offset.
220 ///
221 /// Encodes a C string into the existing data including the terminating
222 ///
223 /// \param[in,out] offset_ptr
224 /// A pointer to an offset within the data that will be advanced
225 /// by the appropriate number of bytes if the value is extracted
226 /// correctly. If the offset is out of bounds or there are not
227 /// enough bytes to extract this value, the offset will be left
228 /// unmodified.
229 ///
230 /// \return
231 /// A pointer to the C string value in the data. If the offset
232 /// pointed to by \a offset_ptr is out of bounds, or if the
233 /// offset plus the length of the C string is out of bounds,
234 /// NULL will be returned.
235 uint32_t PutCString(uint32_t offset_ptr, const char *cstr);
236
237 lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; }
238
239 /// Set the address byte size.
240 ///
241 /// Set the size in bytes that will be used when extracting any address and
242 /// pointer values from data contained in this object.
243 ///
244 /// \param[in] addr_size
245 /// The size in bytes to use when extracting addresses.
246 void SetAddressByteSize(uint8_t addr_size) { m_addr_size = addr_size; }
247
248 /// Set data with a buffer that is caller owned.
249 ///
250 /// Use data that is owned by the caller when extracting values. The data
251 /// must stay around as long as this object, or any object that copies a
252 /// subset of this object's data, is valid. If \a bytes is NULL, or \a
253 /// length is zero, this object will contain no data.
254 ///
255 /// \param[in] bytes
256 /// A pointer to caller owned data.
257 ///
258 /// \param[in] length
259 /// The length in bytes of \a bytes.
260 ///
261 /// \param[in] byte_order
262 /// A byte order of the data that we are extracting from.
263 ///
264 /// \return
265 /// The number of bytes that this object now contains.
266 uint32_t SetData(void *bytes, uint32_t length, lldb::ByteOrder byte_order);
267
268 /// Adopt a subset of shared data in \a data_sp.
269 ///
270 /// Copies the data shared pointer which adds a reference to the contained
271 /// in \a data_sp. The shared data reference is reference counted to ensure
272 /// the data lives as long as anyone still has a valid shared pointer to the
273 /// data in \a data_sp. The byte order and address byte size settings remain
274 /// the same. If \a offset is not a valid offset in \a data_sp, then no
275 /// reference to the shared data will be added. If there are not \a length
276 /// bytes available in \a data starting at \a offset, the length will be
277 /// truncated to contains as many bytes as possible.
278 ///
279 /// \param[in] data_sp
280 /// A shared pointer to data.
281 ///
282 /// \param[in] offset
283 /// The offset into \a data_sp at which the subset starts.
284 ///
285 /// \param[in] length
286 /// The length in bytes of the subset of \a data_sp.
287 ///
288 /// \return
289 /// The number of bytes that this object now contains.
290 uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0,
291 uint32_t length = UINT32_MAX);
292
293 /// Set the byte_order value.
294 ///
295 /// Sets the byte order of the data to extract. Extracted values will be
296 /// swapped if necessary when decoding.
297 ///
298 /// \param[in] byte_order
299 /// The byte order value to use when extracting data.
300 void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; }
301
302 /// Test the validity of \a offset.
303 ///
304 /// \return
305 /// \b true if \a offset is a valid offset into the data in this
306 /// object, \b false otherwise.
307 bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
308
309 /// Test the availability of \a length bytes of data from \a offset.
310 ///
311 /// \return
312 /// \b true if \a offset is a valid offset and there are \a
313 /// length bytes available at that offset, \b false otherwise.
314 bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
315 return length <= BytesLeft(offset);
316 }
317
318 uint32_t BytesLeft(uint32_t offset) const {
319 const uint32_t size = GetByteSize();
320 if (size > offset)
321 return size - offset;
322 return 0;
323 }
324
325protected:
326 // Member variables
327 uint8_t *m_start; ///< A pointer to the first byte of data.
328 uint8_t *m_end; ///< A pointer to the byte that is past the end of the data.
329 lldb::ByteOrder
330 m_byte_order; ///< The byte order of the data we are extracting from.
331 uint8_t m_addr_size; ///< The address size to use when extracting pointers or
332 /// addresses
333 mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can
334 /// be shared among multiple instances
335
336private:
337 DISALLOW_COPY_AND_ASSIGN(DataEncoder);
338};
339
340} // namespace lldb_private
341
342#endif // #if defined (__cplusplus)
343#endif // #ifndef liblldb_DataEncoder_h_