Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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-2005  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 "simplestream.h"
00024 #include "errors.h"
00025 
00026 /* simplestream was intended to provide streams without any dependency on
00027    basestrm, but unknotting the two was never completed */
00028 #include "basestrm.h"
00029 
00030 #ifdef _DOS_
00031   #include "dos/fileio.h"
00032   #include "dos/fileio.cpp"
00033 #else
00034  #ifdef _WIN32_
00035    #include "win32/fileio.h"
00036    #include "win32/fileio.cpp"
00037  #else
00038   #ifdef _UNIX_
00039     #include "unix/fileio.h"
00040     #include "unix/fileio.cpp"
00041   #endif
00042  #endif
00043 #endif
00044 
00045 
00046 tnbufstream::tnbufstream (  )
00047 {
00048    datalen = 0;
00049    _mode = uninitialized;
00050 
00051   zeiger = NULL;
00052   int maxav = 0x10000;
00053 
00054   do {
00055       memsize = maxav;
00056       zeiger = new char [ memsize ];
00057 
00058       maxav /= 0x10;
00059      
00060   } while ( !zeiger && maxav ); /* enddo */
00061 
00062    datasize = 0;
00063    actmempos = 0;
00064 }
00065 
00066 
00067 int          tnbufstream::readdata( void* buf, int size, bool excpt  )
00068 {
00069    char*        cpbuf = (char*) buf;
00070    int          s, actpos2;
00071 
00072    actpos2 = 0;
00073 
00074    if (_mode != reading)
00075       throw  tinvalidmode ( getDeviceName(), _mode, reading );
00076    
00077 
00078    while (actpos2 < size) {
00079       if (datasize == 0) {
00080           if ( excpt ) 
00081              throw treadafterend ( getDeviceName() );
00082           else
00083              return actpos2;
00084       }
00085        
00086       s = datasize - actmempos; 
00087       if (s > size - actpos2) 
00088          s = size - actpos2; 
00089 
00090       memcpy ( cpbuf + actpos2, zeiger + actmempos, s );
00091 
00092       actmempos += s; 
00093       if (actmempos >= datasize) { 
00094          readbuffer();
00095          actmempos = 0; 
00096       }
00097       actpos2 = actpos2 + s; 
00098    } 
00099 
00100    return actpos2;
00101 } 
00102 
00103 
00104 
00105 
00106 
00107 void         tnbufstream::writedata( const void* buf, int size )
00108 { 
00109    datalen += size;
00110    int          s, actpos2;
00111    char*        cpbuf = (char*) buf;
00112 
00113    if (_mode != writing )
00114       throw  tinvalidmode ( getDeviceName(), _mode, writing );
00115 
00116    actpos2 = 0; 
00117 
00118    while (actpos2 < size) { 
00119       s = memsize - actmempos; 
00120       if (s > size - actpos2) 
00121          s = size - actpos2;
00122 
00123       memcpy(  zeiger + actmempos, cpbuf + actpos2, s );
00124       actmempos = actmempos + s; 
00125       if (actmempos == memsize) { 
00126          writebuffer();
00127          actmempos = 0; 
00128       } 
00129       else 
00130          if (actmempos > memsize) 
00131             throw tinternalerror ( __FILE__, __LINE__ );
00132                                    
00133       actpos2 += s;
00134    } 
00135 } 
00136 
00137 
00138 tnbufstream::~tnbufstream ()
00139 { 
00140    if ( memsize > 1)
00141       delete []  zeiger ;
00142 } 
00143 
00144 
00145 
00146 
00147 int tn_file_buf_stream::getstreamsize(void)
00148 {
00149    if ( !sizeCached ) {
00150       struct stat buf;
00151       if ( stat ( getDeviceName().c_str(), &buf) )
00152          sizeValue = -1;
00153       else
00154          sizeValue = buf.st_size ;
00155 
00156       sizeCached = true;
00157    }
00158    return sizeValue;
00159 }
00160 
00161 time_t tn_file_buf_stream::get_time ( void )
00162 {
00163    if ( !timeCached ) {
00164       struct stat buf;
00165       if ( stat ( getDeviceName().c_str(), &buf) )
00166          timeValue = -1;
00167       else
00168          timeValue = buf.st_mtime;
00169 
00170       timeCached = true;
00171 
00172    }
00173    return timeValue;
00174 }
00175 
00176 
00177 tn_file_buf_stream::tn_file_buf_stream( const ASCString& _fileName, IOMode mode)
00178    : sizeCached ( false ), sizeValue ( -1 ), timeCached( false), timeValue( -1 )
00179 
00180 {
00181    char buf[10000];
00182    ASCString s;
00183    if ( strchr ( _fileName.c_str(), pathdelimitter ) == NULL )
00184       s = constructFileName ( buf, 0, NULL, _fileName.c_str() );
00185    else
00186       s = _fileName;
00187 
00188    _mode = mode;
00189 
00190    if (_mode == reading) {
00191       fp = fopen ( s.c_str(), filereadmode );
00192    } else {
00193       fp = fopen ( s.c_str(), filewritemode );
00194    }
00195 
00196    if (fp != NULL && ferror ( fp ) == 0 ) {
00197 
00198      actfilepos = 0;
00199 
00200      if (_mode == reading)
00201        readbuffer();
00202 
00203      devicename = s;
00204 
00205    } else
00206      throw tfileerror( s.c_str() );
00207 
00208 }
00209 
00210 
00211 void tn_file_buf_stream::seek( int newpos )
00212 { 
00213    if ( _mode == writing ) {
00214       writebuffer();
00215 
00216       fseek( fp, newpos, SEEK_SET );
00217       if ( ferror ( fp ) )
00218          throw  tfileerror ( getDeviceName() );
00219    
00220       actmempos = 0; 
00221       actfilepos = newpos; 
00222    } else {
00223       if ( newpos >= actfilepos-datasize   &&  newpos < actfilepos )
00224          actmempos = newpos - ( actfilepos - datasize );
00225       else {
00226          fseek( fp, newpos, SEEK_SET );
00227          if ( ferror ( fp ) )
00228             throw  tfileerror ( getDeviceName() );
00229       
00230          actmempos = 0; 
00231          actfilepos = newpos; 
00232          readbuffer(); 
00233 
00234       }
00235    }
00236 }           
00237 
00238 
00239 void tn_file_buf_stream::readbuffer( void )
00240 { 
00241    datasize = fread( zeiger, 1, memsize, fp);
00242    if ( ferror ( fp ) ) 
00243       throw  tfileerror ( getDeviceName() );
00244 
00245    actfilepos += datasize;
00246 } 
00247 
00248 
00249 
00250 
00251 void tn_file_buf_stream::writebuffer()
00252 { 
00253    size_t written = fwrite( zeiger, 1, actmempos, fp );
00254    if ( ferror ( fp ) || actmempos != written )
00255       throw  tfileerror ( getDeviceName() );
00256 
00257    actmempos = 0;
00258 }
00259 
00260 
00261 tn_file_buf_stream::~tn_file_buf_stream()
00262 {
00263    close();
00264 
00265    if (_mode == writing)
00266       writebuffer();
00267 
00268    int res = fclose( fp );
00269    if ( res != 0 )
00270       throw  tfileerror ( getDeviceName() );
00271       
00272    _mode = uninitialized;
00273 
00274 }
00275 
00276 

Generated on Tue Jun 24 01:27:52 2008 for Advanced Strategic Command by  doxygen 1.4.2