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