Spinning Topp Logo BlackTopp Studios
inc
datastream.cpp
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 _resourcedatastream_cpp
41 #define _resourcedatastream_cpp
42 
43 #include "Resource/datastream.h"
44 #include "stringtool.h"
45 #include "exception.h"
46 
47 #include <cstring>
48 #include <cstdio>
49 #include <algorithm>
50 
51 #define TEMP_STREAM_SIZE 128
52 
53 namespace Mezzanine
54 {
55  namespace Resource
56  {
57  ///////////////////////////////////////////////////////////////////////////////
58  // IStream Methods
59 
60  IStream::IStream(std::streambuf* Buf) :
61  std::istream(Buf)
62  { }
63 
65  { }
66 
67  ///////////////////////////////////////////////////////////////////////////////
68  // Stream Base Operations
69 
71  { return this->eof(); }
72 
74  { return this->bad(); }
75 
77  { return this->fail(); }
78 
80  { return this->good(); }
81 
83  { this->clear(); }
84 
85  ///////////////////////////////////////////////////////////////////////////////
86  // Input methods
87 
88  size_t IStream::Read(void* Buffer, StreamSize Size)
89  {
90  this->read(static_cast<char*>(Buffer),Size);
91  return this->gcount();
92  }
93 
95  { this->seekg(Position); }
96 
98  { this->seekg(Offset,static_cast<std::ios_base::seekdir>(Origin)); }
99 
101  { return this->tellg(); }
102 
103  ///////////////////////////////////////////////////////////////////////////////
104  // OStream Methods
105 
106  OStream::OStream(std::streambuf* Buf) :
107  std::ostream(Buf)
108  { }
109 
111  { }
112 
113  ///////////////////////////////////////////////////////////////////////////////
114  // Stream Base Operations
115 
117  { return this->eof(); }
118 
120  { return this->bad(); }
121 
123  { return this->fail(); }
124 
126  { return this->good(); }
127 
129  { this->clear(); }
130 
131  ///////////////////////////////////////////////////////////////////////////////
132  // Output methods
133 
134  size_t OStream::Write(const void* Buffer, StreamSize Size)
135  {
136  this->write(static_cast<const char*>(Buffer),Size);
137  return ( this->fail() ? 0 : Size );
138  }
139 
141  { this->seekp(Position); }
142 
144  { this->seekp(Offset,static_cast<std::ios_base::seekdir>(Origin)); }
145 
147  { return this->tellp(); }
148 
149  ///////////////////////////////////////////////////////////////////////////////
150  // IOStream Methods
151 
152  IOStream::IOStream(std::streambuf* Buf) :
153  std::iostream(Buf)
154  { }
155 
157  { }
158 
159  ///////////////////////////////////////////////////////////////////////////////
160  // Stream Base Operations
161 
163  { return this->eof(); }
164 
166  { return this->bad(); }
167 
169  { return this->fail(); }
170 
172  { return this->good(); }
173 
175  { this->clear(); }
176 
177  ///////////////////////////////////////////////////////////////////////////////
178  // Input methods
179 
180  size_t IOStream::Read(void* Buffer, StreamSize Size)
181  {
182  this->read(static_cast<char*>(Buffer),Size);
183  return this->gcount();
184  }
185 
187  { this->seekg(Position); }
188 
190  { this->seekg(Offset,static_cast<std::ios_base::seekdir>(Origin)); }
191 
193  { return this->tellg(); }
194 
195  ///////////////////////////////////////////////////////////////////////////////
196  // Output methods
197 
198  size_t IOStream::Write(const void* Buffer, StreamSize Size)
199  {
200  this->write(static_cast<const char*>(Buffer),Size);
201  return ( this->fail() ? 0 : Size );
202  }
203 
205  { this->seekp(Position); }
206 
208  { this->seekp(Offset,static_cast<std::ios_base::seekdir>(Origin)); }
209 
211  { return this->tellp(); }
212 
213  ///////////////////////////////////////////////////////////////////////////////
214  // Input/Output methods
215 
216  void IOStream::Advance(const StreamOff Count)
217  { this->SetStreamPosition(Count,SO_Current); }
218 
220  {
221  this->seekg(Position);
222  this->seekp(Position);
223  }
224 
226  {
227  this->seekg(Offset,static_cast<std::ios_base::seekdir>(Origin));
228  this->seekp(Offset,static_cast<std::ios_base::seekdir>(Origin));
229  }
230 
232  {
233  if(Read) return this->GetReadPosition();
234  else return this->GetWritePosition();
235  }
236 
237  ///////////////////////////////////////////////////////////////////////////////
238  // Formatting Methods
239 
241  {
242  size_t BufferSize = ( this->GetSize() > 0 ? this->GetSize() : 4096 );
243  char* Buffer = new char[BufferSize];
244 
245  this->SetStreamPosition(0);
246  String Ret;
247  while( !this->EoF() )
248  {
249  size_t BytesRead = Read(Buffer,BufferSize);
250  Ret.append(Buffer,BytesRead);
251  }
252  delete[] Buffer;
253  return Ret;
254  }
255 
256  size_t IOStream::ReadLine(Char8* Buffer, size_t MaxCount, const String& Delim)
257  {
258  Boole TrimCR = false;
259  if( Delim.find_first_of('\n') != String::npos ) {
260  TrimCR = true;
261  }
262 
263  char Temp[TEMP_STREAM_SIZE];
264  size_t ChunkSize = std::min(MaxCount,(size_t)TEMP_STREAM_SIZE - 1);
265  size_t TotalCount = 0;
266  size_t ReadCount = 0;
267 
268  while( ChunkSize && ( ReadCount = Read(Temp,ChunkSize) ) != 0 )
269  {
270  Temp[ReadCount] = '\0';
271  size_t Pos = std::strcspn(Temp,Delim.c_str());
272 
273  if( Pos < ReadCount ) {
274  this->Advance((long)(Pos + 1 - ReadCount));
275  }
276 
277  if( Buffer ) {
278  std::memcpy(Buffer + TotalCount,Temp,Pos);
279  }
280  TotalCount += Pos;
281 
282  if( Pos < ReadCount ) {
283  if( TrimCR && TotalCount && Buffer[TotalCount - 1] == '\r' ) {
284  --TotalCount;
285  }
286  break;
287  }
288 
289  ChunkSize = std::min(MaxCount - TotalCount,(size_t)TEMP_STREAM_SIZE - 1);
290  }
291  Buffer[TotalCount] = '\0';
292  return TotalCount;
293  }
294 
296  {
297  char Temp[TEMP_STREAM_SIZE];
298  String Ret;
299  size_t ReadCount;
300 
301  while( ( ReadCount = Read(Temp,TEMP_STREAM_SIZE - 1) ) != 0 )
302  {
303  Temp[ReadCount] = '\0';
304 
305  char* Pos = std::strchr(Temp,'\n');
306  if( Pos != 0 ) {
307  this->Advance( (long)(Pos + 1 - Temp - ReadCount) );
308  *Pos = '\0';
309  }
310 
311  Ret += Temp;
312 
313  if( Pos != 0 ) {
314  if( Ret.length() && Ret[Ret.length() - 1] == '\r' ) {
315  Ret.erase(Ret.length() - 1, 1);
316  }
317  break;
318  }
319  }
320 
321  if( Trim ) {
322  StringTools::Trim(Ret);
323  }
324 
325  return Ret;
326  }
327 
328  size_t IOStream::SkipLine(const String& Delim)
329  {
330  char Temp[TEMP_STREAM_SIZE];
331  size_t TotalBytes = 0;
332  size_t ReadCount = 0;
333 
334  while( ( ReadCount = Read(Temp,TEMP_STREAM_SIZE - 1) ) != 0 )
335  {
336  Temp[ReadCount] = '\0';
337  size_t Position = std::strcspn(Temp,Delim.c_str());
338 
339  if( Position < ReadCount ) {
340  this->Advance( (long)(Position + 1 - ReadCount) );
341  TotalBytes += Position + 1;
342  break;
343  }
344 
345  TotalBytes += ReadCount;
346  }
347 
348  return TotalBytes;
349  }
350  }//Resource
351 }//Mezzanine
352 
353 #endif
virtual size_t Read(void *Buffer, StreamSize Size)
Reads from the stream and copies that data to a buffer.
Definition: datastream.cpp:88
virtual StreamPos GetReadPosition()
Gets the current read position in this stream.
Definition: datastream.cpp:100
virtual Boole Fail() const
Gets whether or not an otherwise silent and recoverable error was detected in a previous operation in...
Definition: datastream.cpp:76
virtual size_t ReadLine(Char8 *Buffer, size_t MaxCount, const String &Delim="\n")
Reads a single line from a string.
Definition: datastream.cpp:256
OStream(std::streambuf *Buf)
Class constructor.
Definition: datastream.cpp:106
virtual Boole IsValid() const
Gets whether or not this stream is intact and ready for operations.
Definition: datastream.cpp:125
bool Boole
Generally acts a single bit, true or false.
Definition: datatypes.h:173
virtual String GetLine(Boole Trim=true)
Gets the contents of the current line in the stream.
Definition: datastream.cpp:295
virtual ~IOStream()
Class destructor.
Definition: datastream.cpp:156
virtual size_t Write(const void *Buffer, StreamSize Size)
Writes data to the stream.
Definition: datastream.cpp:198
virtual Boole Bad() const
Gets whether or not a critical error was detected in a previous operation in the stream.
Definition: datastream.cpp:73
virtual void SetReadPosition(StreamPos Position)
Sets the position of the read cursor explicitly.
Definition: datastream.cpp:94
virtual void SetWritePosition(StreamPos Position)
Sets the position of the write cursor explicitly.
Definition: datastream.cpp:204
STL namespace.
virtual void SetWritePosition(StreamPos Position)
Sets the position of the write cursor explicitly.
Definition: datastream.cpp:140
The current position for read/write operations in the stream.
Definition: datastream.h:80
virtual Boole Fail() const
Gets whether or not an otherwise silent and recoverable error was detected in a previous operation in...
Definition: datastream.cpp:168
virtual Boole EoF() const
Gets whether or not the current position is at the end of the stream.
Definition: datastream.cpp:162
void Trim(String &Source, Boole Left, Boole Right)
Trims all whitespaces and tabs from a one or both sides of a String.
Definition: stringtool.cpp:128
This implements the exception hiearchy for Mezzanine.
virtual StreamPos GetReadPosition()
Gets the current read position in this stream.
Definition: datastream.cpp:192
virtual StreamPos GetWritePosition()
Gets the current write position in this stream.
Definition: datastream.cpp:146
char Char8
A datatype to represent one character.
Definition: datatypes.h:169
virtual size_t Read(void *Buffer, StreamSize Size)
Reads from the stream and copies that data to a buffer.
Definition: datastream.cpp:180
virtual Boole Fail() const
Gets whether or not an otherwise silent and recoverable error was detected in a previous operation in...
Definition: datastream.cpp:122
virtual void ClearErrors()
Clears any stored error state on the stream.
Definition: datastream.cpp:128
virtual void SetReadPosition(StreamPos Position)
Sets the position of the read cursor explicitly.
Definition: datastream.cpp:186
virtual Boole Bad() const
Gets whether or not a critical error was detected in a previous operation in the stream.
Definition: datastream.cpp:119
virtual ~OStream()
Class destructor.
Definition: datastream.cpp:110
virtual Boole EoF() const
Gets whether or not the current position is at the end of the stream.
Definition: datastream.cpp:70
virtual size_t SkipLine(const String &Delim="\n")
Moves the current position to the start of the next line.
Definition: datastream.cpp:328
SeekOrigin
An enum describing which position should be considered the origin for changing the current position i...
Definition: datastream.h:77
IStream(std::streambuf *Buf)
Class constructor.
Definition: datastream.cpp:60
virtual void ClearErrors()
Clears any stored error state on the stream.
Definition: datastream.cpp:174
virtual StreamSize GetSize() const =0
Gets the size of the stream.
virtual void Advance(const StreamOff Count)
Advances the position in the stream.
Definition: datastream.cpp:216
virtual void ClearErrors()
Clears any stored error state on the stream.
Definition: datastream.cpp:82
virtual StreamPos GetWritePosition()
Gets the current write position in this stream.
Definition: datastream.cpp:210
virtual Boole EoF() const
Gets whether or not the current position is at the end of the stream.
Definition: datastream.cpp:116
virtual Boole Bad() const
Gets whether or not a critical error was detected in a previous operation in the stream.
Definition: datastream.cpp:165
The bulk of the engine components go in this namspace.
Definition: actor.cpp:56
IOStream(std::streambuf *Buf)
Class constructor.
Definition: datastream.cpp:152
virtual String GetAsString()
Gets the contents of the stream as a string.
Definition: datastream.cpp:240
std::streamsize StreamSize
Convenience define for the stream size datatype.
Definition: datastream.h:61
virtual Boole IsValid() const
Gets whether or not this stream is intact and ready for operations.
Definition: datastream.cpp:171
std::streampos StreamPos
Convenience define for the stream position datatype.
Definition: datastream.h:57
std::streamoff StreamOff
Convenience define for the stream offset datatype.
Definition: datastream.h:59
virtual size_t Write(const void *Buffer, StreamSize Size)
Writes data to the stream.
Definition: datastream.cpp:134
virtual ~IStream()
Class destructor.
Definition: datastream.cpp:64
virtual void SetStreamPosition(StreamPos Position)
Sets the position of the read and write cursors explicitly.
Definition: datastream.cpp:219
std::string String
A datatype used to a series of characters.
Definition: datatypes.h:159
virtual Boole IsValid() const
Gets whether or not this stream is intact and ready for operations.
Definition: datastream.cpp:79
virtual StreamPos GetStreamPosition(const Boole Read=true)
Gets the current position in this stream.
Definition: datastream.cpp:231
Declaration of DataStream.