mirror of https://github.com/libAthena/athena.git
* Add PHYSFSFileReader class
This commit is contained in:
parent
5a26e21c5b
commit
47054ea881
|
@ -44,7 +44,8 @@ SOURCES += \
|
|||
$$PWD/src/md5.cpp \
|
||||
$$PWD/src/sha1.cpp \
|
||||
$$PWD/src/aes.c \
|
||||
$$PWD/src/lzo.c
|
||||
$$PWD/src/lzo.c \
|
||||
Athena/src/Athena/PHYSFSFileReader.cpp
|
||||
win32:SOURCES += $$PWD/src/win32_largefilewrapper.c
|
||||
|
||||
HEADERS += \
|
||||
|
@ -101,7 +102,8 @@ HEADERS += \
|
|||
$$PWD/include/Athena/WiiSaveWriter.hpp \
|
||||
$$PWD/include/Athena/ZQuestFile.hpp \
|
||||
$$PWD/include/Athena/ZQuestFileReader.hpp \
|
||||
$$PWD/include/Athena/ZQuestFileWriter.hpp
|
||||
$$PWD/include/Athena/ZQuestFileWriter.hpp \
|
||||
Athena/include/Athena/PHYSFSFileReader.hpp
|
||||
|
||||
win32:HEADERS += \
|
||||
$$PWD/include/win32_largefilewrapper.h
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#ifdef ATHENA_ENABLE_PHYSFS
|
||||
#ifndef PHYSFSSTREAM_HPP
|
||||
#define PHYSFSSTREAM_HPP
|
||||
|
||||
#include "Athena/Stream.hpp"
|
||||
#include <physfs.h>
|
||||
|
||||
namespace Athena
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
class PHYSFSFileReader : public Stream
|
||||
{
|
||||
public:
|
||||
PHYSFSFileReader(const std::string& path);
|
||||
|
||||
void setEndian(Endian);
|
||||
Endian endian() const;
|
||||
bool isBigEndian() const;
|
||||
bool isLittleEndian() const;
|
||||
atUint8* data();
|
||||
|
||||
atUint64 length() const;
|
||||
|
||||
atUint64 position() const;
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
void seek(atInt64 position, SeekOrigin origin);
|
||||
atInt8 readByte();
|
||||
atUint8 readUByte();
|
||||
atUint8* readUBytes(atUint64 length);
|
||||
atInt8* readBytes(atUint64 length);
|
||||
atUint16 readUint16();
|
||||
atInt16 readInt16();
|
||||
atUint32 readUint32();
|
||||
atInt32 readInt32();
|
||||
atUint64 readUint64();
|
||||
atInt64 readInt64();
|
||||
double readDouble();
|
||||
float readFloat();
|
||||
bool readBool();
|
||||
|
||||
bool atEnd() const;
|
||||
|
||||
// TODO: Strings
|
||||
private:
|
||||
Endian m_endian;
|
||||
std::string m_path;
|
||||
atUint64 m_length;
|
||||
PHYSFS_File* m_handle;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef PHYSFSFILEREADER_BASE
|
||||
#define PHYSFSFILEREADER_BASE() \
|
||||
typedef Athena::io::PHYSFSFileReader base
|
||||
#endif
|
||||
#endif // PHYSFSSTREAM_HPP
|
||||
#endif // ATHENA_ENABLE_PHYSFS
|
|
@ -21,7 +21,8 @@
|
|||
|
||||
namespace Athena
|
||||
{
|
||||
|
||||
namespace io
|
||||
{
|
||||
std::ostream& operator<<(std::ostream& os, Endian& endian);
|
||||
|
||||
class Stream
|
||||
|
@ -78,4 +79,5 @@ protected:
|
|||
virtual void fill(atInt8, atUint64) {THROW_NOT_IMPLEMENTED_EXCEPTION();}
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif // STREAM_HPP
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
#ifdef ATHENA_ENABLE_PHYSFS
|
||||
#include "Athena/PHYSFSFileReader.hpp"
|
||||
#include "Athena/FileNotFoundException.hpp"
|
||||
#include "Athena/IOException.hpp"
|
||||
|
||||
namespace Athena
|
||||
{
|
||||
namespace io
|
||||
{
|
||||
|
||||
PHYSFSFileReader::PHYSFSFileReader(const std::string& path)
|
||||
: m_path(path),
|
||||
m_endian(Endian::LittleEndian)
|
||||
{
|
||||
if (!PHYSFS_exists(m_path.c_str()))
|
||||
THROW_FILE_NOT_FOUND_EXCEPTION(path);
|
||||
|
||||
m_handle = PHYSFS_openRead(path.c_str());
|
||||
m_length = PHYSFS_fileLength(m_handle);
|
||||
}
|
||||
|
||||
atUint8* PHYSFSFileReader::data()
|
||||
{
|
||||
return readUBytes(length());
|
||||
}
|
||||
|
||||
atUint64 PHYSFSFileReader::length() const
|
||||
{
|
||||
return m_length;
|
||||
}
|
||||
|
||||
atUint64 PHYSFSFileReader::position() const
|
||||
{
|
||||
return PHYSFS_tell(m_handle);
|
||||
}
|
||||
|
||||
bool PHYSFSFileReader::isOpen() const
|
||||
{
|
||||
return (m_handle != nullptr);
|
||||
}
|
||||
|
||||
void PHYSFSFileReader::seek(atInt64 position, SeekOrigin origin)
|
||||
{
|
||||
atInt64 curPos = PHYSFS_tell(m_handle);
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin::Begin:
|
||||
if ((position < 0 || (atInt64)position > (atInt64)m_length))
|
||||
THROW_IO_EXCEPTION("Position %0.16X outside stream bounds ", position);
|
||||
PHYSFS_seek(m_handle, position);
|
||||
break;
|
||||
case SeekOrigin::Current:
|
||||
if ((((atInt64)curPos + position) < 0 || (curPos + position) > m_length))
|
||||
THROW_IO_EXCEPTION("Position %0.16X outside stream bounds ", position);
|
||||
PHYSFS_seek(m_handle, curPos + position);
|
||||
break;
|
||||
case SeekOrigin::End:
|
||||
if ((((atInt64)m_length - position < 0) || (m_length - position) > m_length))
|
||||
THROW_IO_EXCEPTION("Position %0.16X outside stream bounds ", position);
|
||||
PHYSFS_seek(m_handle, m_length - position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
atUint8 PHYSFSFileReader::readUByte()
|
||||
{
|
||||
atUint8 val;
|
||||
|
||||
if (!PHYSFS_read(m_handle, &val, 1, 1))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
atInt8 PHYSFSFileReader::readByte()
|
||||
{
|
||||
return readUByte();
|
||||
}
|
||||
|
||||
atUint8* PHYSFSFileReader::readUBytes(atUint64 length)
|
||||
{
|
||||
atUint8* data = new atUint8[length];
|
||||
if (PHYSFS_read(m_handle, data, 1, length) == length)
|
||||
return data;
|
||||
delete[] data;
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
}
|
||||
|
||||
atInt8*PHYSFSFileReader::readBytes(atUint64 length)
|
||||
{
|
||||
return (atInt8*)readUBytes(length);
|
||||
}
|
||||
|
||||
atUint16 PHYSFSFileReader::readUint16()
|
||||
{
|
||||
atUint16 val;
|
||||
|
||||
if (m_endian == Endian::BigEndian)
|
||||
{
|
||||
if (!PHYSFS_readUBE16(m_handle, &val))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
}
|
||||
else if (!PHYSFS_readULE16(m_handle, &val))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
atInt16 PHYSFSFileReader::readInt16()
|
||||
{
|
||||
return readUint16();
|
||||
}
|
||||
|
||||
atUint32 PHYSFSFileReader::readUint32()
|
||||
{
|
||||
atUint32 val;
|
||||
|
||||
if (m_endian == Endian::BigEndian)
|
||||
{
|
||||
if (!PHYSFS_readUBE32(m_handle, &val))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
}
|
||||
else if (!PHYSFS_readULE32(m_handle, &val))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
atInt32 PHYSFSFileReader::readInt32()
|
||||
{
|
||||
return readUint32();
|
||||
}
|
||||
|
||||
atUint64 PHYSFSFileReader::readUint64()
|
||||
{
|
||||
atUint64 val;
|
||||
|
||||
if (m_endian == Endian::BigEndian)
|
||||
{
|
||||
if (!PHYSFS_readUBE64(m_handle, &val))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
}
|
||||
else if (!PHYSFS_readUBE64(m_handle, &val))
|
||||
THROW_IO_EXCEPTION("Position outside stream bounds");
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
atInt64 PHYSFSFileReader::readInt64()
|
||||
{
|
||||
return readUint64();
|
||||
}
|
||||
|
||||
double PHYSFSFileReader::readDouble()
|
||||
{
|
||||
return static_cast<double>(readUint64());
|
||||
}
|
||||
|
||||
float PHYSFSFileReader::readFloat()
|
||||
{
|
||||
return static_cast<float>(readUint32());
|
||||
}
|
||||
|
||||
bool PHYSFSFileReader::readBool()
|
||||
{
|
||||
return (readByte() != 0);
|
||||
}
|
||||
|
||||
bool PHYSFSFileReader::atEnd() const
|
||||
{
|
||||
return PHYSFS_eof(m_handle);
|
||||
}
|
||||
|
||||
void PHYSFSFileReader::setEndian(Endian endian)
|
||||
{
|
||||
m_endian = endian;
|
||||
}
|
||||
|
||||
Endian PHYSFSFileReader::endian() const
|
||||
{
|
||||
return m_endian;
|
||||
}
|
||||
|
||||
bool PHYSFSFileReader::isBigEndian() const
|
||||
{
|
||||
return m_endian == Endian::BigEndian;
|
||||
}
|
||||
|
||||
bool PHYSFSFileReader::isLittleEndian() const
|
||||
{
|
||||
return m_endian == Endian::LittleEndian;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue