MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
datastream.cpp
1 // © Copyright 2010 - 2014 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 #ifdef USENEWDATASTREAM
58  void IOStream::Advance(const StreamOff Count)
59  {
60  this->SetStreamPosition(Count,SO_Current);
61  }
62 
63  void IOStream::SetStreamPosition(StreamPos Position)
64  {
65  this->SetReadPosition(Position);
66  this->SetWritePosition(Position);
67  }
68 
69  void IOStream::SetStreamPosition(StreamOff Offset, SeekOrigin Origin)
70  {
71  this->SetReadPosition(Offset,Origin);
72  this->SetWritePosition(Offset,Origin);
73  }
74 
75  StreamPos IOStream::GetStreamPosition(bool Read = true)
76  {
77  if(Read) return this->GetReadPosition();
78  else return this->GetWritePosition();
79  }
80 #else //USENEWDATASTREAM
81  ///////////////////////////////////////////////////////////////////////////////
82  // DataStream Methods
83  ///////////////////////////////////////
85  : SFlags(Flags),
86  Size(0)
87  {
88  }
89 
91  {
92  }
93 
94  ///////////////////////////////////////////////////////////////////////////////
95  // Utility
96 
98  {
99  return Size;
100  }
101 
103  {
104  return (SFlags & DataStream::SF_Read);
105  }
106 
108  {
109  return (SFlags & DataStream::SF_Write);
110  }
111 
112  ///////////////////////////////////////////////////////////////////////////////
113  // Stream Access and Manipulation
114 
115  ///////////////////////////////////////////////////////////////////////////////
116  // Formatting Methods
117 
119  {
120  size_t BufferSize = (this->Size > 0 ? this->Size : 4096);
121  char* Buffer = new char[BufferSize];
122 
123  this->SetStreamPosition(0);
124  String Ret;
125  while (!EoF())
126  {
127  size_t BytesRead = Read(Buffer,BufferSize);
128  Ret.append(Buffer,BytesRead);
129  }
130  delete[] Buffer;
131  return Ret;
132  }
133 
134  size_t DataStream::ReadLine(Char8* Buffer, size_t MaxCount, const String& Delim)
135  {
136  bool TrimCR = false;
137  if(Delim.find_first_of('\n') != String::npos)
138  {
139  TrimCR = true;
140  }
141 
142  char Temp[TEMP_STREAM_SIZE];
143  size_t ChunkSize = std::min(MaxCount,(size_t)TEMP_STREAM_SIZE - 1);
144  size_t TotalCount = 0;
145  size_t ReadCount = 0;
146 
147  while(ChunkSize && (ReadCount = Read(Temp,ChunkSize)) != 0)
148  {
149  Temp[ReadCount] = '\0';
150  size_t Pos = std::strcspn(Temp,Delim.c_str());
151 
152  if(Pos < ReadCount)
153  {
154  this->Advance((long)(Pos + 1 - ReadCount));
155  }
156 
157  if(Buffer)
158  {
159  std::memcpy(Buffer + TotalCount,Temp,Pos);
160  }
161  TotalCount += Pos;
162 
163  if(Pos < ReadCount)
164  {
165  if(TrimCR && TotalCount && Buffer[TotalCount - 1] == '\r')
166  {
167  --TotalCount;
168  }
169  break;
170  }
171 
172  ChunkSize = std::min(MaxCount - TotalCount,(size_t)TEMP_STREAM_SIZE - 1);
173  }
174  Buffer[TotalCount] = '\0';
175  return TotalCount;
176  }
177 
179  {
180  char Temp[TEMP_STREAM_SIZE];
181  String Ret;
182  size_t ReadCount;
183 
184  while( (ReadCount = Read(Temp,TEMP_STREAM_SIZE - 1)) != 0 )
185  {
186  Temp[ReadCount] = '\0';
187 
188  char* Pos = std::strchr(Temp,'\n');
189  if(Pos != 0)
190  {
191  this->Advance((long)(Pos + 1 - Temp - ReadCount));
192  *Pos = '\0';
193  }
194 
195  Ret += Temp;
196 
197  if(Pos != 0)
198  {
199  if(Ret.length() && Ret[Ret.length() - 1] == '\r')
200  {
201  Ret.erase(Ret.length() - 1, 1);
202  }
203  break;
204  }
205  }
206 
207  if(Trim)
208  {
209  StringTools::Trim(Ret);
210  }
211 
212  return Ret;
213  }
214 
215  size_t DataStream::SkipLine(const String& Delim)
216  {
217  char Temp[TEMP_STREAM_SIZE];
218  size_t TotalBytes = 0;
219  size_t ReadCount = 0;
220 
221  while( (ReadCount = Read(Temp,TEMP_STREAM_SIZE - 1)) != 0 )
222  {
223  Temp[ReadCount] = '\0';
224  size_t Position = std::strcspn(Temp,Delim.c_str());
225 
226  if(Position < ReadCount)
227  {
228  this->Advance((long)(Position + 1 - ReadCount));
229  TotalBytes += Position + 1;
230  break;
231  }
232 
233  TotalBytes += ReadCount;
234  }
235 
236  return TotalBytes;
237  }
238 #endif
239  }//Resource
240 }//Mezzanine
241 
242 #endif