Spinning Topp Logo BlackTopp Studios
inc
memorystream.h
Go to the documentation of this file.
1 // © Copyright 2010 - 2016 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _resourcememorystream_h
41 #define _resourcememorystream_h
42 
43 #include "Resource/datastream.h"
44 
45 /// @file
46 /// @brief Declaration of MemoryStream
47 
48 namespace Mezzanine
49 {
50  namespace Resource
51  {
52  ///////////////////////////////////////////////////////////////////////////////
53  /// @brief A stream buffer object to a chunk of memory.
54  /// @details
55  ///////////////////////////////////////
56  class MEZZ_LIB MemoryStreamBuffer : public std::streambuf
57  {
58  protected:
59  /// @internal
60  /// @brief A pointer to the start of this memory buffer.
62  /*/// @internal
63  /// @brief The current position for read operations on this buffer.
64  Char8* BufferReadPos;
65  /// @internal
66  /// @brief The current position for write operations on this buffer.
67  Char8* BufferWritePos;// */
68  /// @internal
69  /// @brief A pointer to one passed the last element in the range of this buffer.
71  /// @internal
72  /// @brief A bitfield describing the settings this buffer was opened with.
74  /// @internal
75  /// @brief Stores whether or not the memory allocated will be free'd when this buffer is deleted.
77 
78  /// @brief Verifies a position in this stream is valid.
79  /// @param Position The position in this stream to check.
80  /// @return Returns an std::streampos containing the clamped position for this stream.
81  std::streampos CheckStreamPosition(const std::streampos Position);
82  /// @brief Verifies an offset in this stream is valid for a read or write cursor.
83  /// @param CursorOffset The current read/write position in this stream.
84  /// @param Adjust The amount of offset to be checked/applied to the provided read/write position.
85  /// @return Returns an std::streamoff containing the clamped offset for the given cursor in this stream.
86  std::streamoff CheckStreamOffset(const std::streamoff CursorOffset, const std::streamoff Adjust);
87  /// @brief Gets the current position of the read cursor.
88  /// @return Returns a std::streampos representing the offset of the read position from the start of the stream.
89  std::streampos GetReadPosition() const;
90  /// @brief Gets the current position of the write cursor.
91  /// @return Returns a std::streampos representing the offset of the write position from the start of the stream.
92  std::streampos GetWritePosition() const;
93 
94  ///////////////////////////////////////////////////////////////////////////////
95  // Locales
96 
97  /// @brief Notifies this class that a new locale is being imbued to this streambuf.
98  /// @remarks Does nothing, implemented for ease of future coding.
99  /// @param loc The new locale being imbued.
100  virtual void imbue(const std::locale& loc);
101 
102  ///////////////////////////////////////////////////////////////////////////////
103  // Buffer Management and Positioning
104 
105  /// @brief Sets the buffer to be streamed from.
106  /// @param s The buffer to be wrapped.
107  /// @param n The size of the buffer being wrapped.
108  /// @return Returns this on success, or NULL if there is a failure.
109  virtual std::streambuf* setbuf(char* s, std::streamsize n);
110  /// @brief Moves the read and/or write pointers in the stream.
111  /// @remarks Out of bounds positions will be clamped to the closest limit.
112  /// @param off The amount of advance the current position for the operation specified. Negative values will reverse the position.
113  /// @param way The base point in the stream to apply the offset to.
114  /// @param which Whether this should move the read pointer, write pointer, or both.
115  /// @return Returns the updated read or write position, based on which was provided. Returns the Read position if both were specified.
116  virtual std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out);
117  /// @brief Moves the read and/or write pointers to the specified position in the stream.
118  /// @remarks Out of bounds positions will be clamped to the closest limit.
119  /// @param sp The index the current position will be moved to.
120  /// @param which Whether this should move the read pointer, write pointer, or both.
121  /// @return Returns the updated read or write position, based on which was provided. Returns the Read position if both were specified.
122  virtual std::streampos seekpos(std::streampos sp, std::ios_base::openmode which = std::ios_base::in | std::ios_base::out);
123  /// @brief Syncs this stream buffer with it's source.
124  /// @remarks This buffer is the source for this type of stream, so syncing isn't required; making this an empty implementation.
125  virtual int sync();
126 
127  ///////////////////////////////////////////////////////////////////////////////
128  // Input Functions (get/read)
129 
130  /// @brief Gets the number of characters remaining that can be safely extracted from this buffer.
131  /// @return Returns either the number of characters between the current read position and the end of the buffer, or -1 if no buffer is allocated.
132  virtual std::streamsize showmanyc();
133  /// @brief Gets a number of characters starting at the read position and populates an array with them.
134  /// @param s A pointer to the array where the read characters will be placed.
135  /// @param n The number of characters to read.
136  /// @return This returns the amount of characters retrieved
137  virtual std::streamsize xsgetn(char* s, std::streamsize n);
138  /// @brief Gets the value at the current read position without incrementing the read position.
139  /// @remarks This method us used by the std::streambuf implementation for some limited amount of error checking for when the end of a stream is
140  /// reached and it may be possible to access more (such as streaming a file from disk). This functionality doesn't make sense for a buffer
141  /// located entirely in memory, so we must return the End-Of-File value each time we're at the end of the buffer.
142  /// @return Returns the current character at the read position or EOF.
143  virtual int underflow();
144  /// @brief Gets the value at the current read position and then increments the read position.
145  /// @remarks Under normal circumstances this method will be used along with underflow to get characters at the end of the sequence safely in the
146  /// event that more data needs to be buffered. However the spec requires it to always return EOF if underflow also returns EOF. So because
147  /// of how we have to implement underflow, this methods behavior is quite limited.
148  /// @return Returns EOF, always.
149  virtual int uflow();
150  /// @brief Reverse the last character extraction operation by decrementing the read position and placing the specified character in it's place.
151  /// @param c The character to place into the stream after decrementing the read position.
152  /// @return Returns the current character at the read position after the operation completes, or EOF in the event of a failure.
153  virtual int pbackfail(int c = traits_type::eof());
154 
155  ///////////////////////////////////////////////////////////////////////////////
156  // Output Functions (put/write)
157 
158  /// @brief Writes a number of characters from a provided buffer to the stream.
159  /// @param s The buffer of characters that will be written to the stream.
160  /// @param n The number of characters from the provided buffer that will be written to the stream.
161  /// @return Returns the number of characters successfully written.
162  virtual std::streamsize xsputn(const char* s, std::streamsize n);
163  /// @brief Writes a character at the current write position without advancing the write position.
164  /// @remarks Generally this method is called when the available writing positions in the stream have been depleted and additional writing spaces can
165  /// made. In our case, we can't buffer additional data so in the event the stream is expecting more, we should return the error result of EOF.
166  /// @param c The character to be written to the stream.
167  /// @return Returns the written character, or EOF if there was a failure.
168  virtual int overflow(int c = traits_type::eof());
169  public:
170  /// @brief Class constructor.
172  /// @brief Class destructor.
173  virtual ~MemoryStreamBuffer();
174 
175  ///////////////////////////////////////////////////////////////////////////////
176  // Utility
177 
178  /// @brief Convenience method for creating a new buffer to be used by this stream.
179  /// @remarks No changes will be made if the Size is set to 0 or less.
180  /// @param Size The size of the buffer to be allocated.
181  /// @param Mode An open mode describing if this buffer will be configured for reading, writing, or both.
182  void CreateBuffer(const Whole Size);
183  /// @brief Wraps an external buffer for streaming.
184  /// @param Buffer The buffer to be wrapped.
185  /// @param BufferSize The size of the buffer being wrapped.
186  /// @param FreeBuf Whether or not the buffer passed in should be deleted when this stream is destroyed.
187  void SetBuffer(char* Buffer, const Whole BufferSize, const Boole FreeBuf);
188  /// @brief Copies a pre-existing buffer to this buffer for streaming.
189  /// @param Buffer The buffer to be copied.
190  /// @param BufferSize The size of the buffer to be copied.
191  void CopyBuffer(const char* Buffer, const Whole BufferSize);
192 
193  /// @brief Gets the start of this buffer.
194  /// @return Returns a pointer to the first valid element in this buffer.
195  Char8* GetBufferStart() const;
196  /// @brief Gets the end of this buffer.
197  /// @return Returns a pointer to one passed the last valid element in this buffer.
198  Char8* GetBufferEnd() const;
199  /// @brief Gets the size of the current buffer being streamed to/from.
200  /// @return Returns a std::streamsize representing the size of the current buffer, or 0 if one hasn't been initialized.
201  std::streamsize GetBufferSize() const;
202 
203  /// @brief Sets the get and put pointers for the streambuffer and assigns the current position to the specified offset.
204  /// @param Pos The offset to set the current read/write position to.
205  /// @param Mode An open mode describing if this buffer will be configured for reading, writing, or both.
206  void ConfigureBuffer(const std::streampos Pos, std::ios_base::openmode Mode = std::ios_base::in | std::ios_base::out);
207  /// @brief Convenience method for deleting the existing buffer being streamed.
208  void DestroyBuffer();
209 
210  /// @brief Sets if this should delete it's internal buffer when it is destroyed.
211  /// @param FreeBuf Whether or not the buffer passed in should be deleted when this stream is destroyed.
212  void SetFreeBuffer(const Boole FreeBuf);
213  /// @brief Gets if this should delete it's internal buffer when it is destroyed.
214  /// @return Returns true if the internal buffer will be deleted when this is destroyed.
215  Boole GetFreeBuffer() const;
216  };//MemoryStreamBuffer
217 
218  ///////////////////////////////////////////////////////////////////////////////
219  /// @brief An I/O stream to a buffer of memory.
220  /// @details
221  ///////////////////////////////////////
223  {
224  protected:
225  /// @internal
226  /// @brief The buffer object being streamed to/from.
228  public:
229  /// @brief Blank constructor.
230  MemoryStream();
231  /// @brief Buffer initialization constructor.
232  /// @param BufferSize The size of the buffer being wrapped.
233  /// @param Mode The configuration to open the memory buffer with.
234  MemoryStream(const Whole BufferSize, const Whole Mode = Resource::SF_Read | Resource::SF_Write);
235  /// @brief Buffer copy constructor.
236  /// @param BufferSize The size of the buffer being wrapped.
237  /// @param Mode The configuration to open the memory buffer with.
238  MemoryStream(const void* Buffer, const Whole BufferSize, const Whole Mode = Resource::SF_Read | Resource::SF_Write);
239  /// @brief Buffer wrapper constructor.
240  /// @param Buffer The buffer to be wrapped.
241  /// @param BufferSize The size of the buffer being wrapped.
242  /// @param FreeAfter Whether or not the buffer passed in should be deleted when this stream is destroyed.
243  /// @param Mode The configuration to open the memory buffer with.
244  MemoryStream(void* Buffer, const Whole BufferSize, const Boole FreeAfter, const Whole Mode = Resource::SF_Read | Resource::SF_Write);
245  /// @brief Class destructor.
246  virtual ~MemoryStream();
247 
248  ///////////////////////////////////////////////////////////////////////////////
249  // Utility
250 
251  /// @brief Creates a new memory buffer to stream to/from.
252  /// @remarks No changes will be made if the Size is set to 0 or less.
253  /// @param Size The size of the buffer to be allocated.
254  /// @param Mode An open mode describing if this buffer will be configured for reading, writing, or both.
255  void CreateBuffer(const Whole Size, const Whole Mode = Resource::SF_Read | Resource::SF_Write);
256  /// @brief Wraps an external buffer for streaming.
257  /// @param Buffer The buffer to be wrapped.
258  /// @param BufferSize The size of the buffer being wrapped.
259  /// @param FreeBuf Whether or not the buffer passed in should be deleted when this stream is destroyed.
260  /// @param Mode An open mode describing if this buffer will be configured for reading, writing, or both.
261  void SetBuffer(void* Buffer, const Whole BufferSize, const Boole FreeBuf, const Whole Mode = Resource::SF_Read | Resource::SF_Write);
262  /// @brief Copies a pre-existing buffer to this buffer for streaming.
263  /// @param Buffer The buffer to be copied.
264  /// @param BufferSize The size of the buffer to be copied.
265  /// @param Mode An open mode describing if this buffer will be configured for reading, writing, or both.
266  void CopyBuffer(const void* Buffer, const Whole BufferSize, const Whole Mode = Resource::SF_Read | Resource::SF_Write);
267 
268  /// @brief Gets the start of this buffer.
269  /// @return Returns a pointer to the first valid element in this buffer.
270  Char8* GetBufferStart() const;
271  /// @brief Gets the end of this buffer.
272  /// @return Returns a pointer to one passed the last valid element in this buffer.
273  Char8* GetBufferEnd() const;
274 
275  /// @brief Sets if this should delete it's internal buffer when it is destroyed.
276  /// @param FreeBuf Whether or not the buffer passed in should be deleted when this stream is destroyed.
277  void SetFreeBuffer(const Boole FreeBuf);
278  /// @brief Gets if this should delete it's internal buffer when it is destroyed.
279  /// @return Returns true if the internal buffer will be deleted when this is destroyed.
280  Boole GetFreeBuffer() const;
281 
282  ///////////////////////////////////////////////////////////////////////////////
283  // Stream Base Operations
284 
285  /// @copydoc StreamBase::GetSize() const
286  virtual StreamSize GetSize() const;
287  };//MemoryStream
288  }//Resource
289 }//Mezzanine
290 
291 #endif
Char8 * BufferStart
A pointer to the start of this memory buffer.
Definition: memorystream.h:61
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
Whole OpenMode
A bitfield describing the settings this buffer was opened with.
Definition: memorystream.h:73
Base class for streams that support both read and write operations.
Definition: datastream.h:263
char Char8
A datatype to represent one character.
Definition: datatypes.h:169
An I/O stream to a buffer of memory.
Definition: memorystream.h:222
Permit write operations on the stream.
Definition: datastream.h:69
#define MEZZ_LIB
Some platforms require special decorations to denote what is exported/imported in a share library...
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
unsigned long Whole
Whole is an unsigned integer, it will be at least 32bits in size.
Definition: datatypes.h:151
std::streamsize StreamSize
Convenience define for the stream size datatype.
Definition: datastream.h:61
Char8 * BufferEnd
A pointer to one passed the last element in the range of this buffer.
Definition: memorystream.h:70
MemoryStreamBuffer Buffer
The buffer object being streamed to/from.
Definition: memorystream.h:227
A stream buffer object to a chunk of memory.
Definition: memorystream.h:56
Declaration of DataStream.
Boole FreeBuffer
Stores whether or not the memory allocated will be free'd when this buffer is deleted.
Definition: memorystream.h:76
Permit read operations on the stream.
Definition: datastream.h:68