DataEncoder.h revision 344779
1317027Sdim//===-- DataEncoder.h -------------------------------------------*- C++ -*-===//
2317027Sdim//
3317027Sdim//                     The LLVM Compiler Infrastructure
4317027Sdim//
5317027Sdim// This file is distributed under the University of Illinois Open Source
6317027Sdim// License. See LICENSE.TXT for details.
7317027Sdim//
8317027Sdim//===----------------------------------------------------------------------===//
9317027Sdim
10317027Sdim#ifndef liblldb_DataEncoder_h_
11317027Sdim#define liblldb_DataEncoder_h_
12317027Sdim
13317027Sdim#if defined(__cplusplus)
14317027Sdim
15344779Sdim#include "lldb/lldb-defines.h"
16344779Sdim#include "lldb/lldb-enumerations.h"
17344779Sdim#include "lldb/lldb-forward.h"
18344779Sdim#include "lldb/lldb-types.h"
19317027Sdim
20344779Sdim#include <stddef.h>
21317027Sdim#include <stdint.h>
22317027Sdim
23317027Sdimnamespace lldb_private {
24317027Sdim
25317027Sdim//----------------------------------------------------------------------
26341825Sdim/// @class DataEncoder DataEncoder.h "lldb/Core/DataEncoder.h" An binary data
27341825Sdim/// encoding class.
28317027Sdim///
29341825Sdim/// DataEncoder is a class that can encode binary data (swapping if needed) to
30341825Sdim/// a data buffer. The data buffer can be caller owned, or can be shared data
31341825Sdim/// that can be shared between multiple DataEncoder or DataEncoder instances.
32317027Sdim///
33317027Sdim/// @see DataBuffer
34317027Sdim//----------------------------------------------------------------------
35317027Sdimclass DataEncoder {
36317027Sdimpublic:
37317027Sdim  //------------------------------------------------------------------
38317027Sdim  /// Default constructor.
39317027Sdim  ///
40317027Sdim  /// Initialize all members to a default empty state.
41317027Sdim  //------------------------------------------------------------------
42317027Sdim  DataEncoder();
43317027Sdim
44317027Sdim  //------------------------------------------------------------------
45317027Sdim  /// Construct with a buffer that is owned by the caller.
46317027Sdim  ///
47341825Sdim  /// This constructor allows us to use data that is owned by the caller. The
48341825Sdim  /// data must stay around as long as this object is valid.
49317027Sdim  ///
50317027Sdim  /// @param[in] data
51317027Sdim  ///     A pointer to caller owned data.
52317027Sdim  ///
53317027Sdim  /// @param[in] data_length
54317027Sdim  ///     The length in bytes of \a data.
55317027Sdim  ///
56317027Sdim  /// @param[in] byte_order
57317027Sdim  ///     A byte order of the data that we are extracting from.
58317027Sdim  ///
59317027Sdim  /// @param[in] addr_size
60317027Sdim  ///     A new address byte size value.
61317027Sdim  //------------------------------------------------------------------
62317027Sdim  DataEncoder(void *data, uint32_t data_length, lldb::ByteOrder byte_order,
63317027Sdim              uint8_t addr_size);
64317027Sdim
65317027Sdim  //------------------------------------------------------------------
66317027Sdim  /// Construct with shared data.
67317027Sdim  ///
68341825Sdim  /// Copies the data shared pointer which adds a reference to the contained
69341825Sdim  /// in \a data_sp. The shared data reference is reference counted to ensure
70341825Sdim  /// the data lives as long as anyone still has a valid shared pointer to the
71341825Sdim  /// data in \a data_sp.
72317027Sdim  ///
73317027Sdim  /// @param[in] data_sp
74317027Sdim  ///     A shared pointer to data.
75317027Sdim  ///
76317027Sdim  /// @param[in] byte_order
77317027Sdim  ///     A byte order of the data that we are extracting from.
78317027Sdim  ///
79317027Sdim  /// @param[in] addr_size
80317027Sdim  ///     A new address byte size value.
81317027Sdim  //------------------------------------------------------------------
82317027Sdim  DataEncoder(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order,
83317027Sdim              uint8_t addr_size);
84317027Sdim
85317027Sdim  //------------------------------------------------------------------
86317027Sdim  /// Destructor
87317027Sdim  ///
88341825Sdim  /// If this object contains a valid shared data reference, the reference
89341825Sdim  /// count on the data will be decremented, and if zero, the data will be
90341825Sdim  /// freed.
91317027Sdim  //------------------------------------------------------------------
92317027Sdim  ~DataEncoder();
93317027Sdim
94317027Sdim  //------------------------------------------------------------------
95317027Sdim  /// Clears the object state.
96317027Sdim  ///
97341825Sdim  /// Clears the object contents back to a default invalid state, and release
98341825Sdim  /// any references to shared data that this object may contain.
99317027Sdim  //------------------------------------------------------------------
100317027Sdim  void Clear();
101317027Sdim
102317027Sdim  //------------------------------------------------------------------
103317027Sdim  /// Get the current address size.
104317027Sdim  ///
105341825Sdim  /// Return the size in bytes of any address values this object will extract.
106317027Sdim  ///
107317027Sdim  /// @return
108317027Sdim  ///     The size in bytes of address values that will be extracted.
109317027Sdim  //------------------------------------------------------------------
110317027Sdim  uint8_t GetAddressByteSize() const { return m_addr_size; }
111317027Sdim
112317027Sdim  //------------------------------------------------------------------
113317027Sdim  /// Get the number of bytes contained in this object.
114317027Sdim  ///
115317027Sdim  /// @return
116317027Sdim  ///     The total number of bytes of data this object refers to.
117317027Sdim  //------------------------------------------------------------------
118317027Sdim  size_t GetByteSize() const { return m_end - m_start; }
119317027Sdim
120317027Sdim  //------------------------------------------------------------------
121317027Sdim  /// Get the data end pointer.
122317027Sdim  ///
123317027Sdim  /// @return
124317027Sdim  ///     Returns a pointer to the next byte contained in this
125317027Sdim  ///     object's data, or NULL of there is no data in this object.
126317027Sdim  //------------------------------------------------------------------
127317027Sdim  uint8_t *GetDataEnd() { return m_end; }
128317027Sdim
129317027Sdim  const uint8_t *GetDataEnd() const { return m_end; }
130317027Sdim
131317027Sdim  //------------------------------------------------------------------
132317027Sdim  /// Get the shared data offset.
133317027Sdim  ///
134341825Sdim  /// Get the offset of the first byte of data in the shared data (if any).
135317027Sdim  ///
136317027Sdim  /// @return
137317027Sdim  ///     If this object contains shared data, this function returns
138317027Sdim  ///     the offset in bytes into that shared data, zero otherwise.
139317027Sdim  //------------------------------------------------------------------
140317027Sdim  size_t GetSharedDataOffset() const;
141317027Sdim
142317027Sdim  //------------------------------------------------------------------
143317027Sdim  /// Get the current byte order value.
144317027Sdim  ///
145317027Sdim  /// @return
146317027Sdim  ///     The current byte order value from this object's internal
147317027Sdim  ///     state.
148317027Sdim  //------------------------------------------------------------------
149317027Sdim  lldb::ByteOrder GetByteOrder() const { return m_byte_order; }
150317027Sdim
151317027Sdim  //------------------------------------------------------------------
152317027Sdim  /// Get the data start pointer.
153317027Sdim  ///
154317027Sdim  /// @return
155317027Sdim  ///     Returns a pointer to the first byte contained in this
156317027Sdim  ///     object's data, or NULL of there is no data in this object.
157317027Sdim  //------------------------------------------------------------------
158317027Sdim  uint8_t *GetDataStart() { return m_start; }
159317027Sdim
160317027Sdim  const uint8_t *GetDataStart() const { return m_start; }
161317027Sdim
162317027Sdim  //------------------------------------------------------------------
163317027Sdim  /// Encode unsigned integer values into the data at \a offset.
164317027Sdim  ///
165317027Sdim  /// @param[in] offset
166317027Sdim  ///     The offset within the contained data at which to put the
167317027Sdim  ///     data.
168317027Sdim  ///
169317027Sdim  /// @param[in] value
170317027Sdim  ///     The value to encode into the data.
171317027Sdim  ///
172317027Sdim  /// @return
173317027Sdim  ///     The next offset in the bytes of this data if the data
174317027Sdim  ///     was successfully encoded, UINT32_MAX if the encoding failed.
175317027Sdim  //------------------------------------------------------------------
176317027Sdim  uint32_t PutU8(uint32_t offset, uint8_t value);
177317027Sdim
178317027Sdim  uint32_t PutU16(uint32_t offset, uint16_t value);
179317027Sdim
180317027Sdim  uint32_t PutU32(uint32_t offset, uint32_t value);
181317027Sdim
182317027Sdim  uint32_t PutU64(uint32_t offset, uint64_t value);
183317027Sdim
184317027Sdim  //------------------------------------------------------------------
185317027Sdim  /// Encode an unsigned integer of size \a byte_size to \a offset.
186317027Sdim  ///
187341825Sdim  /// Encode a single integer value at \a offset and return the offset that
188341825Sdim  /// follows the newly encoded integer when the data is successfully encoded
189341825Sdim  /// into the existing data. There must be enough room in the data, else
190341825Sdim  /// UINT32_MAX will be returned to indicate that encoding failed.
191317027Sdim  ///
192317027Sdim  /// @param[in] offset
193317027Sdim  ///     The offset within the contained data at which to put the
194317027Sdim  ///     encoded integer.
195317027Sdim  ///
196317027Sdim  /// @param[in] byte_size
197317027Sdim  ///     The size in byte of the integer to encode.
198317027Sdim  ///
199317027Sdim  /// @param[in] value
200317027Sdim  ///     The integer value to write. The least significant bytes of
201317027Sdim  ///     the integer value will be written if the size is less than
202317027Sdim  ///     8 bytes.
203317027Sdim  ///
204317027Sdim  /// @return
205317027Sdim  ///     The next offset in the bytes of this data if the integer
206317027Sdim  ///     was successfully encoded, UINT32_MAX if the encoding failed.
207317027Sdim  //------------------------------------------------------------------
208317027Sdim  uint32_t PutMaxU64(uint32_t offset, uint32_t byte_size, uint64_t value);
209317027Sdim
210317027Sdim  //------------------------------------------------------------------
211317027Sdim  /// Encode an arbitrary number of bytes.
212317027Sdim  ///
213317027Sdim  /// @param[in] offset
214317027Sdim  ///     The offset in bytes into the contained data at which to
215317027Sdim  ///     start encoding.
216317027Sdim  ///
217317027Sdim  /// @param[in] src
218317027Sdim  ///     The buffer that contains the bytes to encode.
219317027Sdim  ///
220317027Sdim  /// @param[in] src_len
221317027Sdim  ///     The number of bytes to encode.
222317027Sdim  ///
223317027Sdim  /// @return
224317027Sdim  ///     The next valid offset within data if the put operation
225317027Sdim  ///     was successful, else UINT32_MAX to indicate the put failed.
226317027Sdim  //------------------------------------------------------------------
227317027Sdim  uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len);
228317027Sdim
229317027Sdim  //------------------------------------------------------------------
230341825Sdim  /// Encode an address in the existing buffer at \a offset bytes into the
231341825Sdim  /// buffer.
232317027Sdim  ///
233341825Sdim  /// Encode a single address (honoring the m_addr_size member) to the data
234341825Sdim  /// and return the next offset where subsequent data would go. pointed to by
235341825Sdim  /// \a offset_ptr. The size of the extracted address comes from the \a
236341825Sdim  /// m_addr_size member variable and should be set correctly prior to
237341825Sdim  /// extracting any address values.
238317027Sdim  ///
239317027Sdim  /// @param[in,out] offset_ptr
240317027Sdim  ///     A pointer to an offset within the data that will be advanced
241317027Sdim  ///     by the appropriate number of bytes if the value is extracted
242317027Sdim  ///     correctly. If the offset is out of bounds or there are not
243317027Sdim  ///     enough bytes to extract this value, the offset will be left
244317027Sdim  ///     unmodified.
245317027Sdim  ///
246317027Sdim  /// @return
247317027Sdim  ///     The next valid offset within data if the put operation
248317027Sdim  ///     was successful, else UINT32_MAX to indicate the put failed.
249317027Sdim  //------------------------------------------------------------------
250317027Sdim  uint32_t PutAddress(uint32_t offset, lldb::addr_t addr);
251317027Sdim
252317027Sdim  //------------------------------------------------------------------
253317027Sdim  /// Put a C string to \a offset.
254317027Sdim  ///
255341825Sdim  /// Encodes a C string into the existing data including the terminating
256317027Sdim  ///
257317027Sdim  /// @param[in,out] offset_ptr
258317027Sdim  ///     A pointer to an offset within the data that will be advanced
259317027Sdim  ///     by the appropriate number of bytes if the value is extracted
260317027Sdim  ///     correctly. If the offset is out of bounds or there are not
261317027Sdim  ///     enough bytes to extract this value, the offset will be left
262317027Sdim  ///     unmodified.
263317027Sdim  ///
264317027Sdim  /// @return
265317027Sdim  ///     A pointer to the C string value in the data. If the offset
266317027Sdim  ///     pointed to by \a offset_ptr is out of bounds, or if the
267317027Sdim  ///     offset plus the length of the C string is out of bounds,
268317027Sdim  ///     NULL will be returned.
269317027Sdim  //------------------------------------------------------------------
270317027Sdim  uint32_t PutCString(uint32_t offset_ptr, const char *cstr);
271317027Sdim
272317027Sdim  lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; }
273317027Sdim
274317027Sdim  //------------------------------------------------------------------
275317027Sdim  /// Set the address byte size.
276317027Sdim  ///
277341825Sdim  /// Set the size in bytes that will be used when extracting any address and
278341825Sdim  /// pointer values from data contained in this object.
279317027Sdim  ///
280317027Sdim  /// @param[in] addr_size
281317027Sdim  ///     The size in bytes to use when extracting addresses.
282317027Sdim  //------------------------------------------------------------------
283317027Sdim  void SetAddressByteSize(uint8_t addr_size) { m_addr_size = addr_size; }
284317027Sdim
285317027Sdim  //------------------------------------------------------------------
286317027Sdim  /// Set data with a buffer that is caller owned.
287317027Sdim  ///
288341825Sdim  /// Use data that is owned by the caller when extracting values. The data
289341825Sdim  /// must stay around as long as this object, or any object that copies a
290341825Sdim  /// subset of this object's data, is valid. If \a bytes is NULL, or \a
291341825Sdim  /// length is zero, this object will contain no data.
292317027Sdim  ///
293317027Sdim  /// @param[in] bytes
294317027Sdim  ///     A pointer to caller owned data.
295317027Sdim  ///
296317027Sdim  /// @param[in] length
297317027Sdim  ///     The length in bytes of \a bytes.
298317027Sdim  ///
299317027Sdim  /// @param[in] byte_order
300317027Sdim  ///     A byte order of the data that we are extracting from.
301317027Sdim  ///
302317027Sdim  /// @return
303317027Sdim  ///     The number of bytes that this object now contains.
304317027Sdim  //------------------------------------------------------------------
305317027Sdim  uint32_t SetData(void *bytes, uint32_t length, lldb::ByteOrder byte_order);
306317027Sdim
307317027Sdim  //------------------------------------------------------------------
308317027Sdim  /// Adopt a subset of shared data in \a data_sp.
309317027Sdim  ///
310341825Sdim  /// Copies the data shared pointer which adds a reference to the contained
311341825Sdim  /// in \a data_sp. The shared data reference is reference counted to ensure
312341825Sdim  /// the data lives as long as anyone still has a valid shared pointer to the
313341825Sdim  /// data in \a data_sp. The byte order and address byte size settings remain
314341825Sdim  /// the same. If \a offset is not a valid offset in \a data_sp, then no
315341825Sdim  /// reference to the shared data will be added. If there are not \a length
316341825Sdim  /// bytes available in \a data starting at \a offset, the length will be
317341825Sdim  /// truncated to contains as many bytes as possible.
318317027Sdim  ///
319317027Sdim  /// @param[in] data_sp
320317027Sdim  ///     A shared pointer to data.
321317027Sdim  ///
322317027Sdim  /// @param[in] offset
323317027Sdim  ///     The offset into \a data_sp at which the subset starts.
324317027Sdim  ///
325317027Sdim  /// @param[in] length
326317027Sdim  ///     The length in bytes of the subset of \a data_sp.
327317027Sdim  ///
328317027Sdim  /// @return
329317027Sdim  ///     The number of bytes that this object now contains.
330317027Sdim  //------------------------------------------------------------------
331317027Sdim  uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0,
332317027Sdim                   uint32_t length = UINT32_MAX);
333317027Sdim
334317027Sdim  //------------------------------------------------------------------
335317027Sdim  /// Set the byte_order value.
336317027Sdim  ///
337341825Sdim  /// Sets the byte order of the data to extract. Extracted values will be
338341825Sdim  /// swapped if necessary when decoding.
339317027Sdim  ///
340317027Sdim  /// @param[in] byte_order
341317027Sdim  ///     The byte order value to use when extracting data.
342317027Sdim  //------------------------------------------------------------------
343317027Sdim  void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; }
344317027Sdim
345317027Sdim  //------------------------------------------------------------------
346317027Sdim  /// Test the validity of \a offset.
347317027Sdim  ///
348317027Sdim  /// @return
349317027Sdim  ///     \b true if \a offset is a valid offset into the data in this
350317027Sdim  ///     object, \b false otherwise.
351317027Sdim  //------------------------------------------------------------------
352317027Sdim  bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
353317027Sdim
354317027Sdim  //------------------------------------------------------------------
355317027Sdim  /// Test the availability of \a length bytes of data from \a offset.
356317027Sdim  ///
357317027Sdim  /// @return
358317027Sdim  ///     \b true if \a offset is a valid offset and there are \a
359317027Sdim  ///     length bytes available at that offset, \b false otherwise.
360317027Sdim  //------------------------------------------------------------------
361317027Sdim  bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
362317027Sdim    return length <= BytesLeft(offset);
363317027Sdim  }
364317027Sdim
365317027Sdim  uint32_t BytesLeft(uint32_t offset) const {
366317027Sdim    const uint32_t size = GetByteSize();
367317027Sdim    if (size > offset)
368317027Sdim      return size - offset;
369317027Sdim    return 0;
370317027Sdim  }
371317027Sdim
372317027Sdimprotected:
373317027Sdim  //------------------------------------------------------------------
374317027Sdim  // Member variables
375317027Sdim  //------------------------------------------------------------------
376317027Sdim  uint8_t *m_start; ///< A pointer to the first byte of data.
377317027Sdim  uint8_t *m_end;   ///< A pointer to the byte that is past the end of the data.
378317027Sdim  lldb::ByteOrder
379317027Sdim      m_byte_order;    ///< The byte order of the data we are extracting from.
380317027Sdim  uint8_t m_addr_size; ///< The address size to use when extracting pointers or
381317027Sdim                       /// addresses
382317027Sdim  mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can
383317027Sdim                                        /// be shared among multiple instances
384317027Sdim
385317027Sdimprivate:
386317027Sdim  DISALLOW_COPY_AND_ASSIGN(DataEncoder);
387317027Sdim};
388317027Sdim
389317027Sdim} // namespace lldb_private
390317027Sdim
391317027Sdim#endif // #if defined (__cplusplus)
392317027Sdim#endif // #ifndef liblldb_DataEncoder_h_
393