DataEncoder.h revision 317032
174465Srwatson//===-- DataEncoder.h -------------------------------------------*- C++ -*-===//
290127Sjedgar//
374465Srwatson//                     The LLVM Compiler Infrastructure
474465Srwatson//
574465Srwatson// This file is distributed under the University of Illinois Open Source
674465Srwatson// License. See LICENSE.TXT for details.
774465Srwatson//
874465Srwatson//===----------------------------------------------------------------------===//
974465Srwatson
1074465Srwatson#ifndef liblldb_DataEncoder_h_
1174465Srwatson#define liblldb_DataEncoder_h_
1274465Srwatson
1374465Srwatson#if defined(__cplusplus)
1474465Srwatson
1574465Srwatson#include "lldb/lldb-defines.h"      // for DISALLOW_COPY_AND_ASSIGN
1674465Srwatson#include "lldb/lldb-enumerations.h" // for ByteOrder
1774465Srwatson#include "lldb/lldb-forward.h"      // for DataBufferSP
1874465Srwatson#include "lldb/lldb-types.h"        // for addr_t
1974465Srwatson
2074465Srwatson#include <stddef.h> // for size_t
2174465Srwatson#include <stdint.h>
2274465Srwatson
2374465Srwatsonnamespace lldb_private {
2474465Srwatson
2574465Srwatson//----------------------------------------------------------------------
2674465Srwatson/// @class DataEncoder DataEncoder.h "lldb/Core/DataEncoder.h"
2774465Srwatson/// @brief An binary data encoding class.
2874465Srwatson///
2974465Srwatson/// DataEncoder is a class that can encode binary data (swapping if needed)
3074465Srwatson/// to a data buffer. The data buffer can be caller owned, or can be
3174465Srwatson/// shared data that can be shared between multiple DataEncoder or
3274465Srwatson/// DataEncoder instances.
3374465Srwatson///
3474465Srwatson/// @see DataBuffer
3574465Srwatson//----------------------------------------------------------------------
3674465Srwatsonclass DataEncoder {
3774465Srwatsonpublic:
3874465Srwatson  //------------------------------------------------------------------
3974465Srwatson  /// Default constructor.
4074465Srwatson  ///
4174465Srwatson  /// Initialize all members to a default empty state.
4275928Sjedgar  //------------------------------------------------------------------
4374465Srwatson  DataEncoder();
4490127Sjedgar
4574465Srwatson  //------------------------------------------------------------------
4675928Sjedgar  /// Construct with a buffer that is owned by the caller.
4775928Sjedgar  ///
4874465Srwatson  /// This constructor allows us to use data that is owned by the
4975928Sjedgar  /// caller. The data must stay around as long as this object is
5075928Sjedgar  /// valid.
5174465Srwatson  ///
5274465Srwatson  /// @param[in] data
5374465Srwatson  ///     A pointer to caller owned data.
5474465Srwatson  ///
5574465Srwatson  /// @param[in] data_length
5674465Srwatson  ///     The length in bytes of \a data.
5787254Sjedgar  ///
5874465Srwatson  /// @param[in] byte_order
5975928Sjedgar  ///     A byte order of the data that we are extracting from.
6087254Sjedgar  ///
6187254Sjedgar  /// @param[in] addr_size
6274465Srwatson  ///     A new address byte size value.
6387254Sjedgar  //------------------------------------------------------------------
6474465Srwatson  DataEncoder(void *data, uint32_t data_length, lldb::ByteOrder byte_order,
6574465Srwatson              uint8_t addr_size);
6674465Srwatson
6774465Srwatson  //------------------------------------------------------------------
6874465Srwatson  /// Construct with shared data.
6974465Srwatson  ///
7074465Srwatson  /// Copies the data shared pointer which adds a reference to the
7174465Srwatson  /// contained in \a data_sp. The shared data reference is reference
7274465Srwatson  /// counted to ensure the data lives as long as anyone still has a
7374465Srwatson  /// valid shared pointer to the data in \a data_sp.
7487254Sjedgar  ///
7574465Srwatson  /// @param[in] data_sp
7674465Srwatson  ///     A shared pointer to data.
7774465Srwatson  ///
7874465Srwatson  /// @param[in] byte_order
7974465Srwatson  ///     A byte order of the data that we are extracting from.
8074465Srwatson  ///
8174465Srwatson  /// @param[in] addr_size
8275928Sjedgar  ///     A new address byte size value.
8375928Sjedgar  //------------------------------------------------------------------
8475928Sjedgar  DataEncoder(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order,
8575928Sjedgar              uint8_t addr_size);
8675928Sjedgar
8775928Sjedgar  //------------------------------------------------------------------
8875928Sjedgar  /// Destructor
8975928Sjedgar  ///
9075928Sjedgar  /// If this object contains a valid shared data reference, the
9174465Srwatson  /// reference count on the data will be decremented, and if zero,
9287254Sjedgar  /// the data will be freed.
9374465Srwatson  //------------------------------------------------------------------
9475928Sjedgar  ~DataEncoder();
9574465Srwatson
9674465Srwatson  //------------------------------------------------------------------
9774465Srwatson  /// Clears the object state.
9874465Srwatson  ///
9974465Srwatson  /// Clears the object contents back to a default invalid state, and
10074465Srwatson  /// release any references to shared data that this object may
10174465Srwatson  /// contain.
10274465Srwatson  //------------------------------------------------------------------
10374465Srwatson  void Clear();
10487254Sjedgar
10574465Srwatson  //------------------------------------------------------------------
10674465Srwatson  /// Get the current address size.
10790127Sjedgar  ///
10890127Sjedgar  /// Return the size in bytes of any address values this object will
10990127Sjedgar  /// extract.
11090127Sjedgar  ///
11190127Sjedgar  /// @return
11290127Sjedgar  ///     The size in bytes of address values that will be extracted.
11390127Sjedgar  //------------------------------------------------------------------
11490127Sjedgar  uint8_t GetAddressByteSize() const { return m_addr_size; }
11590127Sjedgar
11690127Sjedgar  //------------------------------------------------------------------
11790127Sjedgar  /// Get the number of bytes contained in this object.
11890127Sjedgar  ///
11990127Sjedgar  /// @return
12090127Sjedgar  ///     The total number of bytes of data this object refers to.
12174465Srwatson  //------------------------------------------------------------------
12274465Srwatson  size_t GetByteSize() const { return m_end - m_start; }
12387254Sjedgar
12474465Srwatson  //------------------------------------------------------------------
125  /// Get the data end pointer.
126  ///
127  /// @return
128  ///     Returns a pointer to the next byte contained in this
129  ///     object's data, or NULL of there is no data in this object.
130  //------------------------------------------------------------------
131  uint8_t *GetDataEnd() { return m_end; }
132
133  const uint8_t *GetDataEnd() const { return m_end; }
134
135  //------------------------------------------------------------------
136  /// Get the shared data offset.
137  ///
138  /// Get the offset of the first byte of data in the shared data (if
139  /// any).
140  ///
141  /// @return
142  ///     If this object contains shared data, this function returns
143  ///     the offset in bytes into that shared data, zero otherwise.
144  //------------------------------------------------------------------
145  size_t GetSharedDataOffset() const;
146
147  //------------------------------------------------------------------
148  /// Get the current byte order value.
149  ///
150  /// @return
151  ///     The current byte order value from this object's internal
152  ///     state.
153  //------------------------------------------------------------------
154  lldb::ByteOrder GetByteOrder() const { return m_byte_order; }
155
156  //------------------------------------------------------------------
157  /// Get the data start pointer.
158  ///
159  /// @return
160  ///     Returns a pointer to the first byte contained in this
161  ///     object's data, or NULL of there is no data in this object.
162  //------------------------------------------------------------------
163  uint8_t *GetDataStart() { return m_start; }
164
165  const uint8_t *GetDataStart() const { return m_start; }
166
167  //------------------------------------------------------------------
168  /// Encode unsigned integer values into the data at \a offset.
169  ///
170  /// @param[in] offset
171  ///     The offset within the contained data at which to put the
172  ///     data.
173  ///
174  /// @param[in] value
175  ///     The value to encode into the data.
176  ///
177  /// @return
178  ///     The next offset in the bytes of this data if the data
179  ///     was successfully encoded, UINT32_MAX if the encoding failed.
180  //------------------------------------------------------------------
181  uint32_t PutU8(uint32_t offset, uint8_t value);
182
183  uint32_t PutU16(uint32_t offset, uint16_t value);
184
185  uint32_t PutU32(uint32_t offset, uint32_t value);
186
187  uint32_t PutU64(uint32_t offset, uint64_t value);
188
189  //------------------------------------------------------------------
190  /// Encode an unsigned integer of size \a byte_size to \a offset.
191  ///
192  /// Encode a single integer value at \a offset and return the offset
193  /// that follows the newly encoded integer when the data is successfully
194  /// encoded into the existing data. There must be enough room in the
195  /// data, else UINT32_MAX will be returned to indicate that encoding
196  /// failed.
197  ///
198  /// @param[in] offset
199  ///     The offset within the contained data at which to put the
200  ///     encoded integer.
201  ///
202  /// @param[in] byte_size
203  ///     The size in byte of the integer to encode.
204  ///
205  /// @param[in] value
206  ///     The integer value to write. The least significant bytes of
207  ///     the integer value will be written if the size is less than
208  ///     8 bytes.
209  ///
210  /// @return
211  ///     The next offset in the bytes of this data if the integer
212  ///     was successfully encoded, UINT32_MAX if the encoding failed.
213  //------------------------------------------------------------------
214  uint32_t PutMaxU64(uint32_t offset, uint32_t byte_size, uint64_t value);
215
216  //------------------------------------------------------------------
217  /// Encode an arbitrary number of bytes.
218  ///
219  /// @param[in] offset
220  ///     The offset in bytes into the contained data at which to
221  ///     start encoding.
222  ///
223  /// @param[in] src
224  ///     The buffer that contains the bytes to encode.
225  ///
226  /// @param[in] src_len
227  ///     The number of bytes to encode.
228  ///
229  /// @return
230  ///     The next valid offset within data if the put operation
231  ///     was successful, else UINT32_MAX to indicate the put failed.
232  //------------------------------------------------------------------
233  uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len);
234
235  //------------------------------------------------------------------
236  /// Encode an address in the existing buffer at \a offset bytes into
237  /// the buffer.
238  ///
239  /// Encode a single address (honoring the m_addr_size member) to
240  /// the data and return the next offset where subsequent data would
241  /// go.
242  /// pointed to by \a offset_ptr. The size of the extracted address
243  /// comes from the \a m_addr_size member variable and should be
244  /// set correctly prior to extracting any address values.
245  ///
246  /// @param[in,out] offset_ptr
247  ///     A pointer to an offset within the data that will be advanced
248  ///     by the appropriate number of bytes if the value is extracted
249  ///     correctly. If the offset is out of bounds or there are not
250  ///     enough bytes to extract this value, the offset will be left
251  ///     unmodified.
252  ///
253  /// @return
254  ///     The next valid offset within data if the put operation
255  ///     was successful, else UINT32_MAX to indicate the put failed.
256  //------------------------------------------------------------------
257  uint32_t PutAddress(uint32_t offset, lldb::addr_t addr);
258
259  //------------------------------------------------------------------
260  /// Put a C string to \a offset.
261  ///
262  /// Encodes a C string into the existing data including the
263  /// terminating
264  ///
265  /// @param[in,out] offset_ptr
266  ///     A pointer to an offset within the data that will be advanced
267  ///     by the appropriate number of bytes if the value is extracted
268  ///     correctly. If the offset is out of bounds or there are not
269  ///     enough bytes to extract this value, the offset will be left
270  ///     unmodified.
271  ///
272  /// @return
273  ///     A pointer to the C string value in the data. If the offset
274  ///     pointed to by \a offset_ptr is out of bounds, or if the
275  ///     offset plus the length of the C string is out of bounds,
276  ///     NULL will be returned.
277  //------------------------------------------------------------------
278  uint32_t PutCString(uint32_t offset_ptr, const char *cstr);
279
280  lldb::DataBufferSP &GetSharedDataBuffer() { return m_data_sp; }
281
282  //------------------------------------------------------------------
283  /// Set the address byte size.
284  ///
285  /// Set the size in bytes that will be used when extracting any
286  /// address and pointer values from data contained in this object.
287  ///
288  /// @param[in] addr_size
289  ///     The size in bytes to use when extracting addresses.
290  //------------------------------------------------------------------
291  void SetAddressByteSize(uint8_t addr_size) { m_addr_size = addr_size; }
292
293  //------------------------------------------------------------------
294  /// Set data with a buffer that is caller owned.
295  ///
296  /// Use data that is owned by the caller when extracting values.
297  /// The data must stay around as long as this object, or any object
298  /// that copies a subset of this object's data, is valid. If \a
299  /// bytes is NULL, or \a length is zero, this object will contain
300  /// no data.
301  ///
302  /// @param[in] bytes
303  ///     A pointer to caller owned data.
304  ///
305  /// @param[in] length
306  ///     The length in bytes of \a bytes.
307  ///
308  /// @param[in] byte_order
309  ///     A byte order of the data that we are extracting from.
310  ///
311  /// @return
312  ///     The number of bytes that this object now contains.
313  //------------------------------------------------------------------
314  uint32_t SetData(void *bytes, uint32_t length, lldb::ByteOrder byte_order);
315
316  //------------------------------------------------------------------
317  /// Adopt a subset of shared data in \a data_sp.
318  ///
319  /// Copies the data shared pointer which adds a reference to the
320  /// contained in \a data_sp. The shared data reference is reference
321  /// counted to ensure the data lives as long as anyone still has a
322  /// valid shared pointer to the data in \a data_sp. The byte order
323  /// and address byte size settings remain the same. If
324  /// \a offset is not a valid offset in \a data_sp, then no reference
325  /// to the shared data will be added. If there are not \a length
326  /// bytes available in \a data starting at \a offset, the length
327  /// will be truncated to contains as many bytes as possible.
328  ///
329  /// @param[in] data_sp
330  ///     A shared pointer to data.
331  ///
332  /// @param[in] offset
333  ///     The offset into \a data_sp at which the subset starts.
334  ///
335  /// @param[in] length
336  ///     The length in bytes of the subset of \a data_sp.
337  ///
338  /// @return
339  ///     The number of bytes that this object now contains.
340  //------------------------------------------------------------------
341  uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0,
342                   uint32_t length = UINT32_MAX);
343
344  //------------------------------------------------------------------
345  /// Set the byte_order value.
346  ///
347  /// Sets the byte order of the data to extract. Extracted values
348  /// will be swapped if necessary when decoding.
349  ///
350  /// @param[in] byte_order
351  ///     The byte order value to use when extracting data.
352  //------------------------------------------------------------------
353  void SetByteOrder(lldb::ByteOrder byte_order) { m_byte_order = byte_order; }
354
355  //------------------------------------------------------------------
356  /// Test the validity of \a offset.
357  ///
358  /// @return
359  ///     \b true if \a offset is a valid offset into the data in this
360  ///     object, \b false otherwise.
361  //------------------------------------------------------------------
362  bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
363
364  //------------------------------------------------------------------
365  /// Test the availability of \a length bytes of data from \a offset.
366  ///
367  /// @return
368  ///     \b true if \a offset is a valid offset and there are \a
369  ///     length bytes available at that offset, \b false otherwise.
370  //------------------------------------------------------------------
371  bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
372    return length <= BytesLeft(offset);
373  }
374
375  uint32_t BytesLeft(uint32_t offset) const {
376    const uint32_t size = GetByteSize();
377    if (size > offset)
378      return size - offset;
379    return 0;
380  }
381
382protected:
383  //------------------------------------------------------------------
384  // Member variables
385  //------------------------------------------------------------------
386  uint8_t *m_start; ///< A pointer to the first byte of data.
387  uint8_t *m_end;   ///< A pointer to the byte that is past the end of the data.
388  lldb::ByteOrder
389      m_byte_order;    ///< The byte order of the data we are extracting from.
390  uint8_t m_addr_size; ///< The address size to use when extracting pointers or
391                       /// addresses
392  mutable lldb::DataBufferSP m_data_sp; ///< The shared pointer to data that can
393                                        /// be shared among multiple instances
394
395private:
396  DISALLOW_COPY_AND_ASSIGN(DataEncoder);
397};
398
399} // namespace lldb_private
400
401#endif // #if defined (__cplusplus)
402#endif // #ifndef liblldb_DataEncoder_h_
403