simplestream.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003     Copyright (C) 1994-2010  Martin Bickel  and  Marc Schellenberger
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; see the file COPYING. If not, write to the
00017     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00018     Boston, MA  02111-1307  USA
00019 */
00020 
00021 #include <string.h>
00022 #include <sys/stat.h>
00023 #include <errno.h>
00024 #include "simplestream.h"
00025 #include "errors.h"
00026 
00027 /* simplestream was intended to provide streams without any dependency on
00028    basestrm, but unknotting the two was never completed */
00029 #include "basestrm.h"
00030 
00031 #ifdef _DOS_
00032   #include "dos/fileio.h"
00033   #include "dos/fileio.cpp"
00034 #else
00035  #ifdef _WIN32_
00036    #include "win32/fileio.h"
00037    #include "win32/fileio.cpp"
00038  #else
00039   #ifdef _UNIX_
00040     #include "unix/fileio.h"
00041     #include "unix/fileio.cpp"
00042   #endif
00043  #endif
00044 #endif
00045 
00046 
00047 tnbufstream::tnbufstream (  )
00048 {
00049    datalen = 0;
00050    _mode = uninitialized;
00051 
00052   zeiger = NULL;
00053   int maxav = 0x10000;
00054 
00055   do {
00056       memsize = maxav;
00057       zeiger = new char [ memsize ];
00058 
00059       maxav /= 0x10;
00060      
00061   } while ( !zeiger && maxav ); /* enddo */
00062 
00063    datasize = 0;
00064    actmempos = 0;
00065 }
00066 
00067 
00068 int          tnbufstream::readdata( void* buf, int size, bool excpt  )
00069 {
00070    char*        cpbuf = (char*) buf;
00071    int          s, actpos2;
00072 
00073    actpos2 = 0;
00074 
00075    if (_mode != reading)
00076       throw  tinvalidmode ( getDeviceName(), _mode, reading );
00077    
00078 
00079    while (actpos2 < size) {
00080       if (datasize == 0) {
00081           if ( excpt ) 
00082              throw treadafterend ( getDeviceName() );
00083           else
00084              return actpos2;
00085       }
00086        
00087       s = datasize - actmempos; 
00088       if (s > size - actpos2) 
00089          s = size - actpos2; 
00090 
00091       memcpy ( cpbuf + actpos2, zeiger + actmempos, s );
00092 
00093       actmempos += s; 
00094       if (actmempos >= datasize) { 
00095          readbuffer();
00096          actmempos = 0; 
00097       }
00098       actpos2 = actpos2 + s; 
00099    } 
00100 
00101    return actpos2;
00102 } 
00103 
00104 
00105 
00106 
00107 
00108 void         tnbufstream::writedata( const void* buf, int size )
00109 { 
00110    datalen += size;
00111    int          s, actpos2;
00112    char*        cpbuf = (char*) buf;
00113 
00114    if (_mode != writing )
00115       throw  tinvalidmode ( getDeviceName(), _mode, writing );
00116 
00117    actpos2 = 0; 
00118 
00119    while (actpos2 < size) { 
00120       s = memsize - actmempos; 
00121       if (s > size - actpos2) 
00122          s = size - actpos2;
00123 
00124       memcpy(  zeiger + actmempos, cpbuf + actpos2, s );
00125       actmempos = actmempos + s; 
00126       if (actmempos == memsize) { 
00127          writebuffer();
00128          actmempos = 0; 
00129       } 
00130       else 
00131          if (actmempos > memsize) 
00132             throw tinternalerror ( __FILE__, __LINE__ );
00133                                    
00134       actpos2 += s;
00135    } 
00136 } 
00137 
00138 
00139 tnbufstream::~tnbufstream ()
00140 { 
00141    if ( memsize > 1)
00142       delete []  zeiger ;
00143 } 
00144 
00145 
00146 
00147 
00148 int tn_file_buf_stream::getstreamsize(void)
00149 {
00150    if ( !sizeCached ) {
00151       struct stat buf;
00152       if ( stat ( getDeviceName().c_str(), &buf) )
00153          sizeValue = -1;
00154       else
00155          sizeValue = buf.st_size ;
00156 
00157       sizeCached = true;
00158    }
00159    return sizeValue;
00160 }
00161 
00162 time_t tn_file_buf_stream::get_time ( void )
00163 {
00164    if ( !timeCached ) {
00165       struct stat buf;
00166       if ( stat ( getDeviceName().c_str(), &buf) )
00167          timeValue = -1;
00168       else
00169          timeValue = buf.st_mtime;
00170 
00171       timeCached = true;
00172 
00173    }
00174    return timeValue;
00175 }
00176 
00177 
00178 tn_file_buf_stream::tn_file_buf_stream( const ASCString& _fileName, IOMode mode)
00179    : sizeCached ( false ), sizeValue ( -1 ), timeCached( false), timeValue( -1 )
00180 
00181 {
00182    char buf[10000];
00183    ASCString s;
00184    if ( strchr ( _fileName.c_str(), pathdelimitter ) == NULL )
00185       s = constructFileName ( buf, 0, NULL, _fileName.c_str() );
00186    else
00187       s = _fileName;
00188 
00189    _mode = mode;
00190 
00191    if (_mode == reading) {
00192       fp = fopen ( s.c_str(), filereadmode );
00193    } else {
00194       fp = fopen ( s.c_str(), filewritemode );
00195    }
00196 
00197    if (fp != NULL && ferror ( fp ) == 0 ) {
00198 
00199      actfilepos = 0;
00200 
00201      if (_mode == reading)
00202        readbuffer();
00203 
00204      devicename = s;
00205 
00206    } else {
00207       throw tfileerror( s + " : " + strerror(errno) );
00208    }
00209 
00210 }
00211 
00212 
00213 void tn_file_buf_stream::seek( int newpos )
00214 { 
00215    if ( _mode == writing ) {
00216       writebuffer();
00217 
00218       fseek( fp, newpos, SEEK_SET );
00219       if ( ferror ( fp ) )
00220          throw  tfileerror ( getDeviceName() );
00221    
00222       actmempos = 0; 
00223       actfilepos = newpos; 
00224    } else {
00225       if ( newpos >= actfilepos-datasize   &&  newpos < actfilepos )
00226          actmempos = newpos - ( actfilepos - datasize );
00227       else {
00228          fseek( fp, newpos, SEEK_SET );
00229 
00230          if ( ferror ( fp ) )
00231             throw  tfileerror ( getDeviceName() + " : " + strerror(errno) );
00232       
00233          actmempos = 0; 
00234          actfilepos = newpos; 
00235          readbuffer(); 
00236 
00237       }
00238    }
00239 }           
00240 
00241 
00242 void tn_file_buf_stream::readbuffer( void )
00243 { 
00244    datasize = fread( zeiger, 1, memsize, fp);
00245    if ( ferror ( fp ) ) 
00246       throw  tfileerror ( getDeviceName() );
00247 
00248    actfilepos += datasize;
00249 } 
00250 
00251 
00252 
00253 
00254 void tn_file_buf_stream::writebuffer()
00255 { 
00256    size_t written = fwrite( zeiger, 1, actmempos, fp );
00257    if ( ferror ( fp ) || actmempos != written )
00258       throw  tfileerror ( getDeviceName() );
00259 
00260    actmempos = 0;
00261 }
00262 
00263 
00264 tn_file_buf_stream::~tn_file_buf_stream()
00265 {
00266    close();
00267 
00268    if (_mode == writing)
00269       writebuffer();
00270 
00271    int res = fclose( fp );
00272    if ( res != 0 ) 
00273       throw  tfileerror ( getDeviceName() + " : " + strerror(errno));
00274       
00275    _mode = uninitialized;
00276 
00277 }
00278 
00279 

Generated on Mon May 21 01:26:37 2012 for Advanced Strategic Command by  doxygen 1.5.1