aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h')
-rw-r--r--contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h302
1 files changed, 302 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h b/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h
new file mode 100644
index 000000000000..0b78161d87ef
--- /dev/null
+++ b/contrib/llvm-project/lldb/include/lldb/Utility/DataEncoder.h
@@ -0,0 +1,302 @@
+//===-- DataEncoder.h -------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_UTILITY_DATAENCODER_H
+#define LLDB_UTILITY_DATAENCODER_H
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <cstddef>
+#include <cstdint>
+
+namespace lldb_private {
+
+/// \class DataEncoder
+///
+/// An binary data encoding class.
+///
+/// DataEncoder is a class that can encode binary data (swapping if needed) to
+/// a data buffer. The DataEncoder can be constructed with data that will be
+/// copied into the internally owned buffer. This allows data to be modified
+/// in the internal buffer. The DataEncoder object can also be constructed with
+/// just a byte order and address size and data can be appended to the
+/// internally owned buffer.
+///
+/// Clients can get a shared pointer to the data buffer when done modifying or
+/// creating the data to keep the data around after the lifetime of a
+/// DataEncoder object. \see GetDataBuffer
+///
+/// Client can get a reference to the object owned data as an array by calling
+/// the GetData method. \see GetData
+class DataEncoder {
+public:
+ /// Default constructor.
+ ///
+ /// Initialize all members to a default empty state and create a empty memory
+ /// buffer that can be appended to. The ByteOrder and address size will be set
+ /// to match the current host system.
+ DataEncoder();
+
+ /// Construct an encoder that copies the specified data into the object owned
+ /// data buffer.
+ ///
+ /// This constructor is designed to be used when you have a data buffer and
+ /// want to modify values within the buffer. A copy of the data will be made
+ /// in the internally owned buffer and that data can be fixed up and appended
+ /// to.
+ ///
+ /// \param[in] data
+ /// A pointer to caller owned data.
+ ///
+ /// \param[in] data_length
+ /// The length in bytes of \a data.
+ ///
+ /// \param[in] byte_order
+ /// A byte order for the data that will be encoded.
+ ///
+ /// \param[in] addr_size
+ /// A size of an address in bytes. \see PutAddress, AppendAddress
+ DataEncoder(const void *data, uint32_t data_length,
+ lldb::ByteOrder byte_order, uint8_t addr_size);
+
+ /// Construct an encoder that owns a heap based memory buffer.
+ ///
+ /// This allows clients to create binary data from scratch by appending values
+ /// with the methods that start with "Append".
+ ///
+ /// \param[in] byte_order
+ /// A byte order for the data that will be encoded.
+ ///
+ /// \param[in] addr_size
+ /// A size of an address in bytes. \see PutAddress, AppendAddress
+ DataEncoder(lldb::ByteOrder byte_order, uint8_t addr_size);
+
+ ~DataEncoder();
+
+ /// Encode an unsigned integer of size \a byte_size to \a offset.
+ ///
+ /// Encode a single integer value at \a offset and return the offset that
+ /// follows the newly encoded integer when the data is successfully encoded
+ /// into the existing data. There must be enough room in the existing data,
+ /// else UINT32_MAX will be returned to indicate that encoding failed.
+ ///
+ /// \param[in] offset
+ /// The offset within the contained data at which to put the encoded
+ /// integer.
+ ///
+ /// \param[in] byte_size
+ /// The size in byte of the integer to encode.
+ ///
+ /// \param[in] value
+ /// The integer value to write. The least significant bytes of
+ /// the integer value will be written if the size is less than
+ /// 8 bytes.
+ ///
+ /// \return
+ /// The next offset in the bytes of this data if the integer
+ /// was successfully encoded, UINT32_MAX if the encoding failed.
+ uint32_t PutUnsigned(uint32_t offset, uint32_t byte_size, uint64_t value);
+
+ /// Encode an unsigned integer at offset \a offset.
+ ///
+ /// Encode a single unsigned integer value at \a offset and return the offset
+ /// that follows the newly encoded integer when the data is successfully
+ /// encoded into the existing data. There must be enough room in the data,
+ /// else UINT32_MAX will be returned to indicate that encoding failed.
+ ///
+ /// \param[in] offset
+ /// The offset within the contained data at which to put the encoded
+ /// integer.
+ ///
+ /// \param[in] value
+ /// The integer value to write.
+ ///
+ /// \return
+ /// The next offset in the bytes of this data if the integer was
+ /// successfully encoded, UINT32_MAX if the encoding failed.
+ uint32_t PutU8(uint32_t offset, uint8_t value);
+ uint32_t PutU16(uint32_t offset, uint16_t value);
+ uint32_t PutU32(uint32_t offset, uint32_t value);
+ uint32_t PutU64(uint32_t offset, uint64_t value);
+
+ /// Append a unsigned integer to the end of the owned data.
+ ///
+ /// \param value
+ /// A unsigned integer value to append.
+ void AppendU8(uint8_t value);
+ void AppendU16(uint16_t value);
+ void AppendU32(uint32_t value);
+ void AppendU64(uint64_t value);
+
+ /// Append an address sized integer to the end of the owned data.
+ ///
+ /// \param addr
+ /// A unsigned integer address value to append. The size of the address
+ /// will be determined by the address size specified in the constructor.
+ void AppendAddress(lldb::addr_t addr);
+
+ /// Append a bytes to the end of the owned data.
+ ///
+ /// Append the bytes contained in the string reference. This function will
+ /// not append a NULL termination character for a C string. Use the
+ /// AppendCString function for this purpose.
+ ///
+ /// \param data
+ /// A string reference that contains bytes to append.
+ void AppendData(llvm::StringRef data);
+
+ /// Append a bytes to the end of the owned data.
+ ///
+ /// Append the bytes contained in the array reference.
+ ///
+ /// \param data
+ /// A array reference that contains bytes to append.
+ void AppendData(llvm::ArrayRef<uint8_t> data);
+
+ /// Append a C string to the end of the owned data.
+ ///
+ /// Append the bytes contained in the string reference along with an extra
+ /// NULL termination character if the StringRef bytes doesn't include one as
+ /// the last byte.
+ ///
+ /// \param data
+ /// A string reference that contains bytes to append.
+ void AppendCString(llvm::StringRef data);
+
+ /// Encode an arbitrary number of bytes.
+ ///
+ /// \param[in] offset
+ /// The offset in bytes into the contained data at which to
+ /// start encoding.
+ ///
+ /// \param[in] src
+ /// The buffer that contains the bytes to encode.
+ ///
+ /// \param[in] src_len
+ /// The number of bytes to encode.
+ ///
+ /// \return
+ /// The next valid offset within data if the put operation
+ /// was successful, else UINT32_MAX to indicate the put failed.
+ uint32_t PutData(uint32_t offset, const void *src, uint32_t src_len);
+
+ /// Encode an address in the existing buffer at \a offset bytes into the
+ /// buffer.
+ ///
+ /// Encode a single address to the data and return the next offset where
+ /// subsequent data would go. The size of the address comes from the \a
+ /// m_addr_size member variable and should be set correctly prior to encoding
+ /// any address values.
+ ///
+ /// \param[in] offset
+ /// The offset where to encode the address.
+ ///
+ /// \param[in] addr
+ /// The address to encode.
+ ///
+ /// \return
+ /// The next valid offset within data if the put operation
+ /// was successful, else UINT32_MAX to indicate the put failed.
+ uint32_t PutAddress(uint32_t offset, lldb::addr_t addr);
+
+ /// Put a C string to \a offset.
+ ///
+ /// Encodes a C string into the existing data including the terminating. If
+ /// there is not enough room in the buffer to fit the entire C string and the
+ /// NULL terminator in the existing buffer bounds, then this function will
+ /// fail.
+ ///
+ /// \param[in] offset
+ /// The offset where to encode the string.
+ ///
+ /// \param[in] cstr
+ /// The string to encode.
+ ///
+ /// \return
+ /// The next valid offset within data if the put operation was successful,
+ /// else UINT32_MAX to indicate the put failed.
+ uint32_t PutCString(uint32_t offset, const char *cstr);
+
+ /// Get a shared copy of the heap based memory buffer owned by this object.
+ ///
+ /// This allows a data encoder to be used to create a data buffer that can
+ /// be extracted and used elsewhere after this object is destroyed.
+ ///
+ /// \return
+ /// A shared pointer to the DataBufferHeap that contains the data that was
+ /// encoded into this object.
+ std::shared_ptr<lldb_private::DataBufferHeap> GetDataBuffer() {
+ return m_data_sp;
+ }
+
+ /// Get a access to the bytes that this references.
+ ///
+ /// This value will always return the data that this object references even if
+ /// the object was constructed with caller owned data.
+ ///
+ /// \return
+ /// A array reference to the data that this object references.
+ llvm::ArrayRef<uint8_t> GetData() const;
+
+ /// Get the number of bytes contained in this object.
+ ///
+ /// \return
+ /// The total number of bytes of data this object refers to.
+ size_t GetByteSize() const;
+
+ lldb::ByteOrder GetByteOrder() const { return m_byte_order; }
+
+ /// The address size to use when encoding pointers or addresses.
+ uint8_t GetAddressByteSize() const { return m_addr_size; }
+
+private:
+ uint32_t BytesLeft(uint32_t offset) const {
+ const uint32_t size = GetByteSize();
+ if (size > offset)
+ return size - offset;
+ return 0;
+ }
+
+ /// Test the availability of \a length bytes of data from \a offset.
+ ///
+ /// \return
+ /// \b true if \a offset is a valid offset and there are \a
+ /// length bytes available at that offset, \b false otherwise.
+ bool ValidOffsetForDataOfSize(uint32_t offset, uint32_t length) const {
+ return length <= BytesLeft(offset);
+ }
+
+ /// Test the validity of \a offset.
+ ///
+ /// \return
+ /// \b true if \a offset is a valid offset into the data in this
+ /// object, \b false otherwise.
+ bool ValidOffset(uint32_t offset) const { return offset < GetByteSize(); }
+
+ /// The shared pointer to data that can grow as data is added
+ std::shared_ptr<lldb_private::DataBufferHeap> m_data_sp;
+
+ /// The byte order of the data we are encoding to.
+ const lldb::ByteOrder m_byte_order;
+
+ /// The address size to use when encoding pointers or addresses.
+ const uint8_t m_addr_size;
+
+ DataEncoder(const DataEncoder &) = delete;
+ const DataEncoder &operator=(const DataEncoder &) = delete;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_DATAENCODER_H