void FArchiveFileReaderWindows::Seek( INT InPos ) { check(InPos>=0); check(InPos<=Size); if( SetFilePointer( Handle, InPos, NULL, FILE_BEGIN )==INVALID_SET_FILE_POINTER ) { ArIsError = 1; Error->Logf( TEXT("SetFilePointer Failed %i/%i: %i %s"), InPos, Size, Pos, appGetSystemErrorMessage() ); } Pos = InPos; BufferBase = Pos; BufferCount = 0; }
void FArchiveFileReaderWindows::Serialize( void* V, INT Length ) { while( Length>0 ) { INT Copy = Min( Length, BufferBase+BufferCount-Pos ); if( Copy<=0 ) { if( Length >= ARRAY_COUNT(Buffer) ) { INT Count=0; // Read data from device via Win32 ReadFile API. { SCOPED_FILE_IO_READ_STATS( StatsHandle, Length, Pos ); ReadFile( Handle, V, Length, (DWORD*)&Count, NULL ); } if( Count!=Length ) { ArIsError = 1; Error->Logf( TEXT("ReadFile failed: Count=%i Length=%i Error=%s for file %s"), Count, Length, appGetSystemErrorMessage(), *Filename ); } Pos += Length; BufferBase += Length; return; } InternalPrecache( Pos, MAXINT ); Copy = Min( Length, BufferBase+BufferCount-Pos ); if( Copy<=0 ) { ArIsError = 1; Error->Logf( TEXT("ReadFile beyond EOF %i+%i/%i for file %s"), Pos, Length, Size, *Filename ); } if( ArIsError ) { return; } } appMemcpy( V, Buffer+Pos-BufferBase, Copy ); Pos += Copy; Length -= Copy; V = (BYTE*)V + Copy; } }
UBOOL FArchiveFileReaderWindows::InternalPrecache( INT PrecacheOffset, INT PrecacheSize ) { // Only precache at current position and avoid work if precaching same offset twice. if( Pos == PrecacheOffset && (!BufferBase || !BufferCount || BufferBase != Pos) ) { BufferBase = Pos; BufferCount = Min( Min( PrecacheSize, (INT)(ARRAY_COUNT(Buffer) - (Pos&(ARRAY_COUNT(Buffer)-1))) ), Size-Pos ); BufferCount = Max(BufferCount,0); // clamp to 0 INT Count=0; // Read data from device via Win32 ReadFile API. { SCOPED_FILE_IO_READ_STATS( StatsHandle, BufferCount, Pos ); ReadFile( Handle, Buffer, BufferCount, (DWORD*)&Count, NULL ); } if( Count!=BufferCount ) { ArIsError = 1; Error->Logf( TEXT("ReadFile failed: Count=%i BufferCount=%i Error=%s"), Count, BufferCount, appGetSystemErrorMessage() ); } } return TRUE; }
static void ErrFail(const char *what) { int err = GetLastError(); appWPrintf("...%s failed\nError %d %s\n", what, err, appGetSystemErrorMessage(err)); }