2004-05-06 00:42:06 +00:00
|
|
|
/*
|
|
|
|
|
* RageFile: high-level file abstraction
|
|
|
|
|
*/
|
|
|
|
|
|
2003-12-03 20:37:10 +00:00
|
|
|
#ifndef RAGE_FILE_H
|
|
|
|
|
#define RAGE_FILE_H
|
2003-07-22 07:47:27 +00:00
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
class RageFileObj;
|
2003-07-22 07:47:27 +00:00
|
|
|
|
2003-11-27 07:46:36 +00:00
|
|
|
class RageFile
|
|
|
|
|
{
|
2003-12-04 08:25:59 +00:00
|
|
|
friend class RageFileObj;
|
|
|
|
|
|
|
|
|
|
public:
|
2003-12-21 07:23:29 +00:00
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
READ = 0x1,
|
|
|
|
|
WRITE = 0x2,
|
|
|
|
|
|
|
|
|
|
/* Always write directly to the destination file; don't do a safe write. (for logs) */
|
2004-02-20 06:01:12 +00:00
|
|
|
STREAMED = 0x4,
|
|
|
|
|
|
|
|
|
|
/* Flush the file to disk on close. Combined with not streaming, this results
|
|
|
|
|
* in very safe writes, but is slow. */
|
|
|
|
|
SLOW_FLUSH = 0x8
|
2003-12-21 07:23:29 +00:00
|
|
|
};
|
|
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
RageFile();
|
|
|
|
|
~RageFile() { Close(); }
|
2003-12-10 05:04:37 +00:00
|
|
|
RageFile( const RageFile &cpy );
|
2003-12-04 08:25:59 +00:00
|
|
|
|
2003-12-10 05:04:37 +00:00
|
|
|
/* Use GetRealPath to get the path this file was opened with; use that if you
|
|
|
|
|
* want a path that will probably get you the same file again.
|
|
|
|
|
*
|
|
|
|
|
* GetPath can be overridden by drivers. Use it to get a path for display;
|
|
|
|
|
* it may give more information, such as the name of the archive the file
|
|
|
|
|
* is in. It has no parsable meaning. */
|
2003-12-04 08:25:59 +00:00
|
|
|
const CString &GetRealPath() const { return m_Path; }
|
|
|
|
|
CString GetPath() const;
|
|
|
|
|
|
2003-12-21 07:23:29 +00:00
|
|
|
bool Open( const CString& path, int mode = READ );
|
2003-12-04 08:25:59 +00:00
|
|
|
void Close();
|
|
|
|
|
|
|
|
|
|
bool IsOpen() const { return m_File != NULL; }
|
2003-12-21 07:23:29 +00:00
|
|
|
int GetOpenMode() const { return m_Mode; }
|
2003-12-04 08:25:59 +00:00
|
|
|
bool AtEOF() const { return m_EOF; }
|
|
|
|
|
CString GetError() const { return m_Error; }
|
|
|
|
|
void ClearError() { m_Error = ""; }
|
2004-06-06 08:34:58 +00:00
|
|
|
bool IsGood() const { return IsOpen() && !AtEOF() && m_Error.empty(); }
|
2003-12-10 05:04:37 +00:00
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
int Tell() const { return m_FilePos; }
|
|
|
|
|
int Seek( int offset );
|
|
|
|
|
int SeekCur( int offset );
|
2004-02-17 21:42:06 +00:00
|
|
|
int GetFileSize() const;
|
2003-12-04 08:25:59 +00:00
|
|
|
void Rewind();
|
|
|
|
|
|
|
|
|
|
/* Raw I/O: */
|
|
|
|
|
int Read( void *buffer, size_t bytes );
|
2003-12-21 09:17:39 +00:00
|
|
|
int Read( CString &buffer, int bytes = -1 );
|
2003-12-12 07:47:38 +00:00
|
|
|
int Write( const void *buffer, size_t bytes );
|
|
|
|
|
int Write( const CString& string ) { return Write( string.data(), string.size() ); }
|
|
|
|
|
int Flush();
|
2003-12-04 08:25:59 +00:00
|
|
|
|
2003-12-04 21:10:16 +00:00
|
|
|
/* These are just here to make wrappers (eg. vorbisfile, SDL_rwops) easier. */
|
|
|
|
|
int Write( const void *buffer, size_t bytes, int nmemb );
|
|
|
|
|
int Read( void *buffer, size_t bytes, int nmemb );
|
|
|
|
|
int Seek( int offset, int whence );
|
|
|
|
|
|
2003-12-04 08:25:59 +00:00
|
|
|
/* Line-based I/O: */
|
|
|
|
|
int GetLine( CString &out );
|
|
|
|
|
int PutLine( const CString &str );
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void SetError( const CString &err ) { m_Error = err; } /* called by RageFileObj::SetError */
|
|
|
|
|
|
2003-11-27 07:46:36 +00:00
|
|
|
private:
|
2004-06-23 01:53:30 +00:00
|
|
|
int FillBuf();
|
2003-12-04 08:25:59 +00:00
|
|
|
void ResetBuf();
|
|
|
|
|
|
|
|
|
|
RageFileObj *m_File;
|
|
|
|
|
CString m_Path;
|
2003-12-21 07:23:29 +00:00
|
|
|
int m_Mode;
|
2003-12-04 08:25:59 +00:00
|
|
|
|
|
|
|
|
CString m_Error;
|
|
|
|
|
bool m_EOF;
|
|
|
|
|
int m_FilePos;
|
2003-12-03 23:50:53 +00:00
|
|
|
|
2004-07-24 03:01:23 +00:00
|
|
|
enum { BSIZE = 1024 };
|
2003-12-03 23:50:53 +00:00
|
|
|
char m_Buffer[BSIZE];
|
|
|
|
|
char *m_pBuf;
|
2004-06-23 01:53:30 +00:00
|
|
|
int m_BufAvail;
|
2003-11-27 07:46:36 +00:00
|
|
|
};
|
|
|
|
|
|
2004-10-05 22:53:21 +00:00
|
|
|
/* Convenience wrappers for reading binary files. */
|
|
|
|
|
namespace FileReading
|
|
|
|
|
{
|
|
|
|
|
struct FatalError: public RageException { FatalError(const CString &str): RageException(str) { } };
|
|
|
|
|
struct UnexpectedEOF: public FatalError { UnexpectedEOF(): FatalError("Unexpected end of file") { } };
|
|
|
|
|
|
|
|
|
|
void ReadBytes( RageFile &f, void *buf, int size );
|
|
|
|
|
uint8_t read_8( RageFile &f );
|
|
|
|
|
int16_t read_16_le( RageFile &f );
|
|
|
|
|
uint16_t read_u16_le( RageFile &f );
|
|
|
|
|
int32_t read_32_le( RageFile &f );
|
|
|
|
|
uint32_t read_u32_le( RageFile &f );
|
|
|
|
|
};
|
|
|
|
|
|
2003-07-22 07:47:27 +00:00
|
|
|
#endif
|