Devel Lib
WriteStream.h
1 #pragma once
2 
3 #include "Core/Exceptions.h"
4 #include "IO/Buffer/Buffer.h"
5 #include "Core/CharArray/CharArray.h"
6 
7 #include <type_traits>
8 #include <string>
9 
10 namespace Devel::IO {
42  class CWriteStream {
43  public:
44 
47  : m_pBuffer(nullptr), m_nSize(0), m_nAllocatedSize(0) {
48  }
49 
52  explicit CWriteStream(const size_t i_nSize)
53  : CWriteStream() {
54  this->reallocate(i_nSize);
55  }
56 
59  CWriteStream(const CWriteStream &i_oOther) : CWriteStream() { this->operator=(i_oOther); }
60 
63  CWriteStream(CWriteStream &&i_oWriteStream) noexcept {
64  this->operator=(std::move(i_oWriteStream));
65  }
66 
68  virtual ~CWriteStream() {
69  this->deleteBuffer();
70  }
71 
72  private:
76  void deleteBuffer();
77 
78  public:
80  void clear() {
81  this->m_nSize = 0;
82  }
83 
86  void reallocate(size_t i_nSize);
87 
88  public:
92  void push(const void *i_pBuffer, size_t i_nSize);
93 
96  void push(const CWriteStream &i_oStream) {
97  if (i_oStream.size() > 0) {
98  return this->push(i_oStream.buffer(), i_oStream.size());
99  }
100  }
101 
104  void push(const char *i_szString) {
105  return this->push(i_szString, strlen(i_szString));
106  }
107 
111  void push(const std::string &i_oString, const bool i_fZeroTerminated = true) {
112  if (!i_oString.empty()) {
113  return this->push(i_oString.c_str(), i_oString.size() + (i_fZeroTerminated));
114  }
115  }
116 
120  void push(const std::wstring &i_oString, const bool i_fZeroTerminated = true) {
121  if (!i_oString.empty()) {
122  return this->push(i_oString.c_str(), i_oString.size() * 2 + (i_fZeroTerminated * 2));
123  }
124  }
125 
129  template<typename T, typename std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
130  void push(const T &i_oValue) {
131  this->reallocate(this->m_nSize + sizeof(T));
132 
133  *reinterpret_cast<T *>((this->m_pBuffer + this->m_nSize)) = i_oValue;
134  this->m_nSize += sizeof(T);
135  }
136 
140  template<typename T, typename std::enable_if_t<std::is_enum_v<T>> * = nullptr>
141  void push(const T &i_oValue) {
142  this->reallocate(this->m_nSize + sizeof(T));
143 
144  *reinterpret_cast<T *>((this->m_pBuffer + this->m_nSize)) = i_oValue;
145  this->m_nSize += sizeof(T);
146  }
147 
152  template<size_t TSize>
153  void push(const CCharArray<TSize> &i_oValue, const bool i_bMaxLength = true) {
154  this->push(i_oValue.begin(), i_bMaxLength ? i_oValue.maxLength() : i_oValue.length());
155  }
156 
157  public:
162  void replace(const size_t i_nPosition, const void *i_pBuffer, const size_t i_nSize) const {
163  if (this->m_nSize >= i_nPosition + i_nSize) {
164  memcpy(this->m_pBuffer + i_nPosition, i_pBuffer, i_nSize);
165  } else {
166  throw IndexOutOfRangeException;
167  }
168  }
169 
173  void replace(const size_t i_nPosition, const CWriteStream &i_oStream) const {
174  if (i_oStream.size() > 0) {
175  this->replace(i_nPosition, i_oStream.buffer(), i_oStream.size());
176  }
177  }
178 
182  void replace(const size_t i_nPosition, const char *i_szString) const {
183  return this->replace(i_nPosition, i_szString, strlen(i_szString));
184  }
185 
189  void replace(const size_t i_nPosition, const std::string &i_oString) const {
190  return this->replace(i_nPosition, i_oString.c_str(), i_oString.size());
191  }
192 
197  template<typename T, typename std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
198  void replace(const size_t i_nPosition, const T &i_oValue) {
199  if (this->m_nSize >= i_nPosition + sizeof(T)) {
200  *reinterpret_cast<T *>((this->m_pBuffer + i_nPosition)) = i_oValue;
201  } else {
202  throw IndexOutOfRangeException;
203  }
204  }
205 
210  template<typename T, typename std::enable_if_t<std::is_enum_v<T>> * = nullptr>
211  void replace(const size_t i_nPosition, const T &i_oValue) {
212  if (this->m_nSize >= i_nPosition + sizeof(T)) {
213  *reinterpret_cast<T *>((this->m_pBuffer + i_nPosition)) = i_oValue;
214  } else {
215  throw IndexOutOfRangeException;
216  }
217  }
218 
219  public:
222  [[nodiscard]] size_t allocatedSize() const {
223  return this->m_nAllocatedSize;
224  }
225 
228  [[nodiscard]] size_t size() const {
229  return this->m_nSize;
230  }
231 
234  [[nodiscard]] const char *buffer() const {
235  return this->m_pBuffer;
236  }
237 
238  public:
242  CWriteStream &operator=(const CWriteStream &i_oOther) {
243  this->clear();
244  this->push(i_oOther.m_pBuffer, i_oOther.m_nSize);
245  return *this;
246  }
247 
251  CWriteStream &operator=(CWriteStream &&i_oOther) noexcept {
252  this->deleteBuffer();
253 
254  this->m_pBuffer = i_oOther.m_pBuffer;
255  this->m_nAllocatedSize = i_oOther.m_nAllocatedSize;
256  this->m_nSize = i_oOther.m_nSize;
257 
258  i_oOther.m_pBuffer = nullptr;
259  i_oOther.m_nAllocatedSize = 0;
260  i_oOther.m_nSize = 0;
261 
262  return *this;
263  }
264 
265  private:
268  char *m_pBuffer{};
271  size_t m_nSize{};
274  size_t m_nAllocatedSize{};
275  };
276 }
A class for representing and manipulating a character array.
Definition: CharArray.h:41
char * begin()
Definition: CharArray.h:122
static constexpr size_t maxLength()
Definition: CharArray.h:153
size_t length() const
Definition: CharArray.h:148
A class for writing data to a buffer. This class provides functionality to write data to a buffer....
Definition: WriteStream.h:42
CWriteStream(const CWriteStream &i_oOther)
Copy constructor.
Definition: WriteStream.h:59
CWriteStream & operator=(CWriteStream &&i_oOther) noexcept
Move assignment operator.
Definition: WriteStream.h:251
void push(const void *i_pBuffer, size_t i_nSize)
Pushes the specified data to the buffer.
Definition: WriteStream.cpp:30
const char * buffer() const
Gets a const pointer to the buffer.
Definition: WriteStream.h:234
size_t allocatedSize() const
Gets the allocated size of the buffer.
Definition: WriteStream.h:222
void clear()
Clears the stream by setting the size to 0.
Definition: WriteStream.h:80
void replace(const size_t i_nPosition, const char *i_szString) const
Replaces a portion of the buffer with a null-terminated string.
Definition: WriteStream.h:182
void replace(const size_t i_nPosition, const void *i_pBuffer, const size_t i_nSize) const
Replaces a portion of the buffer with the specified data.
Definition: WriteStream.h:162
void replace(const size_t i_nPosition, const std::string &i_oString) const
Replaces a portion of the buffer with a std::string.
Definition: WriteStream.h:189
void push(const CWriteStream &i_oStream)
Pushes the data from another CWriteStream to the buffer.
Definition: WriteStream.h:96
CWriteStream(const size_t i_nSize)
Constructor with initial size.
Definition: WriteStream.h:52
size_t size() const
Gets the current size of the buffer.
Definition: WriteStream.h:228
void push(const char *i_szString)
Pushes a null-terminated string to the buffer.
Definition: WriteStream.h:104
void replace(const size_t i_nPosition, const T &i_oValue)
Replaces a portion of the buffer with a numeric value.
Definition: WriteStream.h:198
void replace(const size_t i_nPosition, const CWriteStream &i_oStream) const
Replaces a portion of the buffer with the data from another CWriteStream.
Definition: WriteStream.h:173
void push(const std::wstring &i_oString, const bool i_fZeroTerminated=true)
Pushes a std::wstring to the buffer.
Definition: WriteStream.h:120
void reallocate(size_t i_nSize)
Reallocates the buffer to the given size.
Definition: WriteStream.cpp:12
CWriteStream(CWriteStream &&i_oWriteStream) noexcept
Move constructor.
Definition: WriteStream.h:63
CWriteStream()
Default constructor.
Definition: WriteStream.h:46
virtual ~CWriteStream()
Destructor.
Definition: WriteStream.h:68
void push(const T &i_oValue)
Pushes a numeric value to the buffer.
Definition: WriteStream.h:130
void push(const std::string &i_oString, const bool i_fZeroTerminated=true)
Pushes a std::string to the buffer.
Definition: WriteStream.h:111
CWriteStream & operator=(const CWriteStream &i_oOther)
Copy assignment operator.
Definition: WriteStream.h:242
void push(const CCharArray< TSize > &i_oValue, const bool i_bMaxLength=true)
Pushes a CCharArray to the buffer.
Definition: WriteStream.h:153
The namespace encapsulating I/O related classes and functions in the Devel framework.