1 //===-- DataEncoder.h -------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef liblldb_DataEncoder_h_ 10 #define liblldb_DataEncoder_h_ 11 12 #if defined(__cplusplus) 13 14 #include "lldb/lldb-defines.h" 15 #include "lldb/lldb-enumerations.h" 16 #include "lldb/lldb-forward.h" 17 #include "lldb/lldb-types.h" 18 19 #include <stddef.h> 20 #include <stdint.h> 21 22 namespace lldb_private { 23 24 /// \class DataEncoder 25 /// 26 /// An binary data encoding class. 27 /// 28 /// DataEncoder is a class that can encode binary data (swapping if needed) to 29 /// a data buffer. The data buffer can be caller owned, or can be shared data 30 /// that can be shared between multiple DataEncoder or DataEncoder instances. 31 /// 32 /// \see DataBuffer 33 class DataEncoder { 34 public: 35 /// Default constructor. 36 /// 37 /// Initialize all members to a default empty state. 38 DataEncoder(); 39 40 /// Construct with a buffer that is owned by the caller. 41 /// 42 /// This constructor allows us to use data that is owned by the caller. The 43 /// data must stay around as long as this object is valid. 44 /// 45 /// \param[in] data 46 /// A pointer to caller owned data. 47 /// 48 /// \param[in] data_length 49 /// The length in bytes of \a data. 50 /// 51 /// \param[in] byte_order 52 /// A byte order of the data that we are extracting from. 53 /// 54 /// \param[in] addr_size 55 /// A new address byte size value. 56 DataEncoder(void *data, uint32_t data_length, lldb::ByteOrder byte_order, 57 uint8_t addr_size); 58 59 /// Construct with shared data. 60 /// 61 /// Copies the data shared pointer which adds a reference to the contained 62 /// in \a data_sp. The shared data reference is reference counted to ensure 63 /// the data lives as long as anyone still has a valid shared pointer to the 64 /// data in \a data_sp. 65 /// 66 /// \param[in] data_sp 67 /// A shared pointer to data. 68 /// 69 /// \param[in] byte_order 70 /// A byte order of the data that we are extracting from. 71 /// 72 /// \param[in] addr_size 73 /// A new address byte size value. 74 DataEncoder(const lldb::DataBufferSP &data_sp, lldb::ByteOrder byte_order, 75 uint8_t addr_size); 76 77 /// Destructor 78 /// 79 /// If this object contains a valid shared data reference, the reference 80 /// count on the data will be decremented, and if zero, the data will be 81 /// freed. 82 ~DataEncoder(); 83 84 /// Clears the object state. 85 /// 86 /// Clears the object contents back to a default invalid state, and release 87 /// any references to shared data that this object may contain. 88 void Clear(); 89 90 /// Encode an unsigned integer of size \a byte_size to \a offset. 91 /// 92 /// Encode a single integer value at \a offset and return the offset that 93 /// follows the newly encoded integer when the data is successfully encoded 94 /// into the existing data. There must be enough room in the data, else 95 /// UINT32_MAX will be returned to indicate that encoding failed. 96 /// 97 /// \param[in] offset 98 /// The offset within the contained data at which to put the 99 /// encoded integer. 100 /// 101 /// \param[in] byte_size 102 /// The size in byte of the integer to encode. 103 /// 104 /// \param[in] value 105 /// The integer value to write. The least significant bytes of 106 /// the integer value will be written if the size is less than 107 /// 8 bytes. 108 /// 109 /// \return 110 /// The next offset in the bytes of this data if the integer 111 /// was successfully encoded, UINT32_MAX if the encoding failed. 112 uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value); 113 114 /// Encode an arbitrary number of bytes. 115 /// 116 /// \param[in] offset 117 /// The offset in bytes into the contained data at which to 118 /// start encoding. 119 /// 120 /// \param[in] src 121 /// The buffer that contains the bytes to encode. 122 /// 123 /// \param[in] src_len 124 /// The number of bytes to encode. 125 /// 126 /// \return 127 /// The next valid offset within data if the put operation 128 /// was successful, else UINT32_MAX to indicate the put failed. 129 uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len); 130 131 /// Encode an address in the existing buffer at \a offset bytes into the 132 /// buffer. 133 /// 134 /// Encode a single address (honoring the m_addr_size member) to the data 135 /// and return the next offset where subsequent data would go. pointed to by 136 /// \a offset_ptr. The size of the extracted address comes from the \a 137 /// m_addr_size member variable and should be set correctly prior to 138 /// extracting any address values. 139 /// 140 /// \param[in] offset 141 /// The offset where to encode the address. 142 /// 143 /// \param[in] addr 144 /// The address to encode. 145 /// 146 /// \return 147 /// The next valid offset within data if the put operation 148 /// was successful, else UINT32_MAX to indicate the put failed. 149 uint32_t PutAddress(uint32_t offset, lldb::addr_t addr); 150 151 /// Put a C string to \a offset. 152 /// 153 /// Encodes a C string into the existing data including the terminating 154 /// 155 /// \param[in] offset 156 /// The offset where to encode the string. 157 /// 158 /// \param[in] cstr 159 /// The string to encode. 160 /// 161 /// \return 162 /// A pointer to the C string value in the data. If the offset 163 /// pointed to by \a offset_ptr is out of bounds, or if the 164 /// offset plus the length of the C string is out of bounds, 165 /// NULL will be returned. 166 uint32_t PutCString(uint32_t offset, const char *cstr); 167 168 private: 169 uint32_t PutU8(uint32_t offset, uint8_t value); 170 uint32_t PutU16(uint32_t offset, uint16_t value); 171 uint32_t PutU32(uint32_t offset, uint32_t value); 172 uint32_t PutU64(uint32_t offset, uint64_t value); 173 174 uint32_t BytesLeft(uint32_t offset) const { 175 const uint32_t size = GetByteSize(); 176 if (size > offset) 177 return size - offset; 178 return 0; 179 } 180 181 /// Test the availability of \a length bytes of data from \a offset. 182 /// 183 /// \return 184 /// \b true if \a offset is a valid offset and there are \a 185 /// length bytes available at that offset, \b false otherwise. 186 bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const { 187 return length <= BytesLeft(offset); 188 } 189 190 /// Adopt a subset of shared data in \a data_sp. 191 /// 192 /// Copies the data shared pointer which adds a reference to the contained 193 /// in \a data_sp. The shared data reference is reference counted to ensure 194 /// the data lives as long as anyone still has a valid shared pointer to the 195 /// data in \a data_sp. The byte order and address byte size settings remain 196 /// the same. If \a offset is not a valid offset in \a data_sp, then no 197 /// reference to the shared data will be added. If there are not \a length 198 /// bytes available in \a data starting at \a offset, the length will be 199 /// truncated to contains as many bytes as possible. 200 /// 201 /// \param[in] data_sp 202 /// A shared pointer to data. 203 /// 204 /// \param[in] offset 205 /// The offset into \a data_sp at which the subset starts. 206 /// 207 /// \param[in] length 208 /// The length in bytes of the subset of \a data_sp. 209 /// 210 /// \return 211 /// The number of bytes that this object now contains. 212 uint32_t SetData(const lldb::DataBufferSP &data_sp, uint32_t offset = 0, 213 uint32_t length = UINT32_MAX); 214 215 /// Test the validity of \a offset. 216 /// 217 /// \return 218 /// \b true if \a offset is a valid offset into the data in this 219 /// object, \b false otherwise. 220 bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); } 221 222 /// Get the number of bytes contained in this object. 223 /// 224 /// \return 225 /// The total number of bytes of data this object refers to. 226 size_t GetByteSize() const { return m_end - m_start; } 227 228 private: 229 /// A pointer to the first byte of data. 230 uint8_t *m_start; 231 232 /// A pointer to the byte that is past the end of the data. 233 uint8_t *m_end; 234 235 /// The byte order of the data we are extracting from. 236 lldb::ByteOrder m_byte_order; 237 238 /// The address size to use when extracting pointers or 239 /// addresses 240 uint8_t m_addr_size; 241 242 /// The shared pointer to data that can 243 /// be shared among multiple instances 244 mutable lldb::DataBufferSP m_data_sp; 245 246 DISALLOW_COPY_AND_ASSIGN(DataEncoder); 247 }; 248 249 } // namespace lldb_private 250 251 #endif // #if defined (__cplusplus) 252 #endif // #ifndef liblldb_DataEncoder_h_ 253