File: MemoryStream.h

package info (click to toggle)
jazz2-native 3.5.0-3
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 16,912 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (107 lines) | stat: -rw-r--r-- 3,777 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#pragma once

#include "Stream.h"
#include "../Containers/Array.h"

namespace Death { namespace IO {
//###==##====#=====--==~--~=~- --- -- -  -  -   -

	/**
		@brief Provides stream interface for a region of memory
	*/ 
	class MemoryStream : public Stream
	{
	public:
		/** @brief Default constructor */
		MemoryStream();
		/** @brief Construct a growable stream with the specified initial capacity */
		explicit MemoryStream(std::int64_t initialCapacity);

		/** @brief Construct a writable stream that references the specified region of memory */
		MemoryStream(void* bufferPtr, std::int64_t bufferSize);
		/** @brief Construct a read-only stream that references the specified region of memory */
		MemoryStream(const void* bufferPtr, std::int64_t bufferSize);
		/** @overload */
		MemoryStream(Containers::ArrayView<const char> buffer);
		/** @overload */
		MemoryStream(Containers::ArrayView<const std::uint8_t> buffer);

		/** @brief Construct a growable stream with a copy of the specified region of memory */
		explicit MemoryStream(Containers::InPlaceInitT, Containers::ArrayView<const char> buffer);
		/** @overload */
		explicit MemoryStream(Containers::InPlaceInitT, Containers::ArrayView<const std::uint8_t> buffer);

		MemoryStream(const MemoryStream&) = delete;
		MemoryStream& operator=(const MemoryStream&) = delete;

		void Dispose() override;
		std::int64_t Seek(std::int64_t offset, SeekOrigin origin) override;
		std::int64_t GetPosition() const override;
		std::int64_t Read(void* destination, std::int64_t bytesToRead) override;
		std::int64_t Write(const void* source, std::int64_t bytesToWrite) override;
		bool Flush() override;
		bool IsValid() override;
		std::int64_t GetSize() const override;
		std::int64_t SetSize(std::int64_t size) override;

		/** @brief Reserves a capacity in growable memory stream */
		void ReserveCapacity(std::int64_t bytes);
		/** @brief Copies a specified number of bytes from a source stream to the current position */
		std::int64_t FetchFromStream(Stream& source, std::int64_t bytesToRead);

		/** @brief Returns a pointer to underlying buffer */
		DEATH_ALWAYS_INLINE std::uint8_t* GetBuffer() {
			return _data.data();
		}

		/** @overload */
		DEATH_ALWAYS_INLINE const std::uint8_t* GetBuffer() const {
			return _data.data();
		}

		/** @brief Returns a pointer to the current position, which is then incremented by a given number of bytes */
		DEATH_ALWAYS_INLINE const std::uint8_t* GetCurrentPointer(std::int64_t bytes) {
			if (_pos + bytes > _size) {
				return nullptr;
			}
			const std::uint8_t* ptr = _data.data() + _pos;
			_pos += bytes;
			return ptr;
		}

	private:
		enum class AccessMode {
			None,
			ReadOnly,
			Writable,
			Growable
		};

		Containers::Array<std::uint8_t> _data;
		std::int64_t _size;
		std::int64_t _pos;
		AccessMode _mode;
	};

}}

namespace Death { namespace Containers { namespace Implementation {
//###==##====#=====--==~--~=~- --- -- -  -  -   -

	template<> struct ArrayViewConverter<std::uint8_t, IO::MemoryStream> {
		static ArrayView<std::uint8_t> from(IO::MemoryStream& other) {
			return { other.GetBuffer(), std::size_t(other.GetSize()) };
		}
		static ArrayView<std::uint8_t> from(IO::MemoryStream&& other) {
			return { other.GetBuffer(), std::size_t(other.GetSize()) };
		}
	};
	template<> struct ArrayViewConverter<const std::uint8_t, IO::MemoryStream> {
		static ArrayView<const std::uint8_t> from(const IO::MemoryStream& other) {
			return { other.GetBuffer(), std::size_t(other.GetSize()) };
		}
	};
	template<> struct ErasedArrayViewConverter<IO::MemoryStream> : ArrayViewConverter<std::uint8_t, IO::MemoryStream> {};
	template<> struct ErasedArrayViewConverter<const IO::MemoryStream> : ArrayViewConverter<const std::uint8_t, IO::MemoryStream> {};

}}}