2004-12-10 08:48:18 +00:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
2003-11-27 07:46:36 +00:00
|
|
|
#include "global.h"
|
2003-07-22 07:47:27 +00:00
|
|
|
#include "RageFile.h"
|
|
|
|
|
#include "RageUtil.h"
|
2003-12-04 08:25:59 +00:00
|
|
|
#include "RageFileDriver.h"
|
2003-07-22 07:47:27 +00:00
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
RageFile::RageFile()
|
|
|
|
|
{
|
|
|
|
|
m_File = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
RageFile::RageFile( const RageFile &cpy ):
|
|
|
|
|
RageBasicFile( cpy )
|
2003-12-10 05:04:37 +00:00
|
|
|
{
|
2003-12-10 05:48:31 +00:00
|
|
|
/* This will copy the file driver, including its internal file pointer. */
|
2004-12-09 11:52:49 +00:00
|
|
|
m_File = FILEMAN->CopyFileObj( cpy.m_File );
|
2003-12-10 05:04:37 +00:00
|
|
|
m_Path = cpy.m_Path;
|
|
|
|
|
m_Mode = cpy.m_Mode;
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
CString RageFile::GetPath() const
|
|
|
|
|
{
|
2004-12-09 11:31:23 +00:00
|
|
|
if ( !IsOpen() )
|
2003-12-04 08:25:59 +00:00
|
|
|
return "";
|
|
|
|
|
|
2004-12-09 11:31:23 +00:00
|
|
|
CString sRet = m_File->GetDisplayPath();
|
|
|
|
|
if( sRet != "" )
|
|
|
|
|
return sRet;
|
|
|
|
|
|
|
|
|
|
return GetRealPath();
|
2003-12-04 08:25:59 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-21 07:23:29 +00:00
|
|
|
bool RageFile::Open( const CString& path, int mode )
|
2003-11-27 07:46:36 +00:00
|
|
|
{
|
2003-12-04 08:25:59 +00:00
|
|
|
ASSERT( FILEMAN );
|
2003-12-03 23:50:53 +00:00
|
|
|
Close();
|
2003-12-04 08:25:59 +00:00
|
|
|
|
|
|
|
|
m_Path = path;
|
|
|
|
|
FixSlashesInPlace(m_Path);
|
|
|
|
|
|
|
|
|
|
m_Mode = mode;
|
2003-12-03 23:50:53 +00:00
|
|
|
|
2003-12-21 07:23:29 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
int error;
|
2004-12-09 11:52:49 +00:00
|
|
|
m_File = FILEMAN->Open( path, mode, error );
|
2003-12-04 08:25:59 +00:00
|
|
|
|
|
|
|
|
if( m_File == NULL )
|
|
|
|
|
{
|
|
|
|
|
SetError( strerror(error) );
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
2003-11-27 07:46:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void RageFile::Close()
|
|
|
|
|
{
|
2003-12-11 05:32:35 +00:00
|
|
|
FILEMAN->Close( m_File );
|
2003-12-04 08:25:59 +00:00
|
|
|
m_File = NULL;
|
2003-07-22 07:47:27 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
#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 )
|
2004-06-23 01:53:30 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->GetLine( out );
|
2004-06-23 01:53:30 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
int RageFile::PutLine( const CString &str )
|
2003-11-27 07:46:36 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_WRITE;
|
|
|
|
|
return m_File->PutLine( str );
|
2003-12-03 23:50:53 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
bool RageFile::AtEOF() const
|
2003-12-03 23:50:53 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->AtEOF();
|
2003-12-04 08:25:59 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
void RageFile::ClearError()
|
2003-12-04 04:26:49 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
if( m_File != NULL )
|
|
|
|
|
m_File->ClearError();
|
|
|
|
|
m_sError = "";
|
2003-12-04 04:26:49 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
CString RageFile::GetError() const
|
2003-12-03 23:50:53 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
if( m_File != NULL && m_File->GetError() != "" )
|
|
|
|
|
return m_File->GetError();
|
|
|
|
|
return m_sError;
|
|
|
|
|
}
|
2003-12-03 23:50:53 +00:00
|
|
|
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
void RageFile::SetError( const CString &err )
|
|
|
|
|
{
|
|
|
|
|
if( m_File != NULL )
|
|
|
|
|
m_File->ClearError();
|
|
|
|
|
m_sError = err;
|
|
|
|
|
}
|
2003-12-04 08:25:59 +00:00
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
int RageFile::Read( void *pBuffer, size_t iBytes )
|
|
|
|
|
{
|
|
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->Read( pBuffer, iBytes );
|
2003-11-27 07:46:36 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
int RageFile::Seek( int offset )
|
2003-11-27 07:46:36 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->Seek( offset );
|
|
|
|
|
}
|
2003-12-04 08:25:59 +00:00
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
int RageFile::Tell() const
|
|
|
|
|
{
|
|
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->Tell();
|
2003-12-04 08:25:59 +00:00
|
|
|
}
|
|
|
|
|
|
2004-02-17 21:42:06 +00:00
|
|
|
int RageFile::GetFileSize() const
|
2003-12-04 08:25:59 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->GetFileSize();
|
2003-11-27 07:46:36 +00:00
|
|
|
}
|
2003-12-03 23:50:53 +00:00
|
|
|
|
2003-12-21 09:17:39 +00:00
|
|
|
int RageFile::Read( CString &buffer, int bytes )
|
2003-12-10 05:04:37 +00:00
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->Read( buffer, bytes );
|
2003-12-10 05:04:37 +00:00
|
|
|
}
|
2003-12-04 08:25:59 +00:00
|
|
|
|
2003-12-12 07:47:38 +00:00
|
|
|
int RageFile::Write( const void *buffer, size_t bytes )
|
|
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_WRITE;
|
|
|
|
|
return m_File->Write( buffer, bytes );
|
2003-12-12 07:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2003-12-04 21:10:16 +00:00
|
|
|
int RageFile::Write( const void *buffer, size_t bytes, int nmemb )
|
|
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_WRITE;
|
|
|
|
|
return m_File->Write( buffer, bytes, nmemb );
|
2003-12-04 21:10:16 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-12 07:47:38 +00:00
|
|
|
int RageFile::Flush()
|
|
|
|
|
{
|
2003-12-21 07:23:29 +00:00
|
|
|
if( !m_File )
|
|
|
|
|
{
|
|
|
|
|
SetError( "Not open" );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
return m_File->Flush();
|
2003-12-12 07:47:38 +00:00
|
|
|
}
|
|
|
|
|
|
2003-12-04 21:10:16 +00:00
|
|
|
int RageFile::Read( void *buffer, size_t bytes, int nmemb )
|
|
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->Read( buffer, bytes, nmemb );
|
2003-12-04 21:10:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int RageFile::Seek( int offset, int whence )
|
|
|
|
|
{
|
2004-12-10 08:48:18 +00:00
|
|
|
ASSERT_READ;
|
|
|
|
|
return m_File->Seek( offset, whence );
|
2003-12-04 21:10:16 +00:00
|
|
|
}
|
2004-05-06 00:42:06 +00:00
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
void FileReading::ReadBytes( RageBasicFile &f, void *buf, int size, CString &sError )
|
2004-10-05 22:53:21 +00:00
|
|
|
{
|
2004-11-30 08:12:08 +00:00
|
|
|
if( sError.size() != 0 )
|
|
|
|
|
return;
|
|
|
|
|
|
2004-10-05 22:53:21 +00:00
|
|
|
int ret = f.Read( buf, size );
|
|
|
|
|
if( ret == -1 )
|
2004-11-30 08:12:08 +00:00
|
|
|
sError = f.GetError();
|
|
|
|
|
else if( ret < size )
|
|
|
|
|
sError = "Unexpected end of file";
|
2004-10-05 22:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
uint8_t FileReading::read_8( RageBasicFile &f, CString &sError )
|
2004-10-05 22:53:21 +00:00
|
|
|
{
|
|
|
|
|
uint8_t val;
|
2004-11-30 08:12:08 +00:00
|
|
|
ReadBytes( f, &val, sizeof(uint8_t), sError );
|
|
|
|
|
if( sError.size() == 0 )
|
|
|
|
|
return val;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2004-10-05 22:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
uint16_t FileReading::read_u16_le( RageBasicFile &f, CString &sError )
|
2004-10-05 22:53:21 +00:00
|
|
|
{
|
|
|
|
|
uint16_t val;
|
2004-11-30 08:12:08 +00:00
|
|
|
ReadBytes( f, &val, sizeof(uint16_t), sError );
|
|
|
|
|
if( sError.size() == 0 )
|
|
|
|
|
return Swap16LE( val );
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2004-10-05 22:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
int16_t FileReading::read_16_le( RageBasicFile &f, CString &sError )
|
2004-10-05 22:53:21 +00:00
|
|
|
{
|
|
|
|
|
int16_t val;
|
2004-11-30 08:12:08 +00:00
|
|
|
ReadBytes( f, &val, sizeof(int16_t), sError );
|
|
|
|
|
if( sError.size() == 0 )
|
|
|
|
|
return Swap16LE( val );
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2004-10-05 22:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
uint32_t FileReading::read_u32_le( RageBasicFile &f, CString &sError )
|
2004-10-05 22:53:21 +00:00
|
|
|
{
|
|
|
|
|
uint32_t val;
|
2004-11-30 08:12:08 +00:00
|
|
|
ReadBytes( f, &val, sizeof(uint32_t), sError );
|
|
|
|
|
if( sError.size() == 0 )
|
|
|
|
|
return Swap32LE( val );
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2004-10-05 22:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-12-10 08:48:18 +00:00
|
|
|
int32_t FileReading::read_32_le( RageBasicFile &f, CString &sError )
|
2004-10-05 22:53:21 +00:00
|
|
|
{
|
|
|
|
|
int32_t val;
|
2004-11-30 08:12:08 +00:00
|
|
|
ReadBytes( f, &val, sizeof(int32_t), sError );
|
|
|
|
|
if( sError.size() == 0 )
|
|
|
|
|
return Swap32LE( val );
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
2004-10-05 22:53:21 +00:00
|
|
|
}
|
|
|
|
|
|
2004-05-06 00:42:06 +00:00
|
|
|
/*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|