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