Advanced Strategic Command
simplestream.cpp
Go to the documentation of this file.
1 /*
2  This file is part of Advanced Strategic Command; http://www.asc-hq.de
3  Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  Boston, MA 02111-1307 USA
19 */
20 
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <errno.h>
24 #include "simplestream.h"
25 #include "errors.h"
26 
27 /* simplestream was intended to provide streams without any dependency on
28  basestrm, but unknotting the two was never completed */
29 #include "basestrm.h"
30 
31 #ifdef _DOS_
32  #include "dos/fileio.h"
33  #include "dos/fileio.cpp"
34 #else
35  #ifdef _WIN32_
36  #include "win32/fileio.h"
37  #include "win32/fileio.cpp"
38  #else
39  #ifdef _UNIX_
40  #include "unix/fileio.h"
41  #include "unix/fileio.cpp"
42  #endif
43  #endif
44 #endif
45 
46 
48 {
49  datalen = 0;
51 
52  zeiger = NULL;
53  int maxav = 0x10000;
54 
55  do {
56  memsize = maxav;
57  zeiger = new Uint8 [ memsize ];
58 
59  maxav /= 0x10;
60 
61  } while ( !zeiger && maxav ); /* enddo */
62 
63  datasize = 0;
64  actmempos = 0;
65 }
66 
67 
68 int tnbufstream::readdata( void* buf, int size, bool excpt )
69 {
70  char* cpbuf = (char*) buf;
71  int s, actpos2;
72 
73  actpos2 = 0;
74 
75  if (_mode != reading)
77 
78 
79  while (actpos2 < size) {
80  if (datasize == 0) {
81  if ( excpt )
82  throw treadafterend ( getDeviceName() );
83  else
84  return actpos2;
85  }
86 
87  s = datasize - actmempos;
88  if (s > size - actpos2)
89  s = size - actpos2;
90 
91  memcpy ( cpbuf + actpos2, zeiger + actmempos, s );
92 
93  actmempos += s;
94  if (actmempos >= datasize) {
95  readbuffer();
96  actmempos = 0;
97  }
98  actpos2 = actpos2 + s;
99  }
100 
101  return actpos2;
102 }
103 
104 
105 
106 
107 
108 void tnbufstream::writedata( const void* buf, int size )
109 {
110  datalen += size;
111  int s, actpos2;
112  char* cpbuf = (char*) buf;
113 
114  if (_mode != writing )
115  throw tinvalidmode ( getDeviceName(), _mode, writing );
116 
117  actpos2 = 0;
118 
119  while (actpos2 < size) {
120  s = memsize - actmempos;
121  if (s > size - actpos2)
122  s = size - actpos2;
123 
124  memcpy( zeiger + actmempos, cpbuf + actpos2, s );
125  actmempos = actmempos + s;
126  if (actmempos == memsize) {
127  writebuffer();
128  actmempos = 0;
129  }
130  else
131  if (actmempos > memsize)
132  throw tinternalerror ( __FILE__, __LINE__ );
133 
134  actpos2 += s;
135  }
136 }
137 
138 
140 {
141  if ( memsize > 1)
142  delete [] zeiger ;
143 }
144 
145 
146 
147 
149 {
150  if ( !sizeCached ) {
151  struct stat buf;
152  if ( stat ( getDeviceName().c_str(), &buf) )
153  sizeValue = -1;
154  else
155  sizeValue = buf.st_size ;
156 
157  sizeCached = true;
158  }
159  return sizeValue;
160 }
161 
163 {
164  if ( !timeCached ) {
165  struct stat buf;
166  if ( stat ( getDeviceName().c_str(), &buf) )
167  timeValue = -1;
168  else
169  timeValue = buf.st_mtime;
170 
171  timeCached = true;
172 
173  }
174  return timeValue;
175 }
176 
177 
179  : sizeCached ( false ), sizeValue ( -1 ), timeCached( false), timeValue( -1 )
180 
181 {
182  char buf[10000];
183  ASCString s;
184  if ( strchr ( _fileName.c_str(), pathdelimitter ) == NULL )
185  s = constructFileName ( buf, 0, NULL, _fileName.c_str() );
186  else
187  s = _fileName;
188 
189  _mode = mode;
190 
191  if (_mode == reading) {
192  fp = fopen ( s.c_str(), filereadmode );
193  } else {
194  fp = fopen ( s.c_str(), filewritemode );
195  }
196 
197  if (fp != NULL && ferror ( fp ) == 0 ) {
198 
199  actfilepos = 0;
200 
201  if (_mode == reading)
202  readbuffer();
203 
204  devicename = s;
205 
206  } else {
207  throw tfileerror( s + " : " + strerror(errno) );
208  }
209 
210 }
211 
212 
213 void tn_file_buf_stream::seek( int newpos )
214 {
215  if ( _mode == writing ) {
216  writebuffer();
217 
218  fseek( fp, newpos, SEEK_SET );
219  if ( ferror ( fp ) )
220  throw tfileerror ( getDeviceName() );
221 
222  actmempos = 0;
223  actfilepos = newpos;
224  } else {
225  if ( newpos >= actfilepos-datasize && newpos < actfilepos )
226  actmempos = newpos - ( actfilepos - datasize );
227  else {
228  fseek( fp, newpos, SEEK_SET );
229 
230  if ( ferror ( fp ) )
231  throw tfileerror ( getDeviceName() + " : " + strerror(errno) );
232 
233  actmempos = 0;
234  actfilepos = newpos;
235  readbuffer();
236 
237  }
238  }
239 }
240 
241 
243 {
244  datasize = fread( zeiger, 1, memsize, fp);
245  if ( ferror ( fp ) )
246  throw tfileerror ( getDeviceName() );
247 
248  actfilepos += datasize;
249 }
250 
251 
252 
253 
255 {
256  size_t written = fwrite( zeiger, 1, actmempos, fp );
257  if ( ferror ( fp ) || actmempos != written )
258  throw tfileerror ( getDeviceName() );
259 
260  actmempos = 0;
261 }
262 
263 
265 {
266  close();
267 
268  if (_mode == writing)
269  writebuffer();
270 
271  fclose( fp );
273 
274 }
275 
276 
The (base-) classes which are thrown as exceptions.
tn_file_buf_stream(const ASCString &_fileName, IOMode mode)
IOMode _mode
Definition: simplestream.h:34
virtual ASCString getDeviceName()
returns the name of the stream.
Definition: basestrm.cpp:269
virtual void writedata(const void *buf, int size)
writes data to the stream
void writebuffer(void)
The ASCString class provides an abstract way to manipulate strings.
Definition: ascstring.h:14
ASCString devicename
virtual time_t get_time(void)
Uint8 * zeiger
Definition: simplestream.h:33
const char * filereadmode
Definition: unix/fileio.cpp:19
virtual void readbuffer(void)=0
The interface for the various streams that ASC offers, like file and memory streams.
char * constructFileName(char *buf, int directoryLevel, const char *path, const char *filename)
Definition: basestrm.cpp:873
const char pathdelimitter
Definition: unix/fileio.cpp:23
virtual void writebuffer(void)=0
Definition: basestrm.cpp:2454
virtual void seek(int newpos)
Sets the stream pointer to a new location. An exception is thrown if the stream does not support seek...
virtual void close(void)
Definition: simplestream.h:41
const char * filewritemode
Definition: unix/fileio.cpp:20
virtual ~tnbufstream()
virtual int readdata(void *buf, int size, bool excpt=true)
Reads data from the stream.
virtual int getstreamsize(void)
IOMode
the modes in which a stream can operate
virtual ~tn_file_buf_stream()