1 //===-- DataBuffer.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 LLDB_UTILITY_DATABUFFER_H 10 #define LLDB_UTILITY_DATABUFFER_H 11 12 #include <cstdint> 13 #include <cstring> 14 15 #include "lldb/lldb-types.h" 16 17 #include "llvm/ADT/ArrayRef.h" 18 19 namespace lldb_private { 20 21 /// \class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h" 22 /// A pure virtual protocol class for abstracted read only data buffers. 23 /// 24 /// DataBuffer is an abstract class that gets packaged into a shared 25 /// pointer that can use to implement various ways to store data (on the heap, 26 /// memory mapped, cached inferior memory). It gets used by DataExtractor so 27 /// many DataExtractor objects can share the same data and sub-ranges of that 28 /// shared data, and the last object that contains a reference to the shared 29 /// data will free it. 30 /// 31 /// Subclasses can implement as many different constructors or member 32 /// functions that allow data to be stored in the object's buffer prior to 33 /// handing the shared data to clients that use these buffers. 34 /// 35 /// All subclasses must override all of the pure virtual functions as they are 36 /// used by clients to access the data. Having a common interface allows 37 /// different ways of storing data, yet using it in one common way. 38 /// 39 /// This class currently expects all data to be available without any extra 40 /// calls being made, but we can modify it to optionally get data on demand 41 /// with some extra function calls to load the data before it gets accessed. 42 class DataBuffer { 43 public: 44 virtual ~DataBuffer() = default; 45 46 /// Get the number of bytes in the data buffer. 47 /// 48 /// \return 49 /// The number of bytes this object currently contains. 50 virtual lldb::offset_t GetByteSize() const = 0; 51 52 /// Get a const pointer to the data. 53 /// 54 /// \return 55 /// A const pointer to the bytes owned by this object, or NULL 56 /// if the object contains no bytes. GetBytes()57 const uint8_t *GetBytes() const { return GetBytesImpl(); } 58 GetData()59 llvm::ArrayRef<uint8_t> GetData() const { 60 return llvm::ArrayRef<uint8_t>(GetBytes(), GetByteSize()); 61 } 62 63 /// LLVM RTTI support. 64 /// { 65 static char ID; isA(const void * ClassID)66 virtual bool isA(const void *ClassID) const { return ClassID == &ID; } classof(const DataBuffer * data_buffer)67 static bool classof(const DataBuffer *data_buffer) { 68 return data_buffer->isA(&ID); 69 } 70 /// } 71 72 protected: 73 /// Get a const pointer to the data. 74 /// 75 /// \return 76 /// A const pointer to the bytes owned by this object, or NULL 77 /// if the object contains no bytes. 78 virtual const uint8_t *GetBytesImpl() const = 0; 79 }; 80 81 /// \class DataBuffer DataBuffer.h "lldb/Core/DataBuffer.h" 82 /// A pure virtual protocol class for abstracted writable data buffers. 83 /// 84 /// DataBuffer is an abstract class that gets packaged into a shared pointer 85 /// that can use to implement various ways to store data (on the heap, memory 86 /// mapped, cached inferior memory). It gets used by DataExtractor so many 87 /// DataExtractor objects can share the same data and sub-ranges of that 88 /// shared data, and the last object that contains a reference to the shared 89 /// data will free it. 90 class WritableDataBuffer : public DataBuffer { 91 public: 92 /// Destructor 93 /// 94 /// The destructor is virtual as other classes will inherit from this class 95 /// and be downcast to the DataBuffer pure virtual interface. The virtual 96 /// destructor ensures that destructing the base class will destruct the 97 /// class that inherited from it correctly. 98 ~WritableDataBuffer() override = default; 99 100 using DataBuffer::GetBytes; 101 using DataBuffer::GetData; 102 103 /// Get a pointer to the data. 104 /// 105 /// \return 106 /// A pointer to the bytes owned by this object, or NULL if the 107 /// object contains no bytes. GetBytes()108 uint8_t *GetBytes() { return const_cast<uint8_t *>(GetBytesImpl()); } 109 GetData()110 llvm::MutableArrayRef<uint8_t> GetData() { 111 return llvm::MutableArrayRef<uint8_t>(GetBytes(), GetByteSize()); 112 } 113 114 /// LLVM RTTI support. 115 /// { 116 static char ID; isA(const void * ClassID)117 bool isA(const void *ClassID) const override { 118 return ClassID == &ID || DataBuffer::isA(ClassID); 119 } classof(const DataBuffer * data_buffer)120 static bool classof(const DataBuffer *data_buffer) { 121 return data_buffer->isA(&ID); 122 } 123 /// } 124 }; 125 126 class DataBufferUnowned : public WritableDataBuffer { 127 public: DataBufferUnowned(uint8_t * bytes,lldb::offset_t size)128 DataBufferUnowned(uint8_t *bytes, lldb::offset_t size) 129 : m_bytes(bytes), m_size(size) {} 130 GetBytesImpl()131 const uint8_t *GetBytesImpl() const override { return m_bytes; } GetByteSize()132 lldb::offset_t GetByteSize() const override { return m_size; } 133 134 /// LLVM RTTI support. 135 /// { 136 static char ID; isA(const void * ClassID)137 bool isA(const void *ClassID) const override { 138 return ClassID == &ID || WritableDataBuffer::isA(ClassID); 139 } classof(const DataBuffer * data_buffer)140 static bool classof(const DataBuffer *data_buffer) { 141 return data_buffer->isA(&ID); 142 } 143 /// } 144 private: 145 uint8_t *m_bytes; 146 lldb::offset_t m_size; 147 }; 148 149 } // namespace lldb_private 150 151 #endif // LLDB_UTILITY_DATABUFFER_H 152