/source/basestrm.cpp
C++ | 2637 lines | 2066 code | 447 blank | 124 comment | 314 complexity | 44da3823258597314dfaa504bb4958ab MD5 | raw file
Possible License(s): AGPL-1.0, GPL-2.0
Large files files are truncated, but you can click here to view the full file
- /*! \file basestrm.cpp
- \brief The various streams that ASC offers, like file and memory streams.
- */
- /*
- This file is part of Advanced Strategic Command; http://www.asc-hq.de
- Copyright (C) 1994-2010 Martin Bickel and Marc Schellenberger
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- Boston, MA 02111-1307 USA
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <cstdlib>
- #include <stdlib.h>
- #include <string>
- #include <list>
- #include "global.h"
- #ifdef HAVE_LIMITS
- #include <limits>
- #endif
- #include <sys/stat.h>
- #include <bzlib.h>
- #include "global.h"
- #include "basestrm.h"
- #ifdef _DOS_
- #include "dos/fileio.h"
- #else
- #ifdef _WIN32_
- #include "win32/fileio.h"
- #else
- #ifdef _UNIX_
- #include "unix/fileio.h"
- #endif
- #endif
- #endif
- //#include sdlheader
- #include <SDL_endian.h>
- #include "util/messaginghub.h"
- const int maxSearchDirNum = 30;
- int searchDirNum = 0;
- char* ascDirectory[maxSearchDirNum] = { NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL };
- #pragma pack(1)
- struct trleheader {
- unsigned short int id;
- unsigned short int size;
- char rle;
- unsigned short int x;
- unsigned short int y;
- };
- #pragma pack()
- #define bzip_xor_byte 'M'
- const char* containermagic = "NCBM";
- const char* LZ_SIGNATURE = "MBLZW16";
- const char* RLE_SIGNATURE = "MBRLE1";
- const char* BZIP_SIGNATURE = "MBZLB2X!";
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //////////// Watchpointer
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- CharBuf :: CharBuf ( void )
- {
- size = 0;
- buf = NULL;
- }
- CharBuf :: CharBuf ( int _size )
- {
- size = _size;
- buf = new char[ size ];
- }
- void CharBuf :: resize ( int newsize )
- {
- char* nb = new char[newsize];
- for ( int i = 0; i < size; i++ )
- nb[i] = buf[i];
- delete[] buf;
- buf = nb;
- }
- CharBuf :: ~CharBuf()
- {
- if ( buf )
- delete[] buf;
- buf = NULL;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //////////// Exceptions
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- OutOfMemoryError::OutOfMemoryError ( int m )
- {
- required = m;
- }
- tfileerror::tfileerror ( const ASCString& fileName )
- {
- _filename = fileName ;
- }
- tinvalidmode :: tinvalidmode ( const ASCString& _fileName, tnstream::IOMode org_mode, tnstream::IOMode requested_mode )
- : tfileerror ( _fileName )
- {
- orgmode = org_mode;
- requestmode = requested_mode;
- }
- treadafterend :: treadafterend ( const ASCString& _fileName )
- : tfileerror ( _fileName )
- {
- }
- tinternalerror::tinternalerror ( const char* filename, int l )
- {
- linenum = l;
- sourcefilename = filename;
- }
- tinvalidversion :: tinvalidversion ( const ASCString& _fileName, int ex, int fnd )
- : tfileerror ( _fileName ), expected ( ex ), found ( fnd )
- {
- }
- ASCString tinvalidversion :: getMessage() const
- {
- ASCString s;
- if ( expected < found )
- s.format( "File/module %s has invalid version.\nExpected file version %d\nFound file version %d\nThe file/module is newer than your application\nPlease install the latest version of ASC from www.asc-hq.org", getFileName().c_str(), expected, found );
- else
- s.format ( "File/module %s has invalid version.\nExpected file version %d\nFound file version %d\nThis is a bug, please report it!", getFileName().c_str(), expected, found );
- return s;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //////////// Streams
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- tnstream :: tnstream ( void )
- : devicename ( "-abstract tnstream-" ) {}
- void tnstream::seek ( int pos )
- {
- throw tfileerror ( "Seeking not supported for stream " + getDeviceName() );
- }
- void tnstream::readrlepict( void** pnter, bool allocated, int* size)
- {
- trleheader hd;
- int w;
- char* q;
- hd.id = readWord();
- hd.size = readWord();
- hd.rle = readChar();
- hd.x = readWord();
- hd.y = readWord();
- if (hd.id == 16973) {
- if (!allocated)
- *pnter = new char [ hd.size + sizeof(hd) ];
- memcpy( *pnter, &hd, sizeof(hd));
- q = (char*) (*pnter) + sizeof(hd);
- readdata( q, hd.size); // endian ok ?
- *size = hd.size + sizeof(hd);
- }
- else {
- w = (hd.id + 1) * (hd.size + 1) + 4 ;
- if (!allocated)
- *pnter = new char [ w ];
- memcpy ( *pnter, &hd, sizeof ( hd ));
- q = (char*) (*pnter) + sizeof(hd);
- readdata ( q, w - sizeof(hd) ); // endian ok ?
- *size = w;
- }
- }
- void tnstream :: writerlepict ( const void* buf )
- {
- writeImage( buf, true );
- }
- void tnstream :: writeImage ( const void* buf, bool compress )
- {
- if ( compress ) {
- char* tempbuf = new char [ 0xffff ];
- if ( tempbuf ) {
- int size = compressrle ( buf, tempbuf );
- trleheader* hd = (trleheader*) tempbuf;
- writeWord( hd->id );
- writeWord( hd->size );
- writeChar( hd->rle );
- writeWord( hd->x );
- writeWord( hd->y );
-
- writedata ( hd+1, size - sizeof(*hd) );
- delete[] tempbuf;
- } else
- compress = false;
- }
- if ( !compress ) {
- Uint16* pw = (Uint16*) buf;
- writeWord(pw[0] );
- writeWord(pw[1] );
- writedata ( pw+2, ( pw[0] + 1 ) * ( pw[1] + 1 ) );
- }
- }
- ASCString tnstream::getDeviceName()
- {
- return devicename;
- }
- ASCString tnstream::getLocation()
- {
- return devicename;
- }
- ASCString tnstream::getArchive()
- {
- return "";
- }
- int tnstream::readInt ( void )
- {
- int i;
- readdata2 ( i );
- return SDL_SwapLE32( i );
- }
- int tnstream::readWord ( void )
- {
- Uint16 w;
- readdata2 ( w );
- return SDL_SwapLE16( w );
- }
- char tnstream::readChar ( void )
- {
- char c;
- readdata2 ( c );
- return c;
- }
- float SwapFloat( float f )
- {
- union
- {
- float f;
- unsigned char b[4];
- } dat1, dat2;
- dat1.f = f;
- dat2.b[0] = dat1.b[3];
- dat2.b[1] = dat1.b[2];
- dat2.b[2] = dat1.b[1];
- dat2.b[3] = dat1.b[0];
- return dat2.f;
- }
- float tnstream::readFloat ( void )
- {
- float c;
- readdata2 ( c );
- #if SDL_BYTEORDER == SDL_BIG_ENDIAN
- c = SwapFloat(c);
- #endif
- return c;
- }
- #if SIZE_T_not_identical_to_INT
- void tnstream::writeInt ( size_t i )
- {
- #ifdef HAVE_LIMITS
- // assert( i <= numeric_limits<int>::max());
- #endif
- writeInt( int(i) );
- }
- #endif
- void tnstream::writeInt ( unsigned int i )
- {
- i = SDL_SwapLE32(i);
- writedata2 ( i );
- }
- void tnstream::writeInt ( bool b )
- {
- int i = b;
- i = SDL_SwapLE32(i);
- writedata2 ( i );
- }
- void tnstream::writeInt ( int i )
- {
- i = SDL_SwapLE32(i);
- writedata2 ( i );
- }
- void tnstream::writeWord ( int w )
- {
- Uint16 w2 = SDL_SwapLE16( Uint16(w) );
- writedata2 ( w2 );
- }
- void tnstream::writeChar ( char c )
- {
- writedata2 ( c );
- }
- void tnstream::writeFloat ( float f )
- {
- writedata2 ( f );
- }
- void tnstream::readpchar(char** pc, int maxlength )
- {
- int actpos2 = 0;
- int maxav = 100000;
-
- if ( maxlength )
- if ( maxav > maxlength )
- maxav = maxlength;
- CharBuf charbuf ( maxav );
- maxav--;
- char* pch2 = charbuf.buf;
- int loop = 0;
- do {
- actpos2++;
- if ( loop )
- pch2++;
-
- loop++;
- readdata( pch2, 1 ); // endian ok !
- } while (*pch2 != 0 && actpos2 < maxav ); /* enddo */
- if ( actpos2 >= maxav ) {
- pch2[1] = 0;
- actpos2++;
- if ( pch2[0] ) {
- char temp;
- do {
- readdata( &temp, 1 ); // endian ok !
- } while ( temp ); /* enddo */
- }
- }
-
- pch2 = new char [ actpos2 ];
- memcpy ( pch2, charbuf.buf, actpos2 );
- *pc = pch2;
- }
- void tnstream::readpnchar(char** pc, int maxlength )
- {
- int actpos2 = 0;
- int maxav = 10000;
-
- if ( maxlength )
- if ( maxav > maxlength )
- maxav = maxlength;
- CharBuf charbuf ( maxav );
- maxav--;
- char* pch2 = charbuf.buf;
- int ende = 0;
- do {
- char bt;
- int red = readdata( &bt, 1, 0 );
- if ( red < 1 ) {
- ende = 2;
- *pch2 = 0;
- } else
- if ( bt == '\n' || bt == 0 ) {
- *pch2 = 0;
- ende = 1;
- } else
- if ( bt != '\r' ) {
- *pch2 = bt;
- pch2++;
- actpos2++;
- }
- } while ( !ende && actpos2 < maxav ); /* enddo */
- if ( !ende ) {
- if ( actpos2 >= maxav ) {
- *pch2 = 0;
- if ( pch2[0] ) {
- char temp;
- do {
- int red = readdata( &temp, 1, 0 );
- if ( red < 1 ) {
- temp = 0;
- } else
- if ( temp == '\n' )
- temp = 0;
- } while ( temp ); /* enddo */
- }
- }
- }
- if ( ende == 2 ) {
- if ( !actpos2 )
- *pc = NULL;
- else
- *pc = strdup ( charbuf.buf );
- } else
- *pc = strdup ( charbuf.buf );
- }
- bool tnstream::readTextString ( ASCString& s, bool includeCR )
- {
- s = "";
- char c;
- int red;
- int end = 0;
- do {
- red = readdata( &c, 1, 0 ); // endian ok !
- if ( red < 1 ) {
- end = 2;
- } else
- if ( (c == '\n' && !includeCR) || c == 0 ) {
- end = 1;
- } else
- if ( c != '\r' )
- s += c;
- } while ( red && !end );
- if ( end == 2)
- return false;
- else
- return true;
- }
- ASCString tnstream::readString ( bool includeCR )
- {
- ASCString s;
- bool data = readTextString ( s, includeCR );
- if ( !data && s.empty() )
- throw treadafterend ( getLocation() );
- return s;
- }
- void tnstream::writeString(const string& pc, bool binary )
- {
- if ( binary )
- writepchar ( pc.c_str() );
- else
- writedata ( pc.data(), pc.length() );
- }
- void tnstream::writepchar(const char* pc)
- {
- if ( pc ) {
- const char *pch1 = pc;
- int loop = 0;
- do {
- if ( loop )
- pch1++;
- writedata( pch1, 1 );
- loop++;
- } while ( *pch1 > 0 ); /* enddo */
- } else {
- char pch1 = 0;
- writedata ( &pch1, 1 );
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- MemoryStreamCopy :: MemoryStreamCopy ( tnstream* stream )
- {
- buf = NULL;
- int bufused = 0;
- int memreserved = 0;
- int blocksize = 500000;
- int red;
- do {
- if ( bufused + blocksize > memreserved ) {
- int newsize = memreserved + blocksize;
- void* newbuf = malloc (newsize);
- if ( buf ) {
- memcpy ( newbuf, buf, bufused );
- free ( buf );
- }
- buf = newbuf;
- memreserved = newsize;
- }
- char* cp = (char*) buf;
- red = stream->readdata ( cp + bufused, blocksize, 0 ); // endian ok !
- bufused += red;
- } while ( red == blocksize );
- size = bufused;
- pos = 0;
- devicename = stream->getDeviceName();
- }
- ASCString MemoryStreamCopy::getLocation()
- {
- return devicename + " (memory buffered)";
- }
- MemoryStreamCopy :: ~MemoryStreamCopy ( )
- {
- if ( buf )
- free ( buf );
- }
- void MemoryStreamCopy :: writedata ( const void* buf, int size )
- {
- throw tinvalidmode ( getDeviceName(), reading, writing );
- }
- int MemoryStreamCopy :: readdata ( void* buffer, int _size, bool excpt )
- {
- char* cp = (char*) buf;
- if ( pos + _size > size ) {
- if ( excpt )
- throw treadafterend ( getDeviceName() );
- else {
- int tr = size-pos;
- memcpy ( buffer, cp+pos, tr );
- pos += tr;
- return tr;
- }
- } else {
- memcpy ( buffer, cp+pos, _size );
- pos += _size;
- return _size;
- }
- }
- void MemoryStreamCopy :: seek ( int newpos )
- {
- if ( newpos > size || newpos < 0 )
- throw treadafterend ( getDeviceName() );
- pos = newpos;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- static int stream_seek( struct SDL_RWops *context, int offset, int whence)
- {
- MemoryStreamCopy* stream = (MemoryStreamCopy*) context->hidden.unknown.data1;
- if ( whence == SEEK_SET )
- stream->seek ( offset );
- else
- if ( whence == SEEK_CUR )
- stream->seek ( offset + stream->getPosition() );
- else
- if ( whence == SEEK_END )
- stream->seek ( offset + stream->getSize() );
- return stream->getPosition();
- }
- static int stream_read(SDL_RWops *context, void *ptr, int size, int maxnum)
- {
- MemoryStreamCopy* stream = (MemoryStreamCopy*) context->hidden.unknown.data1;
- size_t nread = stream->readdata ( ptr, size * maxnum, 0 );
- return(nread / size);
- }
- static int stream_close(SDL_RWops *context)
- {
- if ( context ) {
- if ( context->hidden.unknown.data1 ) {
- MemoryStreamCopy* stream = (MemoryStreamCopy*) context->hidden.unknown.data1;
- delete stream;
- }
- SDL_FreeRW(context);
- }
- return(0);
- }
- SDL_RWops *SDL_RWFromStream( tnstream* stream )
- {
- MemoryStreamCopy* msb = new MemoryStreamCopy ( stream );
- SDL_RWops *rwops;
- rwops = SDL_AllocRW();
- if ( rwops != NULL ) {
- rwops->seek = stream_seek;
- rwops->read = stream_read;
- rwops->write = NULL;
- rwops->close = stream_close;
- rwops->hidden.unknown.data1 = msb;
- }
- return(rwops);
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- tncontainerstream :: tncontainerstream ( const char* containerfilename, ContainerIndexer* indexer, int dirLevel )
- : tn_file_buf_stream ( containerfilename, reading ), index(NULL)
- {
- num = 0;
- char magic[4];
- readdata ( &magic, 4 ); // endian ok !
- if ( strncmp ( magic, containermagic, 4 ) == 0) {
- int pos = readInt();
- seek ( pos );
- num = readInt();
- index = new tcontainerindex[num];
- for ( int i = 0; i < num; i++ ) {
- bool __loadName = readInt();
- index[i].start = readInt();
- index[i].end = readInt();
- if ( __loadName ) {
- readpchar ( &index[i].name );
- #if CASE_SENSITIVE_FILE_NAMES == 1
- // quick hack to be able to use existing CON files.
- char *c = index[i].name;
- while ( *c ) {
- *c = tolower( *c );
- c++;
- }
- #endif
- indexer->addfile ( index[i].name, this, dirLevel );
- } else
- index[i].name = NULL;
- }
- }
- actfile = NULL;
- containerfilepos = 0;
- }
- int tncontainerstream :: getcontainerfilesize ( const char* name )
- {
- int i = 0;
- while ( i < num && stricmp ( index[i].name, name ) )
- i++;
- if ( i >= num )
- return -1;
- else
- return index[i].end - index[i].start + 1;
- }
- void tncontainerstream :: opencontainerfile ( const char* name )
- {
- if ( actfile ) {
- ASCString err = ASCString("two files simultaneously: ") + actfile->name + " and " + name;
- throw tfileerror ( err );
- }
- containerfilepos = 0;
- int i = 0;
- while ( i < num && stricmp ( index[i].name, name ) )
- i++;
- if ( i >= num )
- throw tfileerror ( name );
- displayLogMessage( 9, ASCString("opencontainerfile ") + name );
- containerfilepos = 0;
- seek ( index[i].start );
- actfile = &index[i];
- }
- int tncontainerstream :: readcontainerdata ( void* buf, int size, bool excpt )
- {
- if ( actfile->start + containerfilepos + size > actfile->end+1 ) {
- if ( excpt )
- throw treadafterend ( actfile->name );
- else {
- int got = readdata ( buf, (actfile->end+1 - actfile->start) - containerfilepos , excpt );
- containerfilepos+=got;
- return got;
- }
- }
- readdata ( buf, size );
- containerfilepos+=size;
- return size;
- }
- void tncontainerstream :: closecontainerfile ( void )
- {
- actfile = NULL;
- }
- char* tncontainerstream :: getfirstname ( void )
- {
- actname = 0;
- return getnextname();
- }
- char* tncontainerstream :: getnextname ( void )
- {
- if ( actname < num )
- return index[actname++].name;
- else
- return NULL;
- }
- tncontainerstream :: ~tncontainerstream ()
- {
- for ( int i = 0; i < num; i++ )
- if ( index[i].name )
- delete[] index[i].name;
- delete[] index;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class ContainerCollector : public ContainerIndexer {
- public:
- struct FileIndex {
- ASCString name;
- pncontainerstream container;
- int directoryLevel;
- };
- protected:
- dynamic_array<FileIndex> index[256]; // not very efficient, but who cares :-)
- dynamic_array<pncontainerstream> container;
- int containernum;
- struct {
- int alpha;
- int index;
- } namesearch; // next entry to return
- public:
- ContainerCollector ( void );
- void init ( const char* wildcard );
- void addfile ( const char* filename, const pncontainerstream stream, int directoryLevel );
- // pncontainerstream getfile ( const char* filename );
- FileIndex* getfile ( const ASCString& filename );
- FileIndex* getfirstname ( void );
- FileIndex* getnextname ( void );
- ASCString listContainer();
- virtual ~ContainerCollector();
- };
- ContainerCollector containercollector;
- char* constructFileName( char* buf, int directoryLevel, const char* path, const char* filename )
- {
- if ( buf ) {
- const char* filename2 = filename;
- buf[0] = 0;
- // filenames beginning with / or ~/ have an absolute path ; ignore variable path for them
- if ( ! (filename && (filename[0] == pathdelimitter || (filename[0]=='~' && filename[1] == pathdelimitter)) )) {
- if ( path )
- strcpy ( buf, path);
- else
- if ( directoryLevel >= 0 && ascDirectory[ directoryLevel ] )
- strcpy ( buf, ascDirectory[ directoryLevel ]);
- }
- appendbackslash ( buf );
- if ( filename && strchr ( filename, pathdelimitter )) {
-
- char name2[ maxFileStringSize ];
- // filename contains directories
- strcpy ( name2, filename );
- int i = strlen ( name2 )-1;
- while ( name2[i] != pathdelimitter )
- i--;
- name2[i+1] = 0;
- filename2 = &filename[i+1];
- // filename2 is now the pure filename without directory
- // name2 is the directory
-
- if ( buf[0] && name2[0]==pathdelimitter )
- strcpy ( buf, name2+1);
- else
- strcpy ( buf, name2);
- }
- if ( buf[0] == '~' && buf[1] == pathdelimitter ) {
- char* home = getenv ( "HOME" );
- if ( home ) {
- char temp[ maxFileStringSize ];
- strcpy ( temp, buf );
- strcpy ( buf, home );
- appendbackslash ( buf );
- strcat ( buf, &temp[2]);
- }
- }
- appendbackslash ( buf );
- if ( filename2 )
- strcat ( buf, filename2 );
- }
- return buf;
- }
- bool isPathRelative( const ASCString& path )
- {
- if ( path.length() < 2 )
- return true;
-
- if ( path[0] == '~' && path[1] == pathdelimitter )
- return false;
- #ifdef WIN32
- if ( path[1] == ':' && path[2] == pathdelimitter )
- return false;
- #endif
-
- if ( path[0] == pathdelimitter )
- return false;
- return true;
- }
- ASCString constructFileName( int directoryLevel, const ASCString& path, ASCString filename )
- {
- ASCString result;
-
- // filenames beginning with / or ~/ have an absolute path ; ignore variable path for them
- if ( isPathRelative( filename )) {
- if ( !path.empty() )
- result += path;
- else
- if ( directoryLevel >= 0 && ascDirectory[ directoryLevel ] )
- result += ascDirectory[ directoryLevel ];
- }
- appendbackslash ( result );
- if ( !filename.empty() && filename.find( pathdelimitter )!= ASCString::npos ) {
- ASCString dir = filename;
-
- dir.erase( dir.rfind( pathdelimitter ) + 1);
- filename.erase( 0, filename.find( pathdelimitter ) + 1 );
-
- if ( dir.find( pathdelimitter ) == 0 )
- dir.erase( 0, 1 );
-
- result = dir;
- }
- if ( result.length() > 2 && result[0] == '~' && result[1] == pathdelimitter ) {
- char* home = getenv ( "HOME" );
- if ( home ) {
- ASCString temp = result;
- result = home;
- appendbackslash ( result );
- result += temp.substr( 2 );
- }
- }
- appendbackslash ( result );
- result += filename;
- return result;
- }
- struct FileLocation {
- int directoryLevel;
- pncontainerstream container;
- int found;
- };
- void locateFile ( const ASCString& filename, FileLocation* loc )
- {
- loc->found = 0;
- ContainerCollector::FileIndex* idx = containercollector.getfile ( filename );
- int maxnum;
- if ( idx ) {
- maxnum = idx->directoryLevel+1;
- loc->directoryLevel = idx->directoryLevel;
- loc->found = 1;
- loc->container = idx->container;
- } else {
- maxnum = searchDirNum;
- loc->container = NULL;
- loc->directoryLevel = -1;
- }
- if ( maxnum ) {
- int localfound = 0;
- for ( int i = 0; i < maxnum && !localfound; i++ ) {
- char buf[2000];
- FILE* fp = fopen ( constructFileName ( buf, i, NULL, filename.c_str()), "r" );
- if ( fp ) {
- localfound = loc->found = 1;
- fclose ( fp );
- loc->container = NULL;
- loc->directoryLevel = i;
- }
- }
- } else {
- char buf[2000];
- FILE* fp = fopen ( constructFileName ( buf, -1, ".", filename.c_str()), "r" );
- if ( fp ) {
- loc->found = 1;
- fclose ( fp );
- loc->container = NULL;
- loc->directoryLevel = -2;
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ASCString listContainer()
- {
- return containercollector.listContainer();
- }
- ContainerCollector :: ContainerCollector ( void )
- {
- containernum = 0;
- }
- void ContainerCollector :: init ( const char* wildcard )
- {
- for ( int i = 0; i < searchDirNum; i++ ) {
- DIR *dirp;
- struct ASC_direct *direntp;
- char buf[ maxFileStringSize ];
- char buf2[ maxFileStringSize ];
- char buf3 [ maxFileStringSize ];
- dirp = opendir( extractPath ( buf2, constructFileName ( buf, i, NULL, wildcard )));
- extractFileName ( buf3, buf );
- if( dirp != NULL ) {
- for(;;) {
- direntp = readdir( dirp );
- if ( direntp == NULL ) {
- break;
- }
- if ( patimat ( buf3, direntp->d_name )) {
- container[containernum++] = new tncontainerstream( constructFileName ( buf, i, buf2, direntp->d_name), this, i);
- if ( MessagingHub::Instance().getVerbosity() >= 2 )
- printf("container %s mounted\n", buf );
- }
- }
- closedir( dirp );
- }
- }
- }
- void ContainerCollector :: addfile ( const char* filename, const pncontainerstream stream, int directoryLevel )
- {
- int found = 0;
- FileIndex* cci = NULL;
- int i1 = toupper ( filename[0] );
- for ( int i = 0; i <= index[i1].getlength(); i++ )
- if ( index[i1][i].name.compare_ci ( filename ) == 0 ) {
- if ( index[i1][i].directoryLevel <= directoryLevel )
- return;
- else {
- cci = &(index[i1][i]);
- found = 1;
- }
- }
- if ( !found )
- cci = &( index[i1][ index[i1].getlength()+1 ] );
- cci->name = filename;
- cci->container = stream;
- cci->directoryLevel = directoryLevel;
- }
- ContainerCollector::FileIndex* ContainerCollector :: getfile ( const ASCString& filename )
- {
- int i1 = toupper ( filename[0] );
- for ( int i = 0; i <= index[i1].getlength(); i++ )
- if ( index[i1][i].name.compare_ci ( filename) == 0 )
- return &index[i1][i];
- return NULL;
- }
- ContainerCollector::FileIndex* ContainerCollector :: getfirstname ( void )
- {
- namesearch.alpha = 0;
- namesearch.index = 0;
- return getnextname();
- }
- ContainerCollector::FileIndex* ContainerCollector :: getnextname ( void )
- {
- while ( index[namesearch.alpha].getlength() < namesearch.index) {
- if ( namesearch.alpha == 255 )
- return NULL;
- namesearch.alpha++;
- namesearch.index = 0;
- } /* endwhile */
- return &index[namesearch.alpha][namesearch.index++];
- }
- ASCString ContainerCollector :: listContainer()
- {
- ASCString s;
- for ( int i = 0; i < containernum; i++ )
- s += container[i]->getLocation() + "\n";
- return s;
-
- }
- ContainerCollector :: ~ContainerCollector()
- {
- int i;
- for (i = 0; i < containernum; i++ )
- delete container[i];
- containernum = 0;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- CompressionStreamAdapter::CompressionStreamAdapter( tnstream* compressedStream )
- : stream ( compressedStream )
- {
- }
- void CompressionStreamAdapter::writecmpdata ( const void* buf, int size )
- {
- stream->writedata( buf, size );
- }
- int CompressionStreamAdapter::readcmpdata ( void* buf, int size, bool excpt )
- {
- return stream->readdata( buf, size, excpt );
- }
- class PrivateCompressionData {
- public:
- bz_stream bzs;
- static const int outputbufsize = 100000;
- char outputbuf[outputbufsize];
-
- PrivateCompressionData() {
- bzs.bzalloc = NULL;
- bzs.bzfree = NULL;
- bzs.opaque = NULL;
- };
-
- ~PrivateCompressionData() {
- BZ2_bzCompressEnd ( &bzs );
- }
- };
- libbzip_compression :: libbzip_compression ( CompressionStreamInterface* strm )
- {
- data = new PrivateCompressionData();
- BZ2_bzCompressInit ( &data->bzs, 5, 0, 0 );
- stream = strm;
- }
- void libbzip_compression :: writedata ( const void* buf, int size )
- {
- char* cbuf = (char*) buf;
- data->bzs.next_in = cbuf ;
- data->bzs.avail_in = size ;
- data->bzs.total_in_lo32 = 0 ;
- data->bzs.total_in_hi32 = 0 ;
- while ( data->bzs.total_in_lo32 < size ) {
- data->bzs.next_out = data->outputbuf;
- data->bzs.avail_out = data->outputbufsize;
- data->bzs.total_out_lo32 = 0;
- data->bzs.total_out_hi32 = 0;
- int res = BZ2_bzCompress ( &data->bzs, BZ_RUN );
- if ( res < 0 )
- throw StreamCompressionError ( "MBZLB2 compression :: writedata", res );
- for ( int i = 0; i < data->bzs.total_out_lo32; i++ )
- data->outputbuf[i] ^= bzip_xor_byte;
- if ( data->bzs.total_out_lo32 > 0 )
- stream->writecmpdata ( data->outputbuf, data->bzs.total_out_lo32 );
- }
- }
- void libbzip_compression :: close_compression ( void )
- {
- int res;
- do {
- data->bzs.next_in = data->outputbuf;
- data->bzs.avail_in = 0;
- data->bzs.next_out = data->outputbuf;
- data->bzs.avail_out = data->outputbufsize;
- data->bzs.total_out_lo32 = 0;
- data->bzs.total_out_hi32 = 0;
- res = BZ2_bzCompress ( &data->bzs, BZ_FINISH );
- if ( res < 0 )
- throw StreamCompressionError ( "MBZLB2 compression :: closecompression", res );
- for ( int i = 0; i < data->bzs.total_out_lo32; i++ )
- data->outputbuf[i] ^= bzip_xor_byte;
- stream->writecmpdata ( data->outputbuf, data->bzs.total_out_lo32 );
- } while ( res != BZ_STREAM_END );
- BZ2_bzCompressEnd ( &data->bzs );
- }
- libbzip_compression :: ~libbzip_compression ( )
- {
- delete data;
- }
- class PrivateDecompressionData {
- public:
- bz_stream bzs;
- static const int inputbufsize = 100000;
- char inputbuf[inputbufsize];
- int inputbufused;
- int inputbufread;
-
- PrivateDecompressionData() {
- bzs.bzalloc = NULL;
- bzs.bzfree = NULL;
- bzs.opaque = NULL;
-
- inputbufused = 0;
- inputbufread = 0;
-
- }
-
- ~PrivateDecompressionData() {
- BZ2_bzDecompressEnd ( &bzs );
- }
-
- };
-
- libbzip_decompression :: libbzip_decompression ( CompressionStreamInterface* strm )
- {
- data = new PrivateDecompressionData();
- BZ2_bzDecompressInit ( &data->bzs, 0, 0 );
- stream = strm;
- }
- int libbzip_decompression :: readdata ( void* buf, int size, bool excpt )
- {
- int decompressed = 0;
- char* cbuf = (char*) buf;
- data->bzs.next_in = cbuf ;
- data->bzs.avail_in = size ;
- data->bzs.total_in_lo32 = 0 ;
- data->bzs.total_in_hi32 = 0 ;
- int abrt = 0;
- while ( decompressed < size && !abrt ) {
- if ( data->inputbufread >= data->inputbufused ) {
- data->inputbufused = stream->readcmpdata ( data->inputbuf, data->inputbufsize, 0 );
- if ( !data->inputbufused && excpt )
- throw StreamCompressionError ( "Decompressor :: out of data", 0 );
- for ( int i = 0; i < data->inputbufused; i++ )
- data->inputbuf[i] ^= bzip_xor_byte;
- data->inputbufread = 0;
- }
- data->bzs.next_in = data->inputbuf + data->inputbufread;
- data->bzs.avail_in = data->inputbufused - data->inputbufread;
- data->bzs.total_in_lo32 = 0;
- data->bzs.total_in_hi32 = 0;
- data->bzs.next_out = cbuf + decompressed;
- data->bzs.avail_out = size - decompressed;
- data->bzs.total_out_lo32 = 0;
- data->bzs.total_out_hi32 = 0;
- int res = BZ2_bzDecompress ( &data->bzs );
- decompressed += data->bzs.total_out_lo32;
- data->inputbufread += data->bzs.total_in_lo32;
- if ( decompressed < size ) {
- if ( res == BZ_STREAM_END ) {
- if ( excpt )
- throw treadafterend ( "BZ_decompress_stream" );
- abrt = 1;
- } else {
- if ( res != BZ_OK ) {
- if ( excpt ) {
- if ( res == BZ_MEM_ERROR )
- throw OutOfMemoryError ( -1 );
- else
- throw StreamCompressionError ( "MBZLB2 decompression :: readdata", res );
- }
- abrt = 1;
- }
- }
- }
- }
- return decompressed;
- }
- libbzip_decompression :: ~libbzip_decompression ( )
- {
- delete data;
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /*
- t_compressor_2ndbuf_filter :: t_compressor_2ndbuf_filter ( t_compressor_stream_interface* strm )
- {
- stream = strm;
- }
- void t_compressor_2ndbuf_filter :: writecmpdata ( const void* buf, int size )
- {
- stream->writecmpdata ( buf, size );
- }
- int t_compressor_2ndbuf_filter :: readcmpdata ( void* buf, int size, bool excpt )
- {
- int got = 0;
- char* pc = (char*) buf;
- while ( size && _queue.size() ) {
- *pc = _queue.front();
- _queue.pop();
- pc++;
- size--;
- got++;
- }
- if ( size )
- got += stream->readcmpdata ( pc, size, excpt );
- return got;
- }
- void t_compressor_2ndbuf_filter :: insert_data_into_queue ( const void* buf, int size )
- {
- char* pc = (char*) buf;
- for (int i = 0; i < size; i++) {
- _queue.push ( *pc );
- pc++;
- }
- }
- */
- tanycompression :: tanycompression ( int md )
- {
- mmd = md;
- bzip_compress = NULL;
- bzip_decompress = NULL;
- }
- void tanycompression :: init ( void )
- {
- if ( mmd == 1 ) {
- char buf[10];
- int maxlen = strlen ( BZIP_SIGNATURE ) + 1;
- int bufdatanum = readcmpdata ( buf, maxlen, 0 );
- int siglen = 0;
- if ( bufdatanum == maxlen ) {
- if ( strncmp ( &buf[1], LZ_SIGNATURE, 9 ) == 0 && !buf[0]) {
- status = 110;
- siglen = 0;
- } else
- if ( strncmp ( &buf[1], RLE_SIGNATURE, 9 ) == 0 && !buf[0]) {
- status = 111;
- siglen = 0;
- } else
- if ( strncmp ( buf, BZIP_SIGNATURE, 9 ) == 0 ) {
- status = 112;
- siglen = strlen ( BZIP_SIGNATURE ) + 1;
- bzip_decompress = new libbzip_decompression ( this );
- } else
- status= 109;
- } else
- status = 109;
- for ( int i = siglen; i < bufdatanum; i++ )
- _queue.push ( buf[i] );
- } else {
- status = 201;
- bzip_compress = new libbzip_compression ( this );
- writecmpdata ( BZIP_SIGNATURE, strlen ( BZIP_SIGNATURE ) + 1 );
- }
- }
- int tanycompression :: readdata ( void* rbuf, int size, bool excpt )
- {
- int red = 0;
- if ( size ) {
- switch ( status ) {
- case 109: red += readlzwdata ( rbuf, size, excpt );
- break;
- case 110:
- case 111: red += tlzwstreamcompression :: readdata ( rbuf, size, excpt );
- break;
- case 112: red += bzip_decompress -> readdata ( rbuf, size, excpt );
- break;
- } /* endswitch */
- }
- return red;
- }
- void tanycompression :: writedata ( const void* buf, int size )
- {
- bzip_compress -> writedata ( buf, size );
- // writecmpdata ( buf, size );
- }
- int tanycompression :: readlzwdata ( void* buf, int size, bool excpt )
- {
- if ( _queue.size() ) {
- int got = 0;
- char* pc = (char*) buf;
- while ( size && _queue.size() ) {
- *pc = _queue.front();
- _queue.pop();
- pc++;
- size--;
- got++;
- } /* endwhile */
- if ( size )
- got += readcmpdata ( pc, size, excpt );
- return got;
- } else
- return readcmpdata ( buf, size, excpt );
- }
- void tanycompression :: writelzwdata ( const void* buf, int size )
- {
- writecmpdata ( buf, size );
- }
- void tanycompression :: close_compression ( void )
- {
- if ( bzip_compress ) {
- bzip_compress->close_compression ( );
- delete bzip_compress;
- bzip_compress = NULL;
- }
- }
- tanycompression :: ~tanycompression ( )
- {
- if ( bzip_decompress ) {
- delete bzip_decompress;
- bzip_decompress = NULL;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- /*
- void tn_lzw_bufstream :: writedata ( const void* buf, int size )
- {
- tlzwstreamcompression :: writedata ( buf, size );
- }
- int tn_lzw_bufstream :: readdata ( void* buf, int size, bool excpt )
- {
- return tlzwstreamcompression :: readdata ( buf, size, excpt );
- }
- int tn_lzw_bufstream :: readlzwdata ( void* buf, int size, bool excpt )
- {
- return tnbufstream :: readdata ( buf, size, excpt );
- }
- void tn_lzw_bufstream :: writelzwdata ( const void* buf, int size )
- {
- tnbufstream :: writedata ( buf, size );
- }
- tn_lzw_bufstream :: ~tn_lzw_bufstream ()
- {
- tlzwstreamcompression :: close();
- tnbufstream :: close();
- }
- */
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- void tn_lzw_file_buf_stream :: writedata ( const void* buf, int size )
- {
- tanycompression :: writedata ( buf, size );
- }
- int tn_lzw_file_buf_stream :: readdata ( void* buf, int size, bool excpt )
- {
- return tanycompression :: readdata ( buf, size, excpt );
- }
- int tn_lzw_file_buf_stream:: readcmpdata ( void* buf, int size, bool excpt )
- {
- return tn_file_buf_stream :: readdata ( buf, size, excpt );
- }
- void tn_lzw_file_buf_stream :: writecmpdata ( const void* buf, int size )
- {
- tn_file_buf_stream :: writedata ( buf, size );
- }
- tn_lzw_file_buf_stream :: ~tn_lzw_file_buf_stream()
- {
- close_compression ();
- tn_file_buf_stream :: close();
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- tn_c_lzw_filestream :: tn_c_lzw_filestream ( const ASCString& name, IOMode mode ) : tanycompression ( mode )
- {
- #ifdef logfiles
- FILE* fp = fopen ( "files.lst", "at" );
- fprintf ( fp, "%s\n", name );
- fclose ( fp );
- #endif
- strm = NULL;
- inp = 0;
- containerstream = NULL;
- FileLocation fl;
- if ( mode == tnstream::reading ) {
- locateFile ( name, &fl );
- if ( !fl.found )
- throw tfileerror ( name );
- } else {
- fl.directoryLevel = 0;
- fl.container = NULL;
- }
- if ( fl.container == NULL ) {
- char string[2000];
- ASCString fileNameComplete = constructFileName ( string, fl.directoryLevel, NULL, name.c_str());
- strm = new tn_file_buf_stream ( fileNameComplete, mode );
- inp = 1;
- devicename = fileNameComplete;
- location = fileNameComplete;
- } else {
- containerstream = fl.container;
- if ( containerstream ) {
- inp = 2;
- containerstream->opencontainerfile ( name.c_str() );
- devicename = name;
- location = name + " located inside " + containerstream->getDeviceName();
- } else
- throw tfileerror ( name );
- }
- fname = name;
- tanycompression :: init ( );
- }
- ASCString tn_c_lzw_filestream::getArchive()
- {
- if ( containerstream )
- return containerstream->getDeviceName();
- else
- return "";
- }
- ASCString tn_c_lzw_filestream::getLocation()
- {
- return location;
- }
- int tn_c_lzw_filestream :: getSize ( void )
- {
- if ( inp == 2 )
- return containerstream->getSize();
- else
- return strm->getSize();
- }
- void tn_c_lzw_filestream :: writecmpdata ( const void* buf, int size )
- {
- if ( inp == 2 )
- throw tinvalidmode ( fname, tnstream::reading, tnstream::writing );
- else
- strm->writedata ( buf, size );
- }
- int tn_c_lzw_filestream :: readcmpdata ( void* buf, int size, bool excpt )
- {
- if ( inp == 2 )
- return containerstream->readcontainerdata ( buf, size, excpt );
- else
- return strm->readdata ( buf, size, excpt );
- };
- void tn_c_lzw_filestream :: writedata ( const void* buf, int size )
- {
- tanycompression :: writedata ( buf, size );
- }
- int tn_c_lzw_filestream :: readdata ( void* buf, int size, bool excpt )
- {
- if ( tanycompression :: mode == readingdirect && !tempbuf.size() )
- if ( inp == 2 )
- return containerstream->readcontainerdata ( buf, size, excpt );
- else
- return strm->readdata ( buf, size, excpt );
- else
- return tanycompression :: readdata ( buf, size, excpt );
- };
- time_t tn_c_lzw_filestream :: get_time ( void )
- {
- if ( inp == 2 )
- return containerstream->get_time();
- else
- return strm->get_time();
- }
- tn_c_lzw_filestream :: ~tn_c_lzw_filestream()
- {
- try {
- displayLogMessage( 9, "~tn_c_lzw_filestream " + getLocation() );
-
- close_compression ();
- close();
- if ( inp == 1 ) {
- delete strm;
- strm = NULL;
- } else {
- displayLogMessage( 9, ASCString("~tn_c_lzw_filestream -> closecontainerfile ") );
- containerstream->closecontainerfile();
- }
- } catch ( ... ) {
- displayLogMessage( 9, ASCString("~tn_c_lzw_filestream : caught exception") );
- throw;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- static const char asciiCodingTable[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
- 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
- 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
- 'w', 'x', 'y', 'z', '0', '1', '2', '3',
- '4', '5', '6', '7', '8', '9', '+', '/' };
- ASCIIEncodingStream::ASCIIEncodingStream() : shift(0), buf(0) {};
- void ASCIIEncodingStream::writedata ( const void* buf, int size ) {
- const char* c = (const char*)buf;
- for ( int i = 0; i < size; ++i )
- put ( c[i] );
- }
- int ASCIIEncodingStream::readdata ( void* buf, int size, bool excpt ) {
- throw tinvalidmode ( "Base64SerializingStream", reading, writing );
- }
- void ASCIIEncodingStream::put( char c )
- {
- if ( shift == 0 ) {
- buf = c >> 6;
- shift = 2;
- result += asciiCodingTable[c & 63];
- } else if ( shift == 2 ) {
- buf |= ( c << 2) & 63;
- result += asciiCodingTable[buf];
- buf = c >> 4;
- shift = 4;
- } else if ( shift==4 ) {
- buf |= (c << 4) & 63;
- result += asciiCodingTable[buf];
- shift = 0;
- result += asciiCodingTable[int((c>>2) & 63)];
- }
- }
- void ASCIIEncodingStream::flush() {
- if ( shift )
- result += asciiCodingTable[buf & 63];
- result += "#";
- }
- ASCString ASCIIEncodingStream::getResult()
- {
- flush();
- return result;
- }
- void ASCIIDecodingStream :: generateTable()
- {
- for ( int i = 0; i< 256; ++i )
- reverse[i] = -1;
- for ( int i = 0; i < sizeof(asciiCodingTable); ++i )
- reverse[ int(asciiCodingTable[i])] = i;
- }
- int ASCIIDecodingStream :: get()
- {
- if ( length < data.length() ) {
- int c = data.at(length);
- if ( c == '#' )
- throw treadafterend("ASCIIDecodingStream");
- ++length;
- if ( reverse[c] == -1 )
- throw ASCmsgException("Invalid ASCII data to decode");
- return reverse[c];
- } else
- throw treadafterend("ASCIIDecodingStream");
- }
- ASCIIDecodingStream :: ASCIIDecodingStream( const ASCString& data) : shift(0), buf(0), length(0)
- {
- this->data = data;
- generateTable();
- }
- void ASCIIDecodingStream :: writedata ( const void* buf, int size )
- {
- throw tinvalidmode ( "ASCIIDecodingStream", writing, reading );
- }
- int ASCIIDecodingStream :: readdata ( void* buffer, int size, bool excpt )
- {
- int i = 0;
- try {
- char* cbuf = (char*) buffer;
- for ( i = 0; i < size; ++i ) {
- if ( shift == 0 ) {
- char c = get();
- char c2 = get();
- cbuf[i] = c | ((c2 << 6) & 0xff);
- shift = 2;
- buf = c2 >> 2;
- } else if ( shift == 2 ) {
- char c = get();
- cbuf[i] = buf | ((c << 4) & 0xff );
- buf = c >> 4;
- shift = 4;
- } else if ( shift == 4 ) {
- char c = get();
- cbuf[i] = buf | (c << 2 );
- shift = 0;
- }
- }
- }
- catch ( treadafterend trae ) {
- if ( excpt )
- throw trae;
- }
- return i;
- }
- StreamCompressionFilter :: StreamCompressionFilter( tnstream* outputstream )
- : adapter( outputstream), compressor( &adapter ), closed(false) {
- }
- void StreamCompressionFilter :: writedata ( const void* buf, int size )
- {
- compressor.writedata(buf,size);
- }
- int StreamCompressionFilter :: readdata ( void* buf, int size, bool excpt )
- {
- throw tinvalidmode ( "StreamCompressionFilter", reading, writing );
- }
- void StreamCompressionFilter :: close()
- {
- if ( closed )
- return;
- compressor.close_compression();
- closed = true;
- }
- StreamCompressionFilter ::~StreamCompressionFilter()
- {
- close();
- }
- StreamDecompressionFilter :: StreamDecompressionFilter( tnstream* inputstream ) : adapter( inputstream), decompressor( &adapter ) {
- }
- void StreamDecompressionFilter :: writedata ( const void* buf, int size )
- {
- throw tinvalidmode ( "StreamCompressionFilter", writing, reading );
- }
- int StreamDecompressionFilter :: readdata ( void* buf, int size, bool excpt )
- {
- return decompressor.readdata(buf,size,excpt);
- }
- ////////////////////////////////////////////////////////////////////////////////////////
- int compressrle ( const void* p, void* q)
- {
- trleheader* sourcehead = (trleheader*) p;
- if ( sourcehead->id == 16973 ) {
- memcpy ( q, p, sourcehead->size + sizeof ( trleheader ) );
- return sourcehead->size + sizeof ( trleheader );
- }
- char* s = (char*) p;
- char* d = (char*) q;
- trleheader* header = (trleheader*) q;
- Uint16 x,y;
- int size;
- {
- Uint16* pw = (Uint16*) s;
- x = pw[0];
- y = pw[1];
- header->x = x;
- header->y = y;
- x++;
- y++;
- size = x * y;
- header->id = 16973;
- }
- {
- int bts[256];
- memset ( bts, 0, sizeof ( bts ));
- for ( int i = 0; i < size ;i++ )
- bts[int(s[i+4])]++;
- int min = 70000;
- for ( int i = 0; i < 256; i++ )
- if ( bts[i] < min ) {
- min = bts[i];
- header->rle = i;
- }
- }
- s+=4;
- d+=sizeof ( trleheader );
- {
- char* startpos = d;
- int xp;
- for (int j = 0; j < y ; j++ ) {
- xp = 0;
- unsigned char num;
- unsigned char actbyte ;
- do {
- num = 1;
- actbyte = *s;
-
- while ( xp+num < x && num < 255 && s[num] == actbyte )
- num++;
-
- if ( num > 2 || actbyte == header->rle ) {
- *(d++) = header->rle;
- *(d++) = num;
- *(d++) = actbyte;
- } else {
- *(d++) = actbyte;
- if ( num > 1 )
- *(d++) = actbyte;
- }
- s += num;
- xp += num;
- } while ( xp < x );
- } /* endfor */
- header->size = d - startpos;
- }
- return header->size + sizeof ( trleheader );
- }
- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- bool patimat (const char *pat, const char *str, bool forceCaseInsensitivity )
- {
- switch (*pat)
- {
- case '\0':
- return !*str;
- case '*' :
- return patimat(pat+1, str, forceCaseInsensitivity) || (*str && patimat(pat, str+1, forceCaseInsensitivity));
- case '?' :
- return *str && patimat(pat+1, str+1, forceCaseInsensitivity);
- default :
- if ( forceCaseInsensitivity ||
- #if CASE_SENSITIVE_FILE_NAMES == 0
- true
- #else
- false
- #endif
- )
- return (toupper(*pat) == toupper(*str)) && patimat(pat+1, str+1, forceCaseInsensitivity);
- else
- return (*pat == *str) && patimat(pat+1, str+1, forceCaseInsensitivity );
- }
- }
- bool patimat (const ASCString& pat, const ASCString& str, bool forceCaseInsensitivity)
- {
- return patimat( pat.c_str(), str.c_str(), forceCaseInsensitivity );
- }
- tfindfile :: tfindfile ( ASCString name, SearchPosition searchPosition, SearchTypes searchTypes )
- {
- convertPathDelimitters ( name );
- if ( searchPosition == DefaultDir )
- searchPosition = AllDirs;
-
- if ( searchDirNum == 0 )
- searchPosition = CurrentDir;
-
- found = 0;
- act = 0;
- if ( name.empty() )
- return;
- ASCString directory[maxSearchDirNum];
- int dirNum;
- ASCString wildcard;
- int ppos = name.rfind ( pathdelimitterstring );
- if ( ppos != name.npos ) {
- // name contains a directory entry
- // checking if absolute or relative path
- bool absolute = false;
- if ( name[0] == pathdelimitter )
- absolute = true;
- if ( has_drive_letters && name.length() > 3 && name.find ( ":\\", 1 ) != name.npos )
- absolute = true;
- if ( absolute || searchPosition == CurrentDir ) {
- directory[0].assign ( name, 0, ppos );
- dirNum = 1;
- } else {
- ASCString strippedPath;
- strippedPath.assign ( name, 0, ppos );
- if ( strippedPath.find ( ASCString(".") + pathdelimitterstring ) == 0 )
- strippedPath.erase( 0, 2);
- int upDir = 0;
- while ( strippedPath.find ( ASCString("..") + pathdelimitterstring ) == 0 ) {
- upDir++;
- strippedPath.erase ( 0, 3 );
- }
- int dirsToProcess;
- if ( searchPosition == AllDirs ) {
- dirsToProcess = searchDirNum;
- } else
- dirsToProcess = 1;
- dirNum = 0;
- for ( int i = 0; i < dirsToProcess; i++ ) {
- ASCString dir = ascDirectory[i];
- // removing the trailing pathdelimitterstring
- dir.erase ( dir.length() -1 );
- for ( int j = 0; j < upDir; j++ ) {
- int pos = dir.rfind ( pathdelimitterstring );
- if ( pos > 0 && pos == dir.npos )
- dir.erase ( pos );
- }
- // append the trailing pathdelimitterstring again
- dir += pathdelimitterstring;
- directory[dirNum++] = dir + strippedPath;
- }
- if ( !dirNum ) {
- directory[0] = ".";
- dirNum = 1;
- }
- }
- wildcard.assign ( name, ppos+1, name.npos );
- } else {
- if ( searchDirNum ) {
- for (int i = 0; i < searchDirNum; i++ )
- directory[i] = ascDirectory[i];
- dirNum = searchDirNum;
- } else {
- directory[0] = ".";
- dirNum = 1;
- }
- wildcard = name;
- }
- if ( searchTypes == All || searchTypes == OutsideContainer )
- for ( int i = 0; i < dirNum; i++ ) {
- DIR *dirp;
- struct ASC_direct *direntp;
- dirp = opendir( directory[i].c_str() );
- if( dirp != NULL ) {
- for(;;) {
- direntp = readdir( dirp );
- if ( direntp == NULL )
- break;
-
- if ( patimat ( wildcard.c_str(), direntp->d_name )) {
- int localfound = 0;
- …
Large files files are truncated, but you can click here to view the full file