/* * This provides an interface to open files in RageFileManager's namespace * This is just a simple RageBasicFile wrapper on top of another RageBasicFile; * when a file is open, is acts like the underlying RageBasicFile, except that * a few extra sanity checks are made to check file modes. */ #include "global.h" #include "RageFile.h" #include "RageUtil.h" #include "RageFileDriver.h" RageFile::RageFile() { m_File = NULL; } RageFile::RageFile( const RageFile &cpy ): RageBasicFile( cpy ) { /* This will copy the file driver, including its internal file pointer. */ m_File = FILEMAN->CopyFileObj( cpy.m_File ); m_Path = cpy.m_Path; m_Mode = cpy.m_Mode; } CString RageFile::GetPath() const { if ( !IsOpen() ) return ""; CString sRet = m_File->GetDisplayPath(); if( sRet != "" ) return sRet; return GetRealPath(); } bool RageFile::Open( const CString& path, int mode ) { ASSERT( FILEMAN ); Close(); m_Path = path; FixSlashesInPlace(m_Path); m_Mode = mode; if( (m_Mode&READ) && (m_Mode&WRITE) ) { SetError( "Reading and writing are mutually exclusive" ); return false; } if( !(m_Mode&READ) && !(m_Mode&WRITE) ) { SetError( "Neither reading nor writing specified" ); return false; } int error; m_File = FILEMAN->Open( path, mode, error ); if( m_File == NULL ) { SetError( strerror(error) ); return false; } return true; } void RageFile::Close() { FILEMAN->Close( m_File ); m_File = NULL; } #define ASSERT_OPEN ASSERT_M( IsOpen(), ssprintf("\"%s\" is not open.", m_Path.c_str()) ); #define ASSERT_READ ASSERT_OPEN; ASSERT_M( !!(m_Mode&READ), ssprintf("\"%s\" is not open for reading", m_Path.c_str()) ); #define ASSERT_WRITE ASSERT_OPEN; ASSERT_M( !!(m_Mode&WRITE), ssprintf("\"%s\" is not open for writing", m_Path.c_str()) ); int RageFile::GetLine( CString &out ) { ASSERT_READ; return m_File->GetLine( out ); } int RageFile::PutLine( const CString &str ) { ASSERT_WRITE; return m_File->PutLine( str ); } bool RageFile::AtEOF() const { ASSERT_READ; return m_File->AtEOF(); } void RageFile::ClearError() { if( m_File != NULL ) m_File->ClearError(); m_sError = ""; } CString RageFile::GetError() const { if( m_File != NULL && m_File->GetError() != "" ) return m_File->GetError(); return m_sError; } void RageFile::SetError( const CString &err ) { if( m_File != NULL ) m_File->ClearError(); m_sError = err; } int RageFile::Read( void *pBuffer, size_t iBytes ) { ASSERT_READ; return m_File->Read( pBuffer, iBytes ); } int RageFile::Seek( int offset ) { ASSERT_READ; return m_File->Seek( offset ); } int RageFile::Tell() const { ASSERT_READ; return m_File->Tell(); } int RageFile::GetFileSize() const { ASSERT_READ; return m_File->GetFileSize(); } int RageFile::Read( CString &buffer, int bytes ) { ASSERT_READ; return m_File->Read( buffer, bytes ); } int RageFile::Write( const void *buffer, size_t bytes ) { ASSERT_WRITE; return m_File->Write( buffer, bytes ); } int RageFile::Write( const void *buffer, size_t bytes, int nmemb ) { ASSERT_WRITE; return m_File->Write( buffer, bytes, nmemb ); } int RageFile::Flush() { if( !m_File ) { SetError( "Not open" ); return -1; } return m_File->Flush(); } int RageFile::Read( void *buffer, size_t bytes, int nmemb ) { ASSERT_READ; return m_File->Read( buffer, bytes, nmemb ); } int RageFile::Seek( int offset, int whence ) { ASSERT_READ; return m_File->Seek( offset, whence ); } void FileReading::ReadBytes( RageBasicFile &f, void *buf, int size, CString &sError ) { if( sError.size() != 0 ) return; int ret = f.Read( buf, size ); if( ret == -1 ) sError = f.GetError(); else if( ret < size ) sError = "Unexpected end of file"; } uint8_t FileReading::read_8( RageBasicFile &f, CString &sError ) { uint8_t val; ReadBytes( f, &val, sizeof(uint8_t), sError ); if( sError.size() == 0 ) return val; else return 0; } uint16_t FileReading::read_u16_le( RageBasicFile &f, CString &sError ) { uint16_t val; ReadBytes( f, &val, sizeof(uint16_t), sError ); if( sError.size() == 0 ) return Swap16LE( val ); else return 0; } int16_t FileReading::read_16_le( RageBasicFile &f, CString &sError ) { int16_t val; ReadBytes( f, &val, sizeof(int16_t), sError ); if( sError.size() == 0 ) return Swap16LE( val ); else return 0; } uint32_t FileReading::read_u32_le( RageBasicFile &f, CString &sError ) { uint32_t val; ReadBytes( f, &val, sizeof(uint32_t), sError ); if( sError.size() == 0 ) return Swap32LE( val ); else return 0; } int32_t FileReading::read_32_le( RageBasicFile &f, CString &sError ) { int32_t val; ReadBytes( f, &val, sizeof(int32_t), sError ); if( sError.size() == 0 ) return Swap32LE( val ); else return 0; } /* * Copyright (c) 2003-2004 Glenn Maynard, Chris Danford, Steve Checkoway * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, provided that the above * copyright notice(s) and this permission notice appear in all copies of * the Software and that both the above copyright notice(s) and this * permission notice appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */