LkEngine 0.1.2
 
Loading...
Searching...
No Matches
Buffer.h
1#pragma once
2
4
5
6namespace LkEngine {
7
8 struct FBuffer
9 {
10 explicit FBuffer(const void* InData, const uint64_t InSize)
11 : Data((void*)InData)
12 , Size(InSize)
13 {
14 }
15
16 FBuffer()
17 : Data(nullptr)
18 , Size(0)
19 {
20 }
21
22 ~FBuffer()
23 {
24 Release();
25 }
26
27 FBuffer(const FBuffer& Other)
28 : Data(nullptr)
29 , Size(Other.Size)
30 {
31 if (Other.Data && (Other.Size > 0))
32 {
33 /* Perform deep copy. */
34 Allocate(Other.Size);
35 if (Data)
36 {
37 memcpy(Data, Other.Data, Other.Size);
38 }
39 }
40 }
41
42 FBuffer(FBuffer&& Other) noexcept
43 : Data(Other.Data)
44 , Size(Other.Size)
45 {
46 /* Do NOT invoke Release here to prevent double call to 'free'. */
47 Other.Data = nullptr;
48 Other.Size = 0;
49 }
50
51 FBuffer& operator=(const FBuffer& Other) noexcept
52 {
53 if (this != &Other)
54 {
55 /* Release current buffer if it exists. */
56 Release();
57
58 if (Other.Data && Other.Size > 0)
59 {
60 /* Perform deep copy. */
61 Allocate(Other.Size);
62 memcpy(Data, Other.Data, Other.Size);
63 Size = Other.Size;
64 }
65 else
66 {
67 Data = nullptr;
68 Size = 0;
69 }
70 }
71
72 return *this;
73 }
74
75 FBuffer& operator=(FBuffer&& Other) noexcept
76 {
77 if (this != &Other)
78 {
79 delete[](byte*)Data;
80
81 /* Transfer ownership. */
82 Allocate(Other.Size);
83 memcpy(Data, Other.Data, Other.Size);
84
85 Size = Other.Size;
86
87 Other.Data = nullptr;
88 Other.Size = 0;
89 }
90
91 return *this;
92 }
93
94 FORCEINLINE static FBuffer Copy(const FBuffer& Other)
95 {
96 FBuffer Buffer;
97 Buffer.Allocate(Other.Size);
98 std::memcpy(Buffer.Data, Other.Data, Other.Size);
99
100 return Buffer;
101 }
102
103 FORCEINLINE static FBuffer Copy(const void* Data, const uint64_t Size)
104 {
105 FBuffer Buffer;
106 Buffer.Allocate(Size);
107 std::memcpy(Buffer.Data, Data, Size);
108
109 return Buffer;
110 }
111
112 FORCEINLINE void Allocate(const uint64_t InSize)
113 {
114 LK_CORE_ASSERT(InSize > 0, "Allocate failed, invalid size: {}", InSize);
115
116 delete[](byte*)Data;
117 Data = nullptr;
118
119 Data = new byte[InSize];
120 Size = InSize;
121 }
122
123 FORCEINLINE void Release()
124 {
125 if (Data)
126 {
127 delete[](byte*)Data;
128 Data = nullptr;
129 Size = 0;
130 }
131 }
132
133 FORCEINLINE void ZeroInitialize()
134 {
135 if (Size > 0)
136 {
137 std::memset(Data, 0, Size);
138 }
139 }
140
141 template<typename T>
142 FORCEINLINE T& Read(const uint64_t Offset = 0)
143 {
144 return *(T*)(static_cast<byte*>(Data) + Offset);
145 }
146
147 template<typename T>
148 FORCEINLINE const T& Read(uint64_t Offset = 0) const
149 {
150 return *(T*)(static_cast<byte*>(Data) + Offset);
151 }
152
153 FORCEINLINE byte* ReadBytes(const uint64_t ReadSize, const uint64_t Offset) const
154 {
155 LK_CORE_ASSERT(Offset + ReadSize <= ReadSize, "Buffer overflow");
156 byte* Buffer = new byte[ReadSize];
157 std::memcpy(Buffer, (byte*)Data + Offset, ReadSize);
158
159 return Buffer;
160 }
161
162 FORCEINLINE void Write(const void* InData, const uint64_t WriteSize, uint64_t Offset = 0)
163 {
164 LK_CORE_ASSERT(Offset + WriteSize <= Size, "FBuffer overflow");
165 std::memcpy((byte*)Data + Offset, InData, WriteSize);
166 }
167
168 operator bool() { return (Data && (Size > 0)); }
169 operator bool() const { return (Data && (Size > 0)); }
170
171 byte& operator[](int index)
172 {
173 return ((byte*)Data)[index];
174 }
175
176 byte operator[](int index) const
177 {
178 return ((byte*)Data)[index];
179 }
180
181 template<typename T>
182 T* As() const
183 {
184 return (T*)Data;
185 }
186
187 FORCEINLINE uint64_t GetSize() const { return Size; }
188
189 public:
190 void* Data = nullptr;
191 uint64_t Size = 0;
192 };
193
194 struct FBufferSafe : public FBuffer
195 {
197 {
198 Release();
199 }
200
201 static FBufferSafe Copy(const void* Data, const uint64_t Size)
202 {
203 FBufferSafe Buffer;
204 Buffer.Allocate(Size);
205 std::memcpy(Buffer.Data, Data, Size);
206
207 return Buffer;
208 }
209 };
210}
Core header.
Definition Asset.h:11
Definition Buffer.h:195
Definition Buffer.h:9