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