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.
57   const uint8_t *GetBytes() const { return GetBytesImpl(); }
58 
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;
66   virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
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.
108   uint8_t *GetBytes() { return const_cast<uint8_t *>(GetBytesImpl()); }
109 
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;
117   bool isA(const void *ClassID) const override {
118     return ClassID == &ID || DataBuffer::isA(ClassID);
119   }
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:
128   DataBufferUnowned(uint8_t *bytes, lldb::offset_t size)
129       : m_bytes(bytes), m_size(size) {}
130 
131   const uint8_t *GetBytesImpl() const override { return m_bytes; }
132   lldb::offset_t GetByteSize() const override { return m_size; }
133 
134   /// LLVM RTTI support.
135   /// {
136   static char ID;
137   bool isA(const void *ClassID) const override {
138     return ClassID == &ID || WritableDataBuffer::isA(ClassID);
139   }
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