DataEncoder.h 8.5 KB

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