/* ** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** 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 3 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. If not, see . */ //////////////////////////////////////////////////////////////////////////////// // // // (c) 2001-2003 Electronic Arts Inc. // // // //////////////////////////////////////////////////////////////////////////////// //---------------------------------------------------------------------------- // // Westwood Studios Pacific. // // Confidential Information // Copyright(C) 2001 - All Rights Reserved // //---------------------------------------------------------------------------- // // Project: RTS // // Module: IO // // File name: StreamingArchiveFile.cpp // // Created: 12/06/02 // //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Includes //---------------------------------------------------------------------------- #include "PreRTS.h" #include #include #include #include #include #include "Common/AsciiString.h" #include "Common/FileSystem.h" #include "Common/StreamingArchiveFile.h" #include "Common/PerfTimer.h" //---------------------------------------------------------------------------- // Externals //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Defines //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Private Types //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Private Data //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Public Data //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Private Prototypes //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- // Private Functions //---------------------------------------------------------------------------- //================================================================= // StreamingArchiveFile::StreamingArchiveFile //================================================================= StreamingArchiveFile::StreamingArchiveFile() : m_file(NULL), m_startingPos(0), m_size(0), m_curPos(0) { } //---------------------------------------------------------------------------- // Public Functions //---------------------------------------------------------------------------- //================================================================= // StreamingArchiveFile::~StreamingArchiveFile //================================================================= StreamingArchiveFile::~StreamingArchiveFile() { File::close(); } //================================================================= // StreamingArchiveFile::open //================================================================= /** * This function opens a file using the standard C open() call. Access flags * are mapped to the appropriate open flags. Returns true if file was opened * successfully. */ //================================================================= //DECLARE_PERF_TIMER(StreamingArchiveFile) Bool StreamingArchiveFile::open( const Char *filename, Int access ) { //USE_PERF_TIMER(StreamingArchiveFile) File *file = TheFileSystem->openFile( filename, access ); if ( file == NULL ) { return FALSE; } return (open( file ) != NULL); } //============================================================================ // StreamingArchiveFile::open //============================================================================ Bool StreamingArchiveFile::open( File *file ) { return TRUE; } //============================================================================ // StreamingArchiveFile::openFromArchive //============================================================================ Bool StreamingArchiveFile::openFromArchive(File *archiveFile, const AsciiString& filename, Int offset, Int size) { //USE_PERF_TIMER(StreamingArchiveFile) if (archiveFile == NULL) { return FALSE; } if (File::open(filename.str(), File::READ | File::BINARY | File::STREAMING) == FALSE) { return FALSE; } m_file = archiveFile; m_startingPos = offset; m_size = size; m_curPos = 0; if (m_file->seek(offset, File::START) != offset) { return FALSE; } if (m_file->seek(size) != m_startingPos + size) { return FALSE; } // We know this will succeed. m_file->seek(offset, File::START); m_nameStr = filename; return TRUE; } //================================================================= // StreamingArchiveFile::close //================================================================= /** * Closes the current file if it is open. * Must call StreamingArchiveFile::close() for each successful StreamingArchiveFile::open() call. */ //================================================================= void StreamingArchiveFile::close( void ) { File::close(); } //================================================================= // StreamingArchiveFile::read //================================================================= // if buffer is null, just advance the current position by 'bytes' Int StreamingArchiveFile::read( void *buffer, Int bytes ) { if (!m_file) { return 0; } // There shouldn't be a way that this can fail, because we've already verified that the file // contains at least this many bits. m_file->seek(m_startingPos + m_curPos, File::START); if (bytes + m_curPos > m_size) bytes = m_size - m_curPos; Int bytesRead = m_file->read(buffer, bytes); m_curPos += bytesRead; return bytesRead; } //================================================================= // StreamingArchiveFile::write //================================================================= Int StreamingArchiveFile::write( const void *buffer, Int bytes ) { DEBUG_CRASH(("Cannot write to streaming files.\n")); return -1; } //================================================================= // StreamingArchiveFile::seek //================================================================= Int StreamingArchiveFile::seek( Int pos, seekMode mode) { Int newPos; switch( mode ) { case START: newPos = pos; break; case CURRENT: newPos = m_curPos + pos; break; case END: DEBUG_ASSERTCRASH(pos <= 0, ("StreamingArchiveFile::seek - position should be <= 0 for a seek starting from the end.")); newPos = m_size + pos; break; default: // bad seek mode return -1; } if ( newPos < 0 ) { newPos = 0; } else if ( newPos > m_size ) { newPos = m_size; } m_curPos = newPos; return m_curPos; }