Plasma Engine  2.0
Loading...
Searching...
No Matches
MemoryStream.h
1#pragma once
2
3#include <Foundation/Basics.h>
4#include <Foundation/Containers/HybridArray.h>
5#include <Foundation/IO/Stream.h>
6#include <Foundation/Strings/String.h>
7#include <Foundation/Types/RefCounted.h>
8
11
15
17class PL_FOUNDATION_DLL plMemoryStreamStorageInterface
18{
19public:
22
24 plUInt32 GetStorageSize32() const
25 {
26 PL_ASSERT_ALWAYS(GetStorageSize64() <= plMath::MaxValue<plUInt32>(), "The memory stream storage object has grown beyond 4GB. The code using it has to be adapted to support this.");
27 return (plUInt32)GetStorageSize64();
28 }
29
31 virtual plUInt64 GetStorageSize64() const = 0; // [tested]
32
34 virtual void Clear() = 0;
35
37 virtual void Compact() = 0;
38
40 virtual plUInt64 GetHeapMemoryUsage() const = 0;
41
43 void ReadAll(plStreamReader& inout_stream, plUInt64 uiMaxBytes = plMath::MaxValue<plUInt64>());
44
46 virtual void Reserve(plUInt64 uiBytes) = 0;
47
49 virtual plResult CopyToStream(plStreamWriter& inout_stream) const = 0;
50
58 virtual plArrayPtr<const plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) const = 0;
59
61 virtual plArrayPtr<plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) = 0;
62
63private:
64 virtual void SetInternalSize(plUInt64 uiSize) = 0;
65
66 friend class plMemoryStreamReader;
67 friend class plMemoryStreamWriter;
68};
69
70
74
78template <typename CONTAINER>
80{
81public:
83 plMemoryStreamContainerStorage(plUInt32 uiInitialCapacity = 0, plAllocator* pAllocator = plFoundation::GetDefaultAllocator())
84 : m_Storage(pAllocator)
85 {
86 m_Storage.Reserve(uiInitialCapacity);
87 }
88
89 virtual plUInt64 GetStorageSize64() const override { return m_Storage.GetCount(); }
90 virtual void Clear() override { m_Storage.Clear(); }
91 virtual void Compact() override { m_Storage.Compact(); }
92 virtual plUInt64 GetHeapMemoryUsage() const override { return m_Storage.GetHeapMemoryUsage(); }
93
94 virtual void Reserve(plUInt64 uiBytes) override
95 {
96 PL_ASSERT_DEV(uiBytes <= plMath::MaxValue<plUInt32>(), "plMemoryStreamContainerStorage only supports 32 bit addressable sizes.");
97 m_Storage.Reserve(static_cast<plUInt32>(uiBytes));
98 }
99
100 virtual plResult CopyToStream(plStreamWriter& inout_stream) const override
101 {
102 return inout_stream.WriteBytes(m_Storage.GetData(), m_Storage.GetCount());
103 }
104
105 virtual plArrayPtr<const plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) const override
106 {
107 if (uiStartByte >= m_Storage.GetCount())
108 return {};
109
110 return plArrayPtr<const plUInt8>(m_Storage.GetData() + uiStartByte, m_Storage.GetCount() - static_cast<plUInt32>(uiStartByte));
111 }
112
113 virtual plArrayPtr<plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) override
114 {
115 if (uiStartByte >= m_Storage.GetCount())
116 return {};
117
118 return plArrayPtr<plUInt8>(m_Storage.GetData() + uiStartByte, m_Storage.GetCount() - static_cast<plUInt32>(uiStartByte));
119 }
120
122 const plUInt8* GetData() const { return m_Storage.GetData(); }
123
124private:
125 virtual void SetInternalSize(plUInt64 uiSize) override
126 {
127 PL_ASSERT_DEV(uiSize <= plMath::MaxValue<plUInt32>(), "Storage that large is not supported.");
128 m_Storage.SetCountUninitialized(static_cast<plUInt32>(uiSize));
129 }
130
131 CONTAINER m_Storage;
132};
133
134
138
139
144class PL_FOUNDATION_DLL plContiguousMemoryStreamStorage : public plMemoryStreamContainerStorage<plHybridArray<plUInt8, 256>>
145{
146public:
147 plContiguousMemoryStreamStorage(plUInt32 uiInitialCapacity = 0, plAllocator* pAllocator = plFoundation::GetDefaultAllocator())
148 : plMemoryStreamContainerStorage<plHybridArray<plUInt8, 256>>(uiInitialCapacity, pAllocator)
149 {
150 }
151};
152
161{
162public:
163 plDefaultMemoryStreamStorage(plUInt32 uiInitialCapacity = 0, plAllocator* pAllocator = plFoundation::GetDefaultAllocator());
165
166 virtual void Reserve(plUInt64 uiBytes) override; // [tested]
167
168 virtual plUInt64 GetStorageSize64() const override; // [tested]
169 virtual void Clear() override;
170 virtual void Compact() override;
171 virtual plUInt64 GetHeapMemoryUsage() const override;
172 virtual plResult CopyToStream(plStreamWriter& inout_stream) const override;
173 virtual plArrayPtr<const plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) const override; // [tested]
174 virtual plArrayPtr<plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) override; // [tested]
175
176private:
177 virtual void SetInternalSize(plUInt64 uiSize) override;
178
179 void AddChunk(plUInt32 uiMinimumSize);
180
181 struct Chunk
182 {
183 plUInt64 m_uiStartOffset = 0;
184 plArrayPtr<plUInt8> m_Bytes;
185 };
186
188
189 plUInt64 m_uiCapacity = 0;
190 plUInt64 m_uiInternalSize = 0;
191 plUInt8 m_InplaceMemory[512]; // used for the very first bytes, might cover small memory streams without an allocation
192 mutable plUInt32 m_uiLastChunkAccessed = 0;
193 mutable plUInt64 m_uiLastByteAccessed = 0;
194};
195
199
201template <typename CONTAINER>
203{
204public:
205 plMemoryStreamContainerWrapperStorage(CONTAINER* pContainer) { m_pStorage = pContainer; }
206
207 virtual plUInt64 GetStorageSize64() const override { return m_pStorage->GetCount(); }
208 virtual void Clear() override { m_pStorage->Clear(); }
209 virtual void Compact() override { m_pStorage->Compact(); }
210 virtual plUInt64 GetHeapMemoryUsage() const override { return m_pStorage->GetHeapMemoryUsage(); }
211
212 virtual void Reserve(plUInt64 uiBytes) override
213 {
214 PL_ASSERT_DEV(uiBytes <= plMath::MaxValue<plUInt32>(), "plMemoryStreamContainerWrapperStorage only supports 32 bit addressable sizes.");
215 m_pStorage->Reserve(static_cast<plUInt32>(uiBytes));
216 }
217
218 virtual plResult CopyToStream(plStreamWriter& inout_stream) const override
219 {
220 return inout_stream.WriteBytes(m_pStorage->GetData(), m_pStorage->GetCount());
221 }
222
223 virtual plArrayPtr<const plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) const override
224 {
225 if (uiStartByte >= m_pStorage->GetCount())
226 return {};
227
228 return plArrayPtr<const plUInt8>(m_pStorage->GetData() + uiStartByte, m_pStorage->GetCount() - static_cast<plUInt32>(uiStartByte));
229 }
230
231 virtual plArrayPtr<plUInt8> GetContiguousMemoryRange(plUInt64 uiStartByte) override
232 {
233 if (uiStartByte >= m_pStorage->GetCount())
234 return {};
235
236 return plArrayPtr<plUInt8>(m_pStorage->GetData() + uiStartByte, m_pStorage->GetCount() - static_cast<plUInt32>(uiStartByte));
237 }
238
239private:
240 virtual void SetInternalSize(plUInt64 uiSize) override
241 {
242 PL_ASSERT_DEV(uiSize <= plMath::MaxValue<plUInt32>(), "plMemoryStreamContainerWrapperStorage only supports up to 4GB sizes.");
243 m_pStorage->SetCountUninitialized(static_cast<plUInt32>(uiSize));
244 }
245
246 CONTAINER* m_pStorage;
247};
248
249
253
258class PL_FOUNDATION_DLL plMemoryStreamReader : public plStreamReader
259{
260public:
263 plMemoryStreamReader(const plMemoryStreamStorageInterface* pStreamStorage = nullptr);
264
266
269 void SetStorage(const plMemoryStreamStorageInterface* pStreamStorage)
270 {
271 m_pStreamStorage = pStreamStorage;
272 m_uiReadPosition = 0;
273 }
274
278 virtual plUInt64 ReadBytes(void* pReadBuffer, plUInt64 uiBytesToRead) override; // [tested]
279
281 virtual plUInt64 SkipBytes(plUInt64 uiBytesToSkip) override; // [tested]
282
284 void SetReadPosition(plUInt64 uiReadPosition); // [tested]
285
287 plUInt64 GetReadPosition() const { return m_uiReadPosition; }
288
290 plUInt32 GetByteCount32() const; // [tested]
291 plUInt64 GetByteCount64() const; // [tested]
292
294 void SetDebugSourceInformation(plStringView sDebugSourceInformation);
295
296private:
297 const plMemoryStreamStorageInterface* m_pStreamStorage = nullptr;
298
299 plString m_sDebugSourceInformation;
300
301 plUInt64 m_uiReadPosition = 0;
302};
303
304
308
312class PL_FOUNDATION_DLL plMemoryStreamWriter : public plStreamWriter
313{
314public:
316 plMemoryStreamWriter(plMemoryStreamStorageInterface* pStreamStorage = nullptr);
317
319
323 {
324 m_pStreamStorage = pStreamStorage;
325 m_uiWritePosition = 0;
326 if (m_pStreamStorage)
327 m_uiWritePosition = m_pStreamStorage->GetStorageSize64();
328 }
329
333 virtual plResult WriteBytes(const void* pWriteBuffer, plUInt64 uiBytesToWrite) override; // [tested]
334
336 void SetWritePosition(plUInt64 uiWritePosition); // [tested]
337
339 plUInt64 GetWritePosition() const { return m_uiWritePosition; }
340
342 plUInt32 GetByteCount32() const; // [tested]
343 plUInt64 GetByteCount64() const; // [tested]
344
345private:
346 plMemoryStreamStorageInterface* m_pStreamStorage = nullptr;
347
348 plUInt64 m_uiWritePosition = 0;
349};
350
351
355
357class PL_FOUNDATION_DLL plRawMemoryStreamReader : public plStreamReader
358{
359public:
361
363 plRawMemoryStreamReader(const void* pData, plUInt64 uiDataSize); // [tested]
364
367 template <typename CONTAINER>
368 plRawMemoryStreamReader(const CONTAINER& container) // [tested]
369 {
370 Reset(container);
371 }
372
374
375 void Reset(const void* pData, plUInt64 uiDataSize); // [tested]
376
377 template <typename CONTAINER>
378 void Reset(const CONTAINER& container) // [tested]
379 {
380 Reset(static_cast<const plUInt8*>(container.GetData()), container.GetCount());
381 }
382
386 virtual plUInt64 ReadBytes(void* pReadBuffer, plUInt64 uiBytesToRead) override; // [tested]
387
389 virtual plUInt64 SkipBytes(plUInt64 uiBytesToSkip) override; // [tested]
390
392 void SetReadPosition(plUInt64 uiReadPosition); // [tested]
393
395 plUInt64 GetReadPosition() const { return m_uiReadPosition; }
396
398 plUInt64 GetByteCount() const; // [tested]
399
401 void SetDebugSourceInformation(plStringView sDebugSourceInformation);
402
403private:
404 const plUInt8* m_pRawMemory = nullptr;
405
406 plUInt64 m_uiChunkSize = 0;
407 plUInt64 m_uiReadPosition = 0;
408
409 plString m_sDebugSourceInformation;
410};
411
415
416
418class PL_FOUNDATION_DLL plRawMemoryStreamWriter : public plStreamWriter
419{
420public:
421 plRawMemoryStreamWriter(); // [tested]
422
424 plRawMemoryStreamWriter(void* pData, plUInt64 uiDataSize); // [tested]
425
428 template <typename CONTAINER>
429 plRawMemoryStreamWriter(CONTAINER& ref_container) // [tested]
430 {
431 Reset(ref_container);
432 }
433
434 ~plRawMemoryStreamWriter(); // [tested]
435
436 void Reset(void* pData, plUInt64 uiDataSize); // [tested]
437
438 template <typename CONTAINER>
439 void Reset(CONTAINER& ref_container) // [tested]
440 {
441 Reset(static_cast<plUInt8*>(ref_container.GetData()), ref_container.GetCount());
442 }
443
445 plUInt64 GetStorageSize() const; // [tested]
446
448 plUInt64 GetNumWrittenBytes() const; // [tested]
449
451 void SetDebugSourceInformation(plStringView sDebugSourceInformation);
452
456 virtual plResult WriteBytes(const void* pWriteBuffer, plUInt64 uiBytesToWrite) override; // [tested]
457
458private:
459 plUInt8* m_pRawMemory = nullptr;
460
461 plUInt64 m_uiChunkSize = 0;
462 plUInt64 m_uiWritePosition = 0;
463
464 plString m_sDebugSourceInformation;
465};
Base class for all memory allocators.
Definition Allocator.h:23
This class encapsulates an array and it's size. It is recommended to use this class instead of plain ...
Definition ArrayPtr.h:37
Definition MemoryStream.h:145
The default implementation for memory stream storage.
Definition MemoryStream.h:161
static PL_ALWAYS_INLINE plAllocator * GetDefaultAllocator()
The default allocator can be used for any kind of allocation if no alignment is required.
Definition Basics.h:82
A hybrid array uses in-place storage to handle the first few elements without any allocation....
Definition HybridArray.h:12
Templated implementation of plMemoryStreamStorageInterface that adapts most standard pl containers to...
Definition MemoryStream.h:80
virtual void Reserve(plUInt64 uiBytes) override
Reserves N bytes of storage.
Definition MemoryStream.h:94
virtual plArrayPtr< const plUInt8 > GetContiguousMemoryRange(plUInt64 uiStartByte) const override
Returns a read-only plArrayPtr that represents a contiguous area in memory which starts at the given ...
Definition MemoryStream.h:105
virtual plArrayPtr< plUInt8 > GetContiguousMemoryRange(plUInt64 uiStartByte) override
Non-const overload of GetContiguousMemoryRange().
Definition MemoryStream.h:113
virtual void Clear() override
Clears the entire storage. All readers and writers must be reset to start from the beginning again.
Definition MemoryStream.h:90
virtual plUInt64 GetStorageSize64() const override
Returns the number of bytes that are currently stored.
Definition MemoryStream.h:89
const plUInt8 * GetData() const
The data is guaranteed to be contiguous.
Definition MemoryStream.h:122
virtual void Compact() override
Deallocates any allocated memory that's not needed to hold the currently stored data.
Definition MemoryStream.h:91
plMemoryStreamContainerStorage(plUInt32 uiInitialCapacity=0, plAllocator *pAllocator=plFoundation::GetDefaultAllocator())
Creates the storage object for a memory stream. Use uiInitialCapacity to reserve some memory up front...
Definition MemoryStream.h:83
virtual plUInt64 GetHeapMemoryUsage() const override
Returns the amount of bytes that are currently allocated on the heap.
Definition MemoryStream.h:92
virtual plResult CopyToStream(plStreamWriter &inout_stream) const override
Writes the entire content of the storage to the provided stream.
Definition MemoryStream.h:100
Wrapper around an existing container to implement plMemoryStreamStorageInterface.
Definition MemoryStream.h:203
virtual void Compact() override
Deallocates any allocated memory that's not needed to hold the currently stored data.
Definition MemoryStream.h:209
virtual plResult CopyToStream(plStreamWriter &inout_stream) const override
Writes the entire content of the storage to the provided stream.
Definition MemoryStream.h:218
virtual plArrayPtr< plUInt8 > GetContiguousMemoryRange(plUInt64 uiStartByte) override
Non-const overload of GetContiguousMemoryRange().
Definition MemoryStream.h:231
virtual plUInt64 GetHeapMemoryUsage() const override
Returns the amount of bytes that are currently allocated on the heap.
Definition MemoryStream.h:210
virtual plArrayPtr< const plUInt8 > GetContiguousMemoryRange(plUInt64 uiStartByte) const override
Returns a read-only plArrayPtr that represents a contiguous area in memory which starts at the given ...
Definition MemoryStream.h:223
virtual void Reserve(plUInt64 uiBytes) override
Reserves N bytes of storage.
Definition MemoryStream.h:212
virtual void Clear() override
Clears the entire storage. All readers and writers must be reset to start from the beginning again.
Definition MemoryStream.h:208
virtual plUInt64 GetStorageSize64() const override
Returns the number of bytes that are currently stored.
Definition MemoryStream.h:207
A reader which can access a memory stream.
Definition MemoryStream.h:259
plUInt64 GetReadPosition() const
Returns the current read position.
Definition MemoryStream.h:287
void SetStorage(const plMemoryStreamStorageInterface *pStreamStorage)
Sets the storage object upon which to operate. Resets the read position to zero. Pass nullptr if you ...
Definition MemoryStream.h:269
Instances of this class act as storage for memory streams.
Definition MemoryStream.h:18
virtual void Reserve(plUInt64 uiBytes)=0
Reserves N bytes of storage.
virtual plUInt64 GetHeapMemoryUsage() const =0
Returns the amount of bytes that are currently allocated on the heap.
virtual plResult CopyToStream(plStreamWriter &inout_stream) const =0
Writes the entire content of the storage to the provided stream.
virtual void Compact()=0
Deallocates any allocated memory that's not needed to hold the currently stored data.
virtual void Clear()=0
Clears the entire storage. All readers and writers must be reset to start from the beginning again.
plUInt32 GetStorageSize32() const
Returns the number of bytes that are currently stored. Asserts that the stored amount is less than 4G...
Definition MemoryStream.h:24
virtual plArrayPtr< const plUInt8 > GetContiguousMemoryRange(plUInt64 uiStartByte) const =0
Returns a read-only plArrayPtr that represents a contiguous area in memory which starts at the given ...
virtual plUInt64 GetStorageSize64() const =0
Returns the number of bytes that are currently stored.
virtual plArrayPtr< plUInt8 > GetContiguousMemoryRange(plUInt64 uiStartByte)=0
Non-const overload of GetContiguousMemoryRange().
A writer which can access a memory stream.
Definition MemoryStream.h:313
void SetStorage(plMemoryStreamStorageInterface *pStreamStorage)
Sets the storage object upon which to operate. Resets the write position to the end of the storage st...
Definition MemoryStream.h:322
plUInt64 GetWritePosition() const
Returns the current write position.
Definition MemoryStream.h:339
Maps a raw chunk of memory to the plStreamReader interface.
Definition MemoryStream.h:358
plUInt64 GetReadPosition() const
Returns the current read position in the raw memory block.
Definition MemoryStream.h:395
plRawMemoryStreamReader(const CONTAINER &container)
Initialize the raw memory reader with the chunk of memory from a standard pl container.
Definition MemoryStream.h:368
Maps a raw chunk of memory to the plStreamReader interface.
Definition MemoryStream.h:419
plRawMemoryStreamWriter(CONTAINER &ref_container)
Initialize the raw memory reader with the chunk of memory from a standard pl container.
Definition MemoryStream.h:429
Interface for binary in (read) streams.
Definition Stream.h:22
Interface for binary out (write) streams.
Definition Stream.h:107
virtual plResult WriteBytes(const void *pWriteBuffer, plUInt64 uiBytesToWrite)=0
Writes a raw number of bytes from the buffer, this is the only method which has to be implemented to ...
plStringView represent a read-only sub-string of a larger string, as it can store a dedicated string ...
Definition StringView.h:34
constexpr TYPE MaxValue()
Returns the largest possible positive value (that is not infinity).
Default enum for returning failure or success, instead of using a bool.
Definition Types.h:54