123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809 |
- /*
- ===========================================================================
- Doom 3 BFG Edition GPL Source Code
- Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
- Doom 3 BFG Edition Source Code 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 3 of the License, or
- (at your option) any later version.
- Doom 3 BFG Edition Source Code 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 Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- #include "Unzip.h"
- /*
- =================
- FS_WriteFloatString
- =================
- */
- int FS_WriteFloatString( char *buf, const char *fmt, va_list argPtr ) {
- long i;
- unsigned long u;
- double f;
- char *str;
- int index;
- idStr tmp, format;
- index = 0;
- while( *fmt ) {
- switch( *fmt ) {
- case '%':
- format = "";
- format += *fmt++;
- while ( (*fmt >= '0' && *fmt <= '9') ||
- *fmt == '.' || *fmt == '-' || *fmt == '+' || *fmt == '#') {
- format += *fmt++;
- }
- format += *fmt;
- switch( *fmt ) {
- case 'f':
- case 'e':
- case 'E':
- case 'g':
- case 'G':
- f = va_arg( argPtr, double );
- if ( format.Length() <= 2 ) {
- // high precision floating point number without trailing zeros
- sprintf( tmp, "%1.10f", f );
- tmp.StripTrailing( '0' );
- tmp.StripTrailing( '.' );
- index += sprintf( buf+index, "%s", tmp.c_str() );
- }
- else {
- index += sprintf( buf+index, format.c_str(), f );
- }
- break;
- case 'd':
- case 'i':
- i = va_arg( argPtr, long );
- index += sprintf( buf+index, format.c_str(), i );
- break;
- case 'u':
- u = va_arg( argPtr, unsigned long );
- index += sprintf( buf+index, format.c_str(), u );
- break;
- case 'o':
- u = va_arg( argPtr, unsigned long );
- index += sprintf( buf+index, format.c_str(), u );
- break;
- case 'x':
- u = va_arg( argPtr, unsigned long );
- index += sprintf( buf+index, format.c_str(), u );
- break;
- case 'X':
- u = va_arg( argPtr, unsigned long );
- index += sprintf( buf+index, format.c_str(), u );
- break;
- case 'c':
- i = va_arg( argPtr, long );
- index += sprintf( buf+index, format.c_str(), (char) i );
- break;
- case 's':
- str = va_arg( argPtr, char * );
- index += sprintf( buf+index, format.c_str(), str );
- break;
- case '%':
- index += sprintf( buf+index, format.c_str() ); //-V618
- break;
- default:
- common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() );
- break;
- }
- fmt++;
- break;
- case '\\':
- fmt++;
- switch( *fmt ) {
- case 't':
- index += sprintf( buf+index, "\t" );
- break;
- case 'v':
- index += sprintf( buf+index, "\v" );
- break;
- case 'n':
- index += sprintf( buf+index, "\n" );
- break;
- case '\\':
- index += sprintf( buf+index, "\\" );
- break;
- default:
- common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt );
- break;
- }
- fmt++;
- break;
- default:
- index += sprintf( buf+index, "%c", *fmt );
- fmt++;
- break;
- }
- }
- return index;
- }
- /*
- =================================================================================
- idFile
- =================================================================================
- */
- /*
- =================
- idFile::GetName
- =================
- */
- const char *idFile::GetName() const {
- return "";
- }
- /*
- =================
- idFile::GetFullPath
- =================
- */
- const char *idFile::GetFullPath() const {
- return "";
- }
- /*
- =================
- idFile::Read
- =================
- */
- int idFile::Read( void *buffer, int len ) {
- common->FatalError( "idFile::Read: cannot read from idFile" );
- return 0;
- }
- /*
- =================
- idFile::Write
- =================
- */
- int idFile::Write( const void *buffer, int len ) {
- common->FatalError( "idFile::Write: cannot write to idFile" );
- return 0;
- }
- /*
- =================
- idFile::Length
- =================
- */
- int idFile::Length() const {
- return 0;
- }
- /*
- =================
- idFile::Timestamp
- =================
- */
- ID_TIME_T idFile::Timestamp() const {
- return 0;
- }
- /*
- =================
- idFile::Tell
- =================
- */
- int idFile::Tell() const {
- return 0;
- }
- /*
- =================
- idFile::ForceFlush
- =================
- */
- void idFile::ForceFlush() {
- }
- /*
- =================
- idFile::Flush
- =================
- */
- void idFile::Flush() {
- }
- /*
- =================
- idFile::Seek
- =================
- */
- int idFile::Seek( long offset, fsOrigin_t origin ) {
- return -1;
- }
- /*
- =================
- idFile::Rewind
- =================
- */
- void idFile::Rewind() {
- Seek( 0, FS_SEEK_SET );
- }
- /*
- =================
- idFile::Printf
- =================
- */
- int idFile::Printf( const char *fmt, ... ) {
- char buf[MAX_PRINT_MSG];
- int length;
- va_list argptr;
- va_start( argptr, fmt );
- length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, argptr );
- va_end( argptr );
- // so notepad formats the lines correctly
- idStr work( buf );
- work.Replace( "\n", "\r\n" );
-
- return Write( work.c_str(), work.Length() );
- }
- /*
- =================
- idFile::VPrintf
- =================
- */
- int idFile::VPrintf( const char *fmt, va_list args ) {
- char buf[MAX_PRINT_MSG];
- int length;
- length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, args );
- return Write( buf, length );
- }
- /*
- =================
- idFile::WriteFloatString
- =================
- */
- int idFile::WriteFloatString( const char *fmt, ... ) {
- char buf[MAX_PRINT_MSG];
- int len;
- va_list argPtr;
- va_start( argPtr, fmt );
- len = FS_WriteFloatString( buf, fmt, argPtr );
- va_end( argPtr );
- return Write( buf, len );
- }
- /*
- =================
- idFile::ReadInt
- =================
- */
- int idFile::ReadInt( int &value ) {
- int result = Read( &value, sizeof( value ) );
- value = LittleLong(value);
- return result;
- }
- /*
- =================
- idFile::ReadUnsignedInt
- =================
- */
- int idFile::ReadUnsignedInt( unsigned int &value ) {
- int result = Read( &value, sizeof( value ) );
- value = LittleLong(value);
- return result;
- }
- /*
- =================
- idFile::ReadShort
- =================
- */
- int idFile::ReadShort( short &value ) {
- int result = Read( &value, sizeof( value ) );
- value = LittleShort(value);
- return result;
- }
- /*
- =================
- idFile::ReadUnsignedShort
- =================
- */
- int idFile::ReadUnsignedShort( unsigned short &value ) {
- int result = Read( &value, sizeof( value ) );
- value = LittleShort(value);
- return result;
- }
- /*
- =================
- idFile::ReadChar
- =================
- */
- int idFile::ReadChar( char &value ) {
- return Read( &value, sizeof( value ) );
- }
- /*
- =================
- idFile::ReadUnsignedChar
- =================
- */
- int idFile::ReadUnsignedChar( unsigned char &value ) {
- return Read( &value, sizeof( value ) );
- }
- /*
- =================
- idFile::ReadFloat
- =================
- */
- int idFile::ReadFloat( float &value ) {
- int result = Read( &value, sizeof( value ) );
- value = LittleFloat(value);
- return result;
- }
- /*
- =================
- idFile::ReadBool
- =================
- */
- int idFile::ReadBool( bool &value ) {
- unsigned char c;
- int result = ReadUnsignedChar( c );
- value = c ? true : false;
- return result;
- }
- /*
- =================
- idFile::ReadString
- =================
- */
- int idFile::ReadString( idStr &string ) {
- int len;
- int result = 0;
-
- ReadInt( len );
- if ( len >= 0 ) {
- string.Fill( ' ', len );
- result = Read( &string[ 0 ], len );
- }
- return result;
- }
- /*
- =================
- idFile::ReadVec2
- =================
- */
- int idFile::ReadVec2( idVec2 &vec ) {
- int result = Read( &vec, sizeof( vec ) );
- LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
- return result;
- }
- /*
- =================
- idFile::ReadVec3
- =================
- */
- int idFile::ReadVec3( idVec3 &vec ) {
- int result = Read( &vec, sizeof( vec ) );
- LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
- return result;
- }
- /*
- =================
- idFile::ReadVec4
- =================
- */
- int idFile::ReadVec4( idVec4 &vec ) {
- int result = Read( &vec, sizeof( vec ) );
- LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
- return result;
- }
- /*
- =================
- idFile::ReadVec6
- =================
- */
- int idFile::ReadVec6( idVec6 &vec ) {
- int result = Read( &vec, sizeof( vec ) );
- LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
- return result;
- }
- /*
- =================
- idFile::ReadMat3
- =================
- */
- int idFile::ReadMat3( idMat3 &mat ) {
- int result = Read( &mat, sizeof( mat ) );
- LittleRevBytes( &mat, sizeof(float), sizeof(mat)/sizeof(float) );
- return result;
- }
- /*
- =================
- idFile::WriteInt
- =================
- */
- int idFile::WriteInt( const int value ) {
- int v = LittleLong(value);
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteUnsignedInt
- =================
- */
- int idFile::WriteUnsignedInt( const unsigned int value ) {
- unsigned int v = LittleLong(value);
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteShort
- =================
- */
- int idFile::WriteShort( const short value ) {
- short v = LittleShort(value);
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteUnsignedShort
- =================
- */
- int idFile::WriteUnsignedShort( const unsigned short value ) {
- unsigned short v = LittleShort(value);
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteChar
- =================
- */
- int idFile::WriteChar( const char value ) {
- return Write( &value, sizeof( value ) );
- }
- /*
- =================
- idFile::WriteUnsignedChar
- =================
- */
- int idFile::WriteUnsignedChar( const unsigned char value ) {
- return Write( &value, sizeof( value ) );
- }
- /*
- =================
- idFile::WriteFloat
- =================
- */
- int idFile::WriteFloat( const float value ) {
- float v = LittleFloat(value);
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteBool
- =================
- */
- int idFile::WriteBool( const bool value ) {
- unsigned char c = value;
- return WriteUnsignedChar( c );
- }
- /*
- =================
- idFile::WriteString
- =================
- */
- int idFile::WriteString( const char *value ) {
- int len = strlen( value );
- WriteInt( len );
- return Write( value, len );
- }
- /*
- =================
- idFile::WriteVec2
- =================
- */
- int idFile::WriteVec2( const idVec2 &vec ) {
- idVec2 v = vec;
- LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteVec3
- =================
- */
- int idFile::WriteVec3( const idVec3 &vec ) {
- idVec3 v = vec;
- LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteVec4
- =================
- */
- int idFile::WriteVec4( const idVec4 &vec ) {
- idVec4 v = vec;
- LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteVec6
- =================
- */
- int idFile::WriteVec6( const idVec6 &vec ) {
- idVec6 v = vec;
- LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
- return Write( &v, sizeof( v ) );
- }
- /*
- =================
- idFile::WriteMat3
- =================
- */
- int idFile::WriteMat3( const idMat3 &mat ) {
- idMat3 v = mat;
- LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
- return Write( &v, sizeof( v ) );
- }
- /*
- =================================================================================
- idFile_Memory
- =================================================================================
- */
- /*
- =================
- idFile_Memory::idFile_Memory
- =================
- */
- idFile_Memory::idFile_Memory() {
- name = "*unknown*";
- maxSize = 0;
- fileSize = 0;
- allocated = 0;
- granularity = 16384;
- mode = ( 1 << FS_WRITE );
- filePtr = NULL;
- curPtr = NULL;
- }
- /*
- =================
- idFile_Memory::idFile_Memory
- =================
- */
- idFile_Memory::idFile_Memory( const char *name ) {
- this->name = name;
- maxSize = 0;
- fileSize = 0;
- allocated = 0;
- granularity = 16384;
- mode = ( 1 << FS_WRITE );
- filePtr = NULL;
- curPtr = NULL;
- }
- /*
- =================
- idFile_Memory::idFile_Memory
- =================
- */
- idFile_Memory::idFile_Memory( const char *name, char *data, int length ) {
- this->name = name;
- maxSize = length;
- fileSize = 0;
- allocated = length;
- granularity = 16384;
- mode = ( 1 << FS_WRITE );
- filePtr = data;
- curPtr = data;
- }
- /*
- =================
- idFile_Memory::idFile_Memory
- =================
- */
- idFile_Memory::idFile_Memory( const char *name, const char *data, int length ) {
- this->name = name;
- maxSize = 0;
- fileSize = length;
- allocated = 0;
- granularity = 16384;
- mode = ( 1 << FS_READ );
- filePtr = const_cast<char *>(data);
- curPtr = const_cast<char *>(data);
- }
- /*
- =================
- idFile_Memory::TakeDataOwnership
- this also makes the file read only
- =================
- */
- void idFile_Memory::TakeDataOwnership() {
- if ( filePtr != NULL && fileSize > 0 ) {
- maxSize = 0;
- mode = ( 1 << FS_READ );
- allocated = fileSize;
- }
- }
- /*
- =================
- idFile_Memory::~idFile_Memory
- =================
- */
- idFile_Memory::~idFile_Memory() {
- if ( filePtr && allocated > 0 && maxSize == 0 ) {
- Mem_Free( filePtr );
- }
- }
- /*
- =================
- idFile_Memory::Read
- =================
- */
- int idFile_Memory::Read( void *buffer, int len ) {
- if ( !( mode & ( 1 << FS_READ ) ) ) {
- common->FatalError( "idFile_Memory::Read: %s not opened in read mode", name.c_str() );
- return 0;
- }
- if ( curPtr + len > filePtr + fileSize ) {
- len = filePtr + fileSize - curPtr;
- }
- memcpy( buffer, curPtr, len );
- curPtr += len;
- return len;
- }
- idCVar memcpyImpl( "memcpyImpl", "0", 0, "Which implementation of memcpy to use for idFile_Memory::Write() [0/1 - standard (1 eliminates branch misprediction), 2 - auto-vectorized]" );
- void * memcpy2( void * __restrict b, const void * __restrict a, size_t n ) {
- char * s1 = (char *)b;
- const char * s2 = (const char *)a;
- for ( ; 0 < n; --n ) {
- *s1++ = *s2++;
- }
- return b;
- }
- /*
- =================
- idFile_Memory::Write
- =================
- */
- idHashTableT< int, int > histogram;
- CONSOLE_COMMAND( outputHistogram, "", 0 ) {
- for ( int i = 0; i < histogram.Num(); i++ ) {
- int key;
- histogram.GetIndexKey( i, key );
- int * value = histogram.GetIndex( i );
- idLib::Printf( "%d\t%d\n", key, *value );
- }
- }
- CONSOLE_COMMAND( clearHistogram, "", 0 ) {
- histogram.Clear();
- }
- int idFile_Memory::Write( const void *buffer, int len ) {
- if ( len == 0 ) {
- // ~4% falls into this case for some reason...
- return 0;
- }
- if ( !( mode & ( 1 << FS_WRITE ) ) ) {
- common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
- return 0;
- }
- int alloc = curPtr + len + 1 - filePtr - allocated; // need room for len+1
- if ( alloc > 0 ) {
- if ( maxSize != 0 ) {
- common->Error( "idFile_Memory::Write: exceeded maximum size %d", maxSize );
- return 0;
- }
- int extra = granularity * ( 1 + alloc / granularity );
- char *newPtr = (char *) Mem_Alloc( allocated + extra, TAG_IDFILE );
- if ( allocated ) {
- memcpy( newPtr, filePtr, allocated );
- }
- allocated += extra;
- curPtr = newPtr + ( curPtr - filePtr );
- if ( filePtr ) {
- Mem_Free( filePtr );
- }
- filePtr = newPtr;
- }
- //memcpy( curPtr, buffer, len );
- memcpy2( curPtr, buffer, len );
- #if 0
- if ( memcpyImpl.GetInteger() == 0 ) {
- memcpy( curPtr, buffer, len );
- } else if ( memcpyImpl.GetInteger() == 1 ) {
- memcpy( curPtr, buffer, len );
- } else if ( memcpyImpl.GetInteger() == 2 ) {
- memcpy2( curPtr, buffer, len );
- }
- #endif
- #if 0
- int * value;
- if ( histogram.Get( len, &value ) && value != NULL ) {
- (*value)++;
- } else {
- histogram.Set( len, 1 );
- }
- #endif
- curPtr += len;
- fileSize += len;
- filePtr[ fileSize ] = 0; // len + 1
- return len;
- }
- /*
- =================
- idFile_Memory::Length
- =================
- */
- int idFile_Memory::Length() const {
- return fileSize;
- }
- /*
- ========================
- idFile_Memory::SetLength
- ========================
- */
- void idFile_Memory::SetLength( size_t len ) {
- PreAllocate( len );
- fileSize = len;
- }
- /*
- ========================
- idFile_Memory::PreAllocate
- ========================
- */
- void idFile_Memory::PreAllocate( size_t len ) {
- if ( len > allocated ) {
- if ( maxSize != 0 ) {
- idLib::Error( "idFile_Memory::SetLength: exceeded maximum size %d", maxSize );
- }
- char * newPtr = (char *)Mem_Alloc( len, TAG_IDFILE );
- if ( allocated > 0 ) {
- memcpy( newPtr, filePtr, allocated );
- }
- allocated = len;
- curPtr = newPtr + ( curPtr - filePtr );
- if ( filePtr != NULL ) {
- Mem_Free( filePtr );
- }
- filePtr = newPtr;
- }
- }
- /*
- =================
- idFile_Memory::Timestamp
- =================
- */
- ID_TIME_T idFile_Memory::Timestamp() const {
- return 0;
- }
- /*
- =================
- idFile_Memory::Tell
- =================
- */
- int idFile_Memory::Tell() const {
- return ( curPtr - filePtr );
- }
- /*
- =================
- idFile_Memory::ForceFlush
- =================
- */
- void idFile_Memory::ForceFlush() {
- }
- /*
- =================
- idFile_Memory::Flush
- =================
- */
- void idFile_Memory::Flush() {
- }
- /*
- =================
- idFile_Memory::Seek
- returns zero on success and -1 on failure
- =================
- */
- int idFile_Memory::Seek( long offset, fsOrigin_t origin ) {
- switch( origin ) {
- case FS_SEEK_CUR: {
- curPtr += offset;
- break;
- }
- case FS_SEEK_END: {
- curPtr = filePtr + fileSize - offset;
- break;
- }
- case FS_SEEK_SET: {
- curPtr = filePtr + offset;
- break;
- }
- default: {
- common->FatalError( "idFile_Memory::Seek: bad origin for %s\n", name.c_str() );
- return -1;
- }
- }
- if ( curPtr < filePtr ) {
- curPtr = filePtr;
- return -1;
- }
- if ( curPtr > filePtr + fileSize ) {
- curPtr = filePtr + fileSize;
- return -1;
- }
- return 0;
- }
- /*
- ========================
- idFile_Memory::SetMaxLength
- ========================
- */
- void idFile_Memory::SetMaxLength( size_t len ) {
- size_t oldLength = fileSize;
- SetLength( len );
- maxSize = len;
- fileSize = oldLength;
- }
- /*
- =================
- idFile_Memory::MakeReadOnly
- =================
- */
- void idFile_Memory::MakeReadOnly() {
- mode = ( 1 << FS_READ );
- Rewind();
- }
- /*
- ========================
- idFile_Memory::MakeWritable
- ========================
- */
- void idFile_Memory::MakeWritable() {
- mode = ( 1 << FS_WRITE );
- Rewind();
- }
- /*
- =================
- idFile_Memory::Clear
- =================
- */
- void idFile_Memory::Clear( bool freeMemory ) {
- fileSize = 0;
- granularity = 16384;
- if ( freeMemory ) {
- allocated = 0;
- Mem_Free( filePtr );
- filePtr = NULL;
- curPtr = NULL;
- } else {
- curPtr = filePtr;
- }
- }
- /*
- =================
- idFile_Memory::SetData
- =================
- */
- void idFile_Memory::SetData( const char *data, int length ) {
- maxSize = 0;
- fileSize = length;
- allocated = 0;
- granularity = 16384;
- mode = ( 1 << FS_READ );
- filePtr = const_cast<char *>(data);
- curPtr = const_cast<char *>(data);
- }
- /*
- ========================
- idFile_Memory::TruncateData
- ========================
- */
- void idFile_Memory::TruncateData( size_t len ) {
- if ( len > allocated ) {
- idLib::Error( "idFile_Memory::TruncateData: len (%d) exceeded allocated size (%d)", len, allocated );
- } else {
- fileSize = len;
- }
- }
- /*
- =================================================================================
- idFile_BitMsg
- =================================================================================
- */
- /*
- =================
- idFile_BitMsg::idFile_BitMsg
- =================
- */
- idFile_BitMsg::idFile_BitMsg( idBitMsg &msg ) {
- name = "*unknown*";
- mode = ( 1 << FS_WRITE );
- this->msg = &msg;
- }
- /*
- =================
- idFile_BitMsg::idFile_BitMsg
- =================
- */
- idFile_BitMsg::idFile_BitMsg( const idBitMsg &msg ) {
- name = "*unknown*";
- mode = ( 1 << FS_READ );
- this->msg = const_cast<idBitMsg *>(&msg);
- }
- /*
- =================
- idFile_BitMsg::~idFile_BitMsg
- =================
- */
- idFile_BitMsg::~idFile_BitMsg() {
- }
- /*
- =================
- idFile_BitMsg::Read
- =================
- */
- int idFile_BitMsg::Read( void *buffer, int len ) {
- if ( !( mode & ( 1 << FS_READ ) ) ) {
- common->FatalError( "idFile_BitMsg::Read: %s not opened in read mode", name.c_str() );
- return 0;
- }
- return msg->ReadData( buffer, len );
- }
- /*
- =================
- idFile_BitMsg::Write
- =================
- */
- int idFile_BitMsg::Write( const void *buffer, int len ) {
- if ( !( mode & ( 1 << FS_WRITE ) ) ) {
- common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
- return 0;
- }
- msg->WriteData( buffer, len );
- return len;
- }
- /*
- =================
- idFile_BitMsg::Length
- =================
- */
- int idFile_BitMsg::Length() const {
- return msg->GetSize();
- }
- /*
- =================
- idFile_BitMsg::Timestamp
- =================
- */
- ID_TIME_T idFile_BitMsg::Timestamp() const {
- return 0;
- }
- /*
- =================
- idFile_BitMsg::Tell
- =================
- */
- int idFile_BitMsg::Tell() const {
- if ( mode == FS_READ ) {
- return msg->GetReadCount();
- } else {
- return msg->GetSize();
- }
- }
- /*
- =================
- idFile_BitMsg::ForceFlush
- =================
- */
- void idFile_BitMsg::ForceFlush() {
- }
- /*
- =================
- idFile_BitMsg::Flush
- =================
- */
- void idFile_BitMsg::Flush() {
- }
- /*
- =================
- idFile_BitMsg::Seek
- returns zero on success and -1 on failure
- =================
- */
- int idFile_BitMsg::Seek( long offset, fsOrigin_t origin ) {
- return -1;
- }
- /*
- =================================================================================
- idFile_Permanent
- =================================================================================
- */
- /*
- =================
- idFile_Permanent::idFile_Permanent
- =================
- */
- idFile_Permanent::idFile_Permanent() {
- name = "invalid";
- o = NULL;
- mode = 0;
- fileSize = 0;
- handleSync = false;
- }
- /*
- =================
- idFile_Permanent::~idFile_Permanent
- =================
- */
- idFile_Permanent::~idFile_Permanent() {
- if ( o ) {
- CloseHandle( o );
- }
- }
- /*
- =================
- idFile_Permanent::Read
- Properly handles partial reads
- =================
- */
- int idFile_Permanent::Read( void *buffer, int len ) {
- int block, remaining;
- int read;
- byte * buf;
- int tries;
- if ( !(mode & ( 1 << FS_READ ) ) ) {
- common->FatalError( "idFile_Permanent::Read: %s not opened in read mode", name.c_str() );
- return 0;
- }
- if ( !o ) {
- return 0;
- }
- buf = (byte *)buffer;
- remaining = len;
- tries = 0;
- while( remaining ) {
- block = remaining;
- DWORD bytesRead;
- if ( !ReadFile( o, buf, block, &bytesRead, NULL ) ) {
- idLib::Warning( "idFile_Permanent::Read failed with %d from %s", GetLastError(), name.c_str() );
- }
- read = bytesRead;
- if ( read == 0 ) {
- // we might have been trying to read from a CD, which
- // sometimes returns a 0 read on windows
- if ( !tries ) {
- tries = 1;
- }
- else {
- return len-remaining;
- }
- }
- if ( read == -1 ) {
- common->FatalError( "idFile_Permanent::Read: -1 bytes read from %s", name.c_str() );
- }
- remaining -= read;
- buf += read;
- }
- return len;
- }
- /*
- =================
- idFile_Permanent::Write
- Properly handles partial writes
- =================
- */
- int idFile_Permanent::Write( const void *buffer, int len ) {
- int block, remaining;
- int written;
- byte * buf;
- int tries;
- if ( !( mode & ( 1 << FS_WRITE ) ) ) {
- common->FatalError( "idFile_Permanent::Write: %s not opened in write mode", name.c_str() );
- return 0;
- }
- if ( !o ) {
- return 0;
- }
- buf = (byte *)buffer;
- remaining = len;
- tries = 0;
- while( remaining ) {
- block = remaining;
- DWORD bytesWritten;
- WriteFile( o, buf, block, &bytesWritten, NULL );
- written = bytesWritten;
- if ( written == 0 ) {
- if ( !tries ) {
- tries = 1;
- }
- else {
- common->Printf( "idFile_Permanent::Write: 0 bytes written to %s\n", name.c_str() );
- return 0;
- }
- }
- if ( written == -1 ) {
- common->Printf( "idFile_Permanent::Write: -1 bytes written to %s\n", name.c_str() );
- return 0;
- }
- remaining -= written;
- buf += written;
- fileSize += written;
- }
- if ( handleSync ) {
- Flush();
- }
- return len;
- }
- /*
- =================
- idFile_Permanent::ForceFlush
- =================
- */
- void idFile_Permanent::ForceFlush() {
- FlushFileBuffers( o );
- }
- /*
- =================
- idFile_Permanent::Flush
- =================
- */
- void idFile_Permanent::Flush() {
- FlushFileBuffers( o );
- }
- /*
- =================
- idFile_Permanent::Tell
- =================
- */
- int idFile_Permanent::Tell() const {
- return SetFilePointer( o, 0, NULL, FILE_CURRENT );
- }
- /*
- ================
- idFile_Permanent::Length
- ================
- */
- int idFile_Permanent::Length() const {
- return fileSize;
- }
- /*
- ================
- idFile_Permanent::Timestamp
- ================
- */
- ID_TIME_T idFile_Permanent::Timestamp() const {
- ID_TIME_T ts = Sys_FileTimeStamp( o );
- return ts;
- }
- /*
- =================
- idFile_Permanent::Seek
- returns zero on success and -1 on failure
- =================
- */
- int idFile_Permanent::Seek( long offset, fsOrigin_t origin ) {
- int retVal = INVALID_SET_FILE_POINTER;
- switch( origin ) {
- case FS_SEEK_CUR: retVal = SetFilePointer( o, offset, NULL, FILE_CURRENT ); break;
- case FS_SEEK_END: retVal = SetFilePointer( o, offset, NULL, FILE_END ); break;
- case FS_SEEK_SET: retVal = SetFilePointer( o, offset, NULL, FILE_BEGIN ); break;
- }
- return ( retVal == INVALID_SET_FILE_POINTER ) ? -1 : 0;
- }
- #if 1
- /*
- =================================================================================
- idFile_Cached
- =================================================================================
- */
- /*
- =================
- idFile_Cached::idFile_Cached
- =================
- */
- idFile_Cached::idFile_Cached() : idFile_Permanent() {
- internalFilePos = 0;
- bufferedStartOffset = 0;
- bufferedEndOffset = 0;
- buffered = NULL;
- }
- /*
- =================
- idFile_Cached::~idFile_Cached
- =================
- */
- idFile_Cached::~idFile_Cached() {
- Mem_Free( buffered );
- }
- /*
- =================
- idFile_ReadBuffered::BufferData
- Buffer a section of the file
- =================
- */
- void idFile_Cached::CacheData( uint64 offset, uint64 length ) {
- Mem_Free( buffered );
- bufferedStartOffset = offset;
- bufferedEndOffset = offset + length;
- buffered = ( byte* )Mem_Alloc( length, TAG_RESOURCE );
- if ( buffered == NULL ) {
- return;
- }
- int internalFilePos = idFile_Permanent::Tell();
- idFile_Permanent::Seek( offset, FS_SEEK_SET );
- idFile_Permanent::Read( buffered, length );
- idFile_Permanent::Seek( internalFilePos, FS_SEEK_SET );
- }
- /*
- =================
- idFile_ReadBuffered::Read
- =================
- */
- int idFile_Cached::Read( void *buffer, int len ) {
- if ( internalFilePos >= bufferedStartOffset && internalFilePos + len < bufferedEndOffset ) {
- // this is in the buffer
- memcpy( buffer, (void*)&buffered[ internalFilePos - bufferedStartOffset ], len );
- internalFilePos += len;
- return len;
- }
- int read = idFile_Permanent::Read( buffer, len );
- if ( read != -1 ) {
- internalFilePos += ( int64 )read;
- }
- return read;
- }
- /*
- =================
- idFile_Cached::Tell
- =================
- */
- int idFile_Cached::Tell() const {
- return internalFilePos;
- }
- /*
- =================
- idFile_Cached::Seek
- returns zero on success and -1 on failure
- =================
- */
- int idFile_Cached::Seek( long offset, fsOrigin_t origin ) {
- if ( origin == FS_SEEK_SET && offset >= bufferedStartOffset && offset < bufferedEndOffset ) {
- // don't do anything to the actual file ptr, just update or internal position
- internalFilePos = offset;
- return 0;
- }
- int retVal = idFile_Permanent::Seek( offset, origin );
- internalFilePos = idFile_Permanent::Tell();
- return retVal;
- }
- #endif
- /*
- =================================================================================
- idFile_InZip
- =================================================================================
- */
- /*
- =================
- idFile_InZip::idFile_InZip
- =================
- */
- idFile_InZip::idFile_InZip() {
- name = "invalid";
- zipFilePos = 0;
- fileSize = 0;
- memset( &z, 0, sizeof( z ) );
- }
- /*
- =================
- idFile_InZip::~idFile_InZip
- =================
- */
- idFile_InZip::~idFile_InZip() {
- unzCloseCurrentFile( z );
- unzClose( z );
- }
- /*
- =================
- idFile_InZip::Read
- Properly handles partial reads
- =================
- */
- int idFile_InZip::Read( void *buffer, int len ) {
- int l = unzReadCurrentFile( z, buffer, len );
- return l;
- }
- /*
- =================
- idFile_InZip::Write
- =================
- */
- int idFile_InZip::Write( const void *buffer, int len ) {
- common->FatalError( "idFile_InZip::Write: cannot write to the zipped file %s", name.c_str() );
- return 0;
- }
- /*
- =================
- idFile_InZip::ForceFlush
- =================
- */
- void idFile_InZip::ForceFlush() {
- common->FatalError( "idFile_InZip::ForceFlush: cannot flush the zipped file %s", name.c_str() );
- }
- /*
- =================
- idFile_InZip::Flush
- =================
- */
- void idFile_InZip::Flush() {
- common->FatalError( "idFile_InZip::Flush: cannot flush the zipped file %s", name.c_str() );
- }
- /*
- =================
- idFile_InZip::Tell
- =================
- */
- int idFile_InZip::Tell() const {
- return unztell( z );
- }
- /*
- ================
- idFile_InZip::Length
- ================
- */
- int idFile_InZip::Length() const {
- return fileSize;
- }
- /*
- ================
- idFile_InZip::Timestamp
- ================
- */
- ID_TIME_T idFile_InZip::Timestamp() const {
- return 0;
- }
- /*
- =================
- idFile_InZip::Seek
- returns zero on success and -1 on failure
- =================
- */
- #define ZIP_SEEK_BUF_SIZE (1<<15)
- int idFile_InZip::Seek( long offset, fsOrigin_t origin ) {
- int res, i;
- char *buf;
- switch( origin ) {
- case FS_SEEK_END: {
- offset = fileSize - offset;
- }
- case FS_SEEK_SET: {
- // set the file position in the zip file (also sets the current file info)
- unzSetCurrentFileInfoPosition( z, zipFilePos );
- unzOpenCurrentFile( z );
- if ( offset <= 0 ) {
- return 0;
- }
- }
- case FS_SEEK_CUR: {
- buf = (char *) _alloca16( ZIP_SEEK_BUF_SIZE );
- for ( i = 0; i < ( offset - ZIP_SEEK_BUF_SIZE ); i += ZIP_SEEK_BUF_SIZE ) {
- res = unzReadCurrentFile( z, buf, ZIP_SEEK_BUF_SIZE );
- if ( res < ZIP_SEEK_BUF_SIZE ) {
- return -1;
- }
- }
- res = i + unzReadCurrentFile( z, buf, offset - i );
- return ( res == offset ) ? 0 : -1;
- }
- default: {
- common->FatalError( "idFile_InZip::Seek: bad origin for %s\n", name.c_str() );
- break;
- }
- }
- return -1;
- }
- #if 1
- /*
- =================================================================================
- idFile_InnerResource
- =================================================================================
- */
- /*
- =================
- idFile_InnerResource::idFile_InnerResource
- =================
- */
- idFile_InnerResource::idFile_InnerResource( const char *_name, idFile *rezFile, int _offset, int _len ) {
- name = _name;
- offset = _offset;
- length = _len;
- resourceFile = rezFile;
- internalFilePos = 0;
- resourceBuffer = NULL;
- }
- /*
- =================
- idFile_InnerResource::~idFile_InnerResource
- =================
- */
- idFile_InnerResource::~idFile_InnerResource() {
- if ( resourceBuffer != NULL ) {
- fileSystem->FreeResourceBuffer();
- }
- }
- /*
- =================
- idFile_InnerResource::Read
- Properly handles partial reads
- =================
- */
- int idFile_InnerResource::Read( void *buffer, int len ) {
- if ( resourceFile == NULL ) {
- return 0;
- }
- if ( internalFilePos + len > length ) {
- len = length - internalFilePos;
- }
- int read = 0; //fileSystem->ReadFromBGL( resourceFile, (byte*)buffer, offset + internalFilePos, len );
- if ( read != len ) {
- if ( resourceBuffer != NULL ) {
- memcpy( buffer, &resourceBuffer[ internalFilePos ], len );
- read = len;
- } else {
- read = fileSystem->ReadFromBGL( resourceFile, buffer, offset + internalFilePos, len );
- }
- }
- internalFilePos += read;
- return read;
- }
- /*
- =================
- idFile_InnerResource::Tell
- =================
- */
- int idFile_InnerResource::Tell() const {
- return internalFilePos;
- }
- /*
- =================
- idFile_InnerResource::Seek
- returns zero on success and -1 on failure
- =================
- */
- int idFile_InnerResource::Seek( long offset, fsOrigin_t origin ) {
- switch( origin ) {
- case FS_SEEK_END: {
- internalFilePos = length - offset - 1;
- return 0;
- }
- case FS_SEEK_SET: {
- internalFilePos = offset;
- if ( internalFilePos >= 0 && internalFilePos < length ) {
- return 0;
- }
- return -1;
- }
- case FS_SEEK_CUR: {
- internalFilePos += offset;
- if ( internalFilePos >= 0 && internalFilePos < length ) {
- return 0;
- }
- return -1;
- }
- default: {
- common->FatalError( "idFile_InnerResource::Seek: bad origin for %s\n", name.c_str() );
- break;
- }
- }
- return -1;
- }
- #endif
- /*
- ================================================================================================
- idFileLocal
- ================================================================================================
- */
- /*
- ========================
- idFileLocal::~idFileLocal
- Destructor that will destroy (close) the managed file when this wrapper class goes out of scope.
- ========================
- */
- idFileLocal::~idFileLocal() {
- if ( file != NULL ) {
- delete file;
- file = NULL;
- }
- }
- static const char * testEndianNessFilename = "temp.bin";
- struct testEndianNess_t {
- testEndianNess_t() {
- a = 0x12345678;
- b = 0x12345678;
- c = 3.0f;
- d = -4.0f;
- e = "test";
- f = idVec3( 1.0f, 2.0f, -3.0f );
- g = false;
- h = true;
- for ( int index = 0; index < sizeof( i ); index++ ) {
- i[index] = 0x37;
- }
- }
- bool operator==( testEndianNess_t & test ) const {
- return a == test.a &&
- b == test.b &&
- c == test.c &&
- d == test.d &&
- e == test.e &&
- f == test.f &&
- g == test.g &&
- h == test.h &&
- ( memcmp( i, test.i, sizeof( i ) ) == 0 );
- }
- int a;
- unsigned int b;
- float c;
- float d;
- idStr e;
- idVec3 f;
- bool g;
- bool h;
- byte i[10];
- };
- CONSOLE_COMMAND( testEndianNessWrite, "Tests the read/write compatibility between platforms", 0 ) {
- idFileLocal file( fileSystem->OpenFileWrite( testEndianNessFilename ) );
- if ( file == NULL ) {
- idLib::Printf( "Couldn't open the %s testfile.\n", testEndianNessFilename );
- return;
- }
- testEndianNess_t testData;
- file->WriteBig( testData.a );
- file->WriteBig( testData.b );
- file->WriteFloat( testData.c );
- file->WriteFloat( testData.d );
- file->WriteString( testData.e );
- file->WriteVec3( testData.f );
- file->WriteBig( testData.g );
- file->WriteBig( testData.h );
- file->Write( testData.i, sizeof( testData.i )/ sizeof( testData.i[0] ) );
- }
- CONSOLE_COMMAND( testEndianNessRead, "Tests the read/write compatibility between platforms", 0 ) {
- idFileLocal file( fileSystem->OpenFileRead( testEndianNessFilename ) );
- if ( file == NULL ) {
- idLib::Printf( "Couldn't find the %s testfile.\n", testEndianNessFilename );
- return;
- }
- testEndianNess_t srcData;
- testEndianNess_t testData;
- memset( &testData, 0, sizeof( testData ) );
- file->ReadBig( testData.a );
- file->ReadBig( testData.b );
- file->ReadFloat( testData.c );
- file->ReadFloat( testData.d );
- file->ReadString( testData.e );
- file->ReadVec3( testData.f );
- file->ReadBig( testData.g );
- file->ReadBig( testData.h );
- file->Read( testData.i, sizeof( testData.i )/ sizeof( testData.i[0] ) );
- assert( srcData == testData );
- }
- CONSOLE_COMMAND( testEndianNessReset, "Tests the read/write compatibility between platforms", 0 ) {
- fileSystem->RemoveFile( testEndianNessFilename );
- }
|