Remove and replace exceptions

This commit is contained in:
Phillip Stephens 2015-07-21 22:37:22 -07:00
parent 602f6b6e15
commit 8ea5071e0f
33 changed files with 425 additions and 588 deletions

View File

@ -51,16 +51,10 @@ add_library(AthenaCore
include/Athena/Types.hpp include/Athena/Types.hpp
include/Athena/Utility.hpp include/Athena/Utility.hpp
include/Athena/Global.hpp include/Athena/Global.hpp
include/Athena/Exception.hpp
include/Athena/FileNotFoundException.hpp
include/Athena/IOException.hpp
include/Athena/InvalidDataException.hpp
include/Athena/InvalidOperationException.hpp
include/Athena/FileReader.hpp include/Athena/FileReader.hpp
include/Athena/FileWriter.hpp include/Athena/FileWriter.hpp
include/Athena/MemoryReader.hpp include/Athena/MemoryReader.hpp
include/Athena/MemoryWriter.hpp include/Athena/MemoryWriter.hpp
include/Athena/NotImplementedException.hpp
include/Athena/Checksums.hpp include/Athena/Checksums.hpp
include/Athena/Compression.hpp include/Athena/Compression.hpp
include/LZ77/LZBase.hpp include/LZ77/LZBase.hpp

View File

@ -1,7 +1,7 @@
# PKGBUILD for libAthena # PKGBUILD for libAthena
_pkgname=libathena _pkgname=libathena
pkgname=$_pkgname-git pkgname=$_pkgname-git
pkgver=2.0.0.9.gf3ba881 pkgver=2.1.0
pkgrel=1 pkgrel=1
pkgdesc="Basic cross platform IO library" pkgdesc="Basic cross platform IO library"
arch=('i686' 'x86_64') arch=('i686' 'x86_64')

View File

@ -17,7 +17,7 @@
#ifndef ALTTP_FILE_HPP #ifndef ALTTP_FILE_HPP
#define ALTTP_FILE_HPP #define ALTTP_FILE_HPP
#include "Athena/Types.hpp" #include "Athena/Global.hpp"
#include <vector> #include <vector>
namespace Athena namespace Athena

View File

@ -17,7 +17,7 @@
#ifndef ALTTP_QUEST_HPP #ifndef ALTTP_QUEST_HPP
#define ALTTP_QUEST_HPP #define ALTTP_QUEST_HPP
#include "Types.hpp" #include "Athena/Global.hpp"
#include <string> #include <string>
#include <vector> #include <vector>
#include "Athena/ALTTPStructs.hpp" #include "Athena/ALTTPStructs.hpp"

View File

@ -1,116 +0,0 @@
#ifndef EXCEPTION_HPP
#define EXCEPTION_HPP
#include <string>
#include <stdarg.h>
#include "Athena/Utility.hpp"
#include "Athena/Global.hpp"
#define __STRX(x) #x
#define __STR(x) __STRX(x)
#define __LINE_STRING__ __STR(__LINE__)
namespace Athena
{
namespace error
{
/*! \class Exception
* \brief The baseclass for all Exceptions.
*
* <b>Do Not</b> use Exception directly, instead create an appropriate
* Exception class and inherit from this baseclass.
*/
class Exception
{
public:
/*! \brief The constructor for an Exception
* \param message The error message to throw
*/
inline Exception(const std::string& message, const std::string& file, const std::string& function, const int line) :
m_message(message),
m_file(file),
m_function(function),
m_line(line),
m_exceptionName("Exception")
{
}
/*! \brief Returns the Error message of the exception
* \return std::string The error message
*/
inline std::string message() const
{
return m_exceptionName + (m_message.empty() ? "" : ": " + m_message);
}
inline std::string file() const
{
return m_file;
}
inline std::string function() const
{
return m_function;
}
inline int line() const
{
return m_line;
}
inline std::string formattedMessage() const
{
return Athena::utility::sprintf("%s : %s (%i) %s", m_file.c_str(), m_function.c_str(), m_line, message().c_str());
}
protected:
std::string m_message; //!< The error message string
std::string m_file;
std::string m_function;
int m_line;
std::string m_exceptionName;
};
} // error
} // Athena
#ifdef _MSC_VER
#define THROW_EXCEPTION(args,...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, __VA_ARGS__); return; \
} else { std::string msg = Athena::utility::sprintf(__VA_ARGS__); \
throw Athena::error::Exception(std::string("Exception: ")+msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#elif defined(__GNUC__)
#define THROW_EXCEPTION(args...) \
do { \
if (atGetExceptionHandler()) { atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return; \
} else { \
std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::Exception(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#ifdef _MSC_VER
#define THROW_EXCEPTION_RETURN(ret, args,...) \
do { \
if (atGetExceptionHandler()) \
{ \
atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, __VA_ARGS__); \
return ret; \
} else { \
std::string msg = Athena::utility::sprintf(__VA_ARGS__); \
throw Athena::error::Exception(std::string("Exception: ")+msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#elif defined(__GNUC__)
#define THROW_EXCEPTION_RETURN(ret, args...) \
do { \
if (atGetExceptionHandler()) { atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return ret; \
} else { \
std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::Exception(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#endif // EXCEPTION_HPP

View File

@ -1,68 +0,0 @@
#ifndef FILENOTFOUNDEXCEPTION_HPP
#define FILENOTFOUNDEXCEPTION_HPP
#include "Athena/Exception.hpp"
namespace Athena
{
namespace error
{
/*! \class FileNotFoundException
* \brief An excpeption thrown when a file could not be found at the given path.
*
* This should only be thrown when the Stream is unable to open a file.<br />
* <br />
* It is <b>NOT</b> appropriate to use <b>throw new</b> so avoid doing so,
* keeping things on the stack as much as possible is very important for speed.
*/
class FileNotFoundException : public Exception
{
public:
/*! \brief The constructor for an FileNotFoundException
* \param filename The path of the offending file.
*/
inline FileNotFoundException(const std::string& filename, const std::string& file, const std::string& function, const int line) :
Exception(std::string("FileNotFoundException: Could not find file \"") + filename + std::string("\", please check that it exists."), file, function, line),
m_filename(filename)
{
m_exceptionName = "FileNotFoundException";
}
/*! \brief Returns the path of the offending file.
* \return std::string The filename of the file including the path.
*/
inline std::string filename() const { return m_filename; }
private:
std::string m_filename;
};
} // error
} // Athena
#ifndef THROW_FILE_NOT_FOUND_EXCEPTION
#define THROW_FILE_NOT_FOUND_EXCEPTION(msg) \
do { \
if (atGetExceptionHandler()) \
{ \
atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, msg); \
return; \
} \
else \
throw Athena::error::FileNotFoundException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} while(0)
#endif
#ifndef THROW_FILE_NOT_FOUND_EXCEPTION_RETURN
#define THROW_FILE_NOT_FOUND_EXCEPTION_RETURN(ret, msg) \
do { \
if (atGetExceptionHandler()) \
{ \
atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, msg); \
return ret; \
} \
else \
throw Athena::error::FileNotFoundException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} while(0)
#endif
#endif // FILENOTFOUNDEXCEPTION_HPP

View File

@ -51,21 +51,6 @@ typedef struct _stat64 stat64_t;
typedef struct stat64 stat64_t; typedef struct stat64 stat64_t;
#endif #endif
#ifndef aDebug
#define aDebug() \
std::cout << __FILE__ << "(" << __LINE__ << ") " << AT_PRETTY_FUNCTION << ": "
#endif
#ifndef aError
#define aError() \
std::cerr << __FILE__ << "(" << __LINE__ << ") " << AT_PRETTY_FUNCTION << ": "
#endif
#ifndef aPrint
#define aPrint() std::cout
#endif
#define aEnd() '\n'
#ifndef BLOCKSZ #ifndef BLOCKSZ
#define BLOCKSZ 512 #define BLOCKSZ 512
#endif #endif
@ -75,6 +60,16 @@ typedef struct stat64 stat64_t;
namespace Athena namespace Athena
{ {
namespace error
{
enum Level
{
MESSAGE,
WARNING,
ERROR,
FATAL
};
}
enum SeekOrigin enum SeekOrigin
{ {
Begin, Begin,
@ -91,7 +86,6 @@ enum Endian
#ifndef ATHENA_NO_SAKURA #ifndef ATHENA_NO_SAKURA
namespace Sakura namespace Sakura
{ {
template <typename T> template <typename T>
class Vector2D class Vector2D
{ {
@ -118,11 +112,83 @@ typedef Vector2D<float> Vector2Df;
#endif // ATHENA_NO_SAKURA #endif // ATHENA_NO_SAKURA
} // Athena } // Athena
typedef void (*atEXCEPTION_HANDLER)(const std::string& file, const std::string& function, int line, const std::string&, ...); typedef void (*atEXCEPTION_HANDLER)(const Athena::error::Level& level, const std::string& file, const std::string& function, int line, const char* fmt, ...);
atEXCEPTION_HANDLER atGetExceptionHandler(); atEXCEPTION_HANDLER atGetExceptionHandler();
void atSetExceptionHandler(atEXCEPTION_HANDLER func); void atSetExceptionHandler(atEXCEPTION_HANDLER func);
std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin); std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin);
std::ostream& operator<<(std::ostream& os, const Athena::Endian& endian); std::ostream& operator<<(std::ostream& os, const Athena::Endian& endian);
#ifdef _MSC_VER
#ifndef NDEBUG
#define atDebug(fmt, ...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::MESSAGE, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#else
#define atDebug(fmt, ...)
#endif
#define atMessage(fmt, ...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::MESSAGE, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define atWarning(fmt, ...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::WARNING, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define atError(fmt, ...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::ERROR, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#define atFatal(fmt, ...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::FATAL, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt, ##__VA_ARGS__); \
} while(0)
#elif defined(__GNUC__)
#ifndef NDEBUG
#define atDebug(fmt...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::MESSAGE, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while(0)
#else // _MSC_VER
#define atDebug(fmt, ...)
#endif // NDEBUG
#define atMessage(fmt...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::MESSAGE, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while(0)
#define atWarning(fmt...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::WARNING, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while(0)
#define atError(fmt...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::ERROR, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while(0)
#define atFatal(fmt...) \
do { atEXCEPTION_HANDLER __handler = atGetExceptionHandler(); \
if (__handler) \
__handler(Athena::error::FATAL, __FILE__, AT_PRETTY_FUNCTION, __LINE__, fmt); \
} while(0)
#endif // defined(__GNUC__)
#endif // GLOBAL_HPP #endif // GLOBAL_HPP

View File

@ -1,75 +0,0 @@
#ifndef IOEXCEPTION_HPP
#define IOEXCEPTION_HPP
#include "Athena/Exception.hpp"
namespace Athena
{
namespace error
{
/*! \class IOException
* \brief An excpeption thrown on inappropriate IO calls.
*
* This should only be thrown when the library tries to write to a buffer
* e.g when the position is greater than the position and the stream
* is not set to autoresize.<br />
* <br />
* It is <b>NOT</b> appropriate to use <b>throw new</b> so avoid doing so,
* keeping things on the stack as much as possible is very important for speed.
*/
class IOException : public Exception
{
public:
/*! \brief The constructor for an IOException
* \param message The error message to throw
*/
inline IOException(const std::string& message, const std::string& file, const std::string& function, const int line) :
Exception(message, file, function, line)
{
m_exceptionName = "IOException";
}
};
} // error
} // Athena
#ifdef _MSC_VER
#define THROW_IO_EXCEPTION(args, ...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args, __VA_ARGS__); return; \
} else { \
std::string msg = Athena::utility::sprintf(args, __VA_ARGS__); \
throw Athena::error::IOException(std::string("IOException: ") + msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while (0)
#elif defined(__GNUC__)
#define THROW_IO_EXCEPTION(args...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return; \
} else { std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::IOException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#ifdef _MSC_VER
#define THROW_IO_EXCEPTION_RETURN(ret, args, ...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args, __VA_ARGS__); return ret; \
} else { \
std::string msg = Athena::utility::sprintf(args, __VA_ARGS__); \
throw Athena::error::IOException(std::string("IOException: ") + msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while (0)
#elif defined(__GNUC__)
#define THROW_IO_EXCEPTION_RETURN(ret, args...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return ret; \
} else { std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::IOException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#endif // IOEXCEPTION_HPP

View File

@ -2,7 +2,6 @@
#define STREAM_HPP #define STREAM_HPP
#include "Global.hpp" #include "Global.hpp"
#include "Athena/NotImplementedException.hpp"
namespace Athena namespace Athena
{ {

View File

@ -1,65 +0,0 @@
#ifndef INVALIDDATAEXCEPTION_HPP
#define INVALIDDATAEXCEPTION_HPP
#include "Athena/Exception.hpp"
#include <sstream>
namespace Athena
{
namespace error
{
/*! \class InvalidDataException
* \brief An exception thrown on Invalid Data calls.
*
* This should only be thrown when the library tries to
* e.g pass a NULL pointer to a function which requires a valid pointer.
* <br />
* It is <b>NOT</b> appropriate to use <b>throw new</b> so avoid doing so,
* keeping things on the stack as much as possible is very important for speed.
*/
class InvalidDataException : public Exception
{
public:
inline InvalidDataException(const std::string& error, const std::string& file, const std::string& function, const int line)
: Exception(("InvalidDataException") + error, file, function, line)
{
m_exceptionName = "InvalidDataException";
}
};
} // error
} // Athena
#ifdef _MSC_VER
#define THROW_INVALID_DATA_EXCEPTION(args, ...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args, __VA_ARGS__); return; } \
else { std::string msg = Athena::utility::sprintf(args, __VA_ARGS__); \
throw Athena::error::InvalidDataException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#elif defined(__GNUC__)
#define THROW_INVALID_DATA_EXCEPTION(args...) \
do { if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return; } \
else { std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::InvalidDataException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#ifdef _MSC_VER
#define THROW_INVALID_DATA_EXCEPTION_RETURN(ret, args, ...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args, __VA_ARGS__); return ret; } \
else { std::string msg = Athena::utility::sprintf(args, __VA_ARGS__); \
throw Athena::error::InvalidDataException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#elif defined(__GNUC__)
#define THROW_INVALID_DATA_EXCEPTION_RETURN(ret, args...) \
do { if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return ret; } \
else { std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::InvalidDataException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#endif // INVALIDDATAEXCEPTION_HPP

View File

@ -1,76 +0,0 @@
#ifndef INVALID_OPERATION_EXCEPTION_HPP
#define INVALID_OPERATION_EXCEPTION_HPP
#include <string>
#include <stdarg.h>
#include "Athena/Exception.hpp"
namespace Athena
{
namespace error
{
/*! \class InvalidOperationException
* \brief An excpeption thrown on Invalid Operations calls.
*
* This should only be thrown when the library tries to
* e.g pass a NULL pointer to a function which requires a valid pointer.
* <br />
* It is <b>NOT</b> appropriate to use <b>throw new</b> so avoid doing so,
* keeping things on the stack as much as possible is very important for speed.
*/
class InvalidOperationException : public Exception
{
public:
/*! \brief The constructor for an InvalidOperationException
* \param error The error message to throw
*/
inline InvalidOperationException(const std::string& message, const std::string& file, const std::string& function, const int line) :
Exception(message, file, function, line)
{
m_exceptionName = "InvalidOperationException";
}
};
} // error
} // Athena
#ifdef _MSC_VER
#define THROW_INVALID_OPERATION_EXCEPTION(args, ...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args, __VA_ARGS__); return; \
} else { \
std::string msg = Athena::utility::sprintf(args , __VA_ARGS__); \
\
throw Athena::error::InvalidOperationException(std::string("InvalidOperationException: ") + msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
\
} \
} while (0)
#elif defined (__GNUC__)
#define THROW_INVALID_OPERATION_EXCEPTION(args...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return; \
} else { std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::InvalidOperationException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#ifdef _MSC_VER
#define THROW_INVALID_OPERATION_EXCEPTION_RETURN(ret, args, ...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args, __VA_ARGS__); return ret; \
} else { \
std::string msg = Athena::utility::sprintf(args, __VA_ARGS__); \
\
throw Athena::error::InvalidOperationException(std::string("InvalidOperationException: ") + msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while (0)
#elif defined(__GNUC__)
#define THROW_INVALID_OPERATION_EXCEPTION_RETURN(ret, args...) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, args); return ret; \
} else { std::string msg = Athena::utility::sprintf(args); \
throw Athena::error::InvalidOperationException(msg, __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif
#endif // INVALID_OPERATION_EXCEPTION_HPP

View File

@ -1,37 +0,0 @@
#ifndef NOTIMPLEMENTEDEXCEPTION_HPP
#define NOTIMPLEMENTEDEXCEPTION_HPP
#include "Athena/Exception.hpp"
namespace Athena
{
namespace error
{
class NotImplementedException : public Exception
{
public:
NotImplementedException(const std::string& message, const std::string& file, const std::string& function, const int line) :
Exception(message, file, function, line)
{
m_exceptionName = "NotImplementedException";
}
};
} // error
} // Athena
#define THROW_NOT_IMPLEMENTED_EXCEPTION() \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, "NotImplementedException"); return; \
} else { \
throw Athena::error::NotImplementedException(std::string(), __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#define THROW_NOT_IMPLEMENTED_EXCEPTION_RETURN(ret) \
do { \
if (atGetExceptionHandler()) {atGetExceptionHandler()(__FILE__, AT_PRETTY_FUNCTION, __LINE__, "NotImplementedException"); return ret; \
} else { \
throw Athena::error::NotImplementedException(std::string(), __FILE__, AT_PRETTY_FUNCTION, __LINE__); \
} \
} while(0)
#endif // NOTIMPLEMENTEDEXCEPTION_HPP

View File

@ -17,8 +17,6 @@
#include "Athena/ALTTPFile.hpp" #include "Athena/ALTTPFile.hpp"
#include "Athena/ALTTPQuest.hpp" #include "Athena/ALTTPQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
namespace Athena namespace Athena
{ {
ALTTPFile::ALTTPFile() ALTTPFile::ALTTPFile()
@ -33,7 +31,10 @@ ALTTPFile::ALTTPFile(std::vector<ALTTPQuest*> quests, std::vector<ALTTPQuest*> b
void ALTTPFile::setQuest(atUint32 id, ALTTPQuest* val) void ALTTPFile::setQuest(atUint32 id, ALTTPQuest* val)
{ {
if (id > m_quests.size()) if (id > m_quests.size())
THROW_INVALID_OPERATION_EXCEPTION("index out of range"); {
atWarning("index out of range");
return;
}
m_quests[id] = val; m_quests[id] = val;
} }
@ -45,7 +46,10 @@ std::vector<ALTTPQuest*> ALTTPFile::questList() const
ALTTPQuest* ALTTPFile::quest(atUint32 id) const ALTTPQuest* ALTTPFile::quest(atUint32 id) const
{ {
if (id > m_quests.size()) if (id > m_quests.size())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(nullptr, "index out of range"); {
atWarning("index out of range");
return nullptr;
}
return m_quests[id]; return m_quests[id];
} }

View File

@ -247,7 +247,7 @@ ALTTPDungeonItemFlags ALTTPFileReader::readDungeonFlags()
flags.HyruleCastle = (flagsByte >> 6) & 1; flags.HyruleCastle = (flagsByte >> 6) & 1;
flags.SewerPassage = (flagsByte >> 7) & 1; flags.SewerPassage = (flagsByte >> 7) & 1;
aDebug() << std::hex << flags.flags1 << " " << flags.flags2 << std::dec << std::endl; atDebug("%x %x", flags.flags1, flags.flags2);
return flags; return flags;
} }

View File

@ -15,7 +15,6 @@
// along with libAthena. If not, see <http://www.gnu.org/licenses/> // along with libAthena. If not, see <http://www.gnu.org/licenses/>
#include "Athena/ALTTPQuest.hpp" #include "Athena/ALTTPQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
#include <iostream> #include <iostream>
namespace Athena namespace Athena
@ -72,7 +71,10 @@ std::vector<ALTTPOverworldEvent*> ALTTPQuest::overworldEvents() const
ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const ALTTPOverworldEvent* ALTTPQuest::overworldEvent(atUint32 id) const
{ {
if (id > m_overworldEvents.size() - 1) if (id > m_overworldEvents.size() - 1)
THROW_INVALID_OPERATION_EXCEPTION_RETURN(nullptr, "index out of range"); {
atWarning("index out of range");
return nullptr;
}
return m_overworldEvents[id]; return m_overworldEvents[id];
} }
@ -303,7 +305,10 @@ void ALTTPQuest::setDungeonKeys(std::vector<atUint8> val)
void ALTTPQuest::setDungeonKeys(atUint32 id, atUint8 val) void ALTTPQuest::setDungeonKeys(atUint32 id, atUint8 val)
{ {
if (id > m_dungeonKeys.size() - 1) if (id > m_dungeonKeys.size() - 1)
THROW_INVALID_OPERATION_EXCEPTION("index out of range"); {
atWarning("index out of range");
return;
}
m_dungeonKeys[id] = val; m_dungeonKeys[id] = val;
} }
@ -311,7 +316,10 @@ void ALTTPQuest::setDungeonKeys(atUint32 id, atUint8 val)
atUint8 ALTTPQuest::dungeonKeys(atUint32 id) const atUint8 ALTTPQuest::dungeonKeys(atUint32 id) const
{ {
if (id > m_dungeonKeys.size() - 1) if (id > m_dungeonKeys.size() - 1)
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "index out of range"); {
atWarning("index out of range");
return 0;
}
return m_dungeonKeys[id]; return m_dungeonKeys[id];
} }
@ -400,7 +408,10 @@ void ALTTPQuest::setOldManFlags(std::vector<atUint8> flags)
void ALTTPQuest::setOldManFlag(atUint32 id, atUint8 val) void ALTTPQuest::setOldManFlag(atUint32 id, atUint8 val)
{ {
if (id > m_oldManFlags.size() - 1) if (id > m_oldManFlags.size() - 1)
THROW_INVALID_OPERATION_EXCEPTION("index out of range"); {
atWarning("index out of range");
return;
}
m_oldManFlags[id] = val; m_oldManFlags[id] = val;
} }
@ -408,8 +419,10 @@ void ALTTPQuest::setOldManFlag(atUint32 id, atUint8 val)
atUint8 ALTTPQuest::oldManFlag(atUint32 id) atUint8 ALTTPQuest::oldManFlag(atUint32 id)
{ {
if (id > m_oldManFlags.size() - 1) if (id > m_oldManFlags.size() - 1)
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "index out of range"); {
atWarning("index out of range");
return 0;
}
return m_oldManFlags[id]; return m_oldManFlags[id];
} }
@ -436,7 +449,10 @@ void ALTTPQuest::setUnknown1(std::vector<atUint8> flags)
void ALTTPQuest::setUnknown1(atUint32 id, atUint8 val) void ALTTPQuest::setUnknown1(atUint32 id, atUint8 val)
{ {
if (id > m_unknown1.size()) if (id > m_unknown1.size())
THROW_INVALID_OPERATION_EXCEPTION("index out of range"); {
atWarning("index out of range");
return;
}
m_unknown1[id] = val; m_unknown1[id] = val;
} }
@ -444,7 +460,10 @@ void ALTTPQuest::setUnknown1(atUint32 id, atUint8 val)
atUint8 ALTTPQuest::unknown1(atUint32 id) atUint8 ALTTPQuest::unknown1(atUint32 id)
{ {
if (id > m_unknown1.size()) if (id > m_unknown1.size())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "index out of range"); {
atWarning("index out of range");
return 0;
}
return m_unknown1[id]; return m_unknown1[id];
} }
@ -462,7 +481,10 @@ void ALTTPQuest::setPlayerName(std::vector<atUint16> playerName)
void ALTTPQuest::setPlayerName(const std::string& playerName) void ALTTPQuest::setPlayerName(const std::string& playerName)
{ {
if (playerName == std::string() || playerName.size() > 6) if (playerName == std::string() || playerName.size() > 6)
THROW_INVALID_OPERATION_EXCEPTION("index out of range"); {
atWarning("index out of range");
return;
}
m_playerName.clear(); m_playerName.clear();
@ -675,7 +697,10 @@ void ALTTPQuest::setDungeonDeathTotals(std::vector<atUint16> val)
void ALTTPQuest::setDungeonDeathTotal(atUint32 id, atUint16 val) void ALTTPQuest::setDungeonDeathTotal(atUint32 id, atUint16 val)
{ {
if (id > m_dungeonDeathTotals.size()) if (id > m_dungeonDeathTotals.size())
THROW_INVALID_OPERATION_EXCEPTION("index out of range"); {
atWarning("index out of range");
return;
}
m_dungeonDeathTotals[id] = val; m_dungeonDeathTotals[id] = val;
} }
@ -683,7 +708,10 @@ void ALTTPQuest::setDungeonDeathTotal(atUint32 id, atUint16 val)
atUint16 ALTTPQuest::dungeonDeathTotal(atUint32 id) const atUint16 ALTTPQuest::dungeonDeathTotal(atUint32 id) const
{ {
if (id > m_dungeonDeathTotals.size()) if (id > m_dungeonDeathTotals.size())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "index out of range"); {
atWarning("index out of range");
return 0;
}
return m_dungeonDeathTotals[id]; return m_dungeonDeathTotals[id];
} }

View File

@ -1,5 +1,4 @@
#include "Athena/Compression.hpp" #include "Athena/Compression.hpp"
#include "Athena/Exception.hpp"
#include <lzo/lzo1x.h> #include <lzo/lzo1x.h>
#include <iostream> #include <iostream>
#include <zlib.h> #include <zlib.h>

View File

@ -1,8 +1,4 @@
#include "Athena/FileReader.hpp" #include "Athena/FileReader.hpp"
#include "Athena/FileNotFoundException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/IOException.hpp"
#if _WIN32 #if _WIN32
#include "win32_largefilewrapper.h" #include "win32_largefilewrapper.h"
@ -35,7 +31,10 @@ void FileReader::open()
m_fileHandle = fopen(m_filename.c_str(), "rb"); m_fileHandle = fopen(m_filename.c_str(), "rb");
if (!m_fileHandle) if (!m_fileHandle)
THROW_FILE_NOT_FOUND_EXCEPTION(m_filename); {
atError("File not found '%s'", m_filename.c_str());
return;
}
// ensure we're at the beginning of the file // ensure we're at the beginning of the file
rewind(m_fileHandle); rewind(m_fileHandle);
@ -44,7 +43,10 @@ void FileReader::open()
void FileReader::close() void FileReader::close()
{ {
if (!m_fileHandle) if (!m_fileHandle)
THROW_INVALID_OPERATION_EXCEPTION("Cannot close an unopened stream"); {
atError("Cannot close an unopened stream");
return;
}
fclose(m_fileHandle); fclose(m_fileHandle);
m_fileHandle = NULL; m_fileHandle = NULL;
@ -72,7 +74,8 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
if (m_offset > length()) if (m_offset > length())
{ {
oldOff = m_offset; oldOff = m_offset;
THROW_INVALID_OPERATION_EXCEPTION("Unable to seek in file"); atError("Unable to seek in file");
return;
} }
size_t block = m_offset / m_blockSize; size_t block = m_offset / m_blockSize;
@ -84,13 +87,16 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
} }
} }
else if (fseeko64(m_fileHandle, pos, (int)origin) != 0) else if (fseeko64(m_fileHandle, pos, (int)origin) != 0)
THROW_INVALID_OPERATION_EXCEPTION("Unable to seek in file"); atError("Unable to seek in file");
} }
atUint64 FileReader::position() const atUint64 FileReader::position() const
{ {
if (!isOpen()) if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "File not open"); {
atError("File not open");
return 0;
}
if (m_blockSize > 0) if (m_blockSize > 0)
return m_offset; return m_offset;
@ -101,7 +107,10 @@ atUint64 FileReader::position() const
atUint64 FileReader::length() const atUint64 FileReader::length() const
{ {
if (!isOpen()) if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "File not open"); {
atError("File not open");
return 0;
}
return utility::fileSize(m_filename); return utility::fileSize(m_filename);
} }
@ -109,7 +118,10 @@ atUint64 FileReader::length() const
atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len) atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
{ {
if (!isOpen()) if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "File not open for reading"); {
atError("File not open for reading");
return 0;
}
if (m_blockSize <= 0) if (m_blockSize <= 0)
return fread(buf, 1, len, m_fileHandle); return fread(buf, 1, len, m_fileHandle);

View File

@ -1,8 +1,4 @@
#include "Athena/FileWriter.hpp" #include "Athena/FileWriter.hpp"
#include "Athena/FileNotFoundException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/IOException.hpp"
#if _WIN32 #if _WIN32
#include "win32_largefilewrapper.h" #include "win32_largefilewrapper.h"
@ -36,7 +32,10 @@ void FileWriter::open(bool overwrite)
m_fileHandle = fopen(m_filename.c_str(), "r+b"); m_fileHandle = fopen(m_filename.c_str(), "r+b");
if (!m_fileHandle) if (!m_fileHandle)
THROW_FILE_NOT_FOUND_EXCEPTION(m_filename); {
atError("Unable to open file '%s'", m_filename.c_str());
return;
}
// ensure we're at the beginning of the file // ensure we're at the beginning of the file
rewind(m_fileHandle); rewind(m_fileHandle);
@ -45,7 +44,10 @@ void FileWriter::open(bool overwrite)
void FileWriter::close() void FileWriter::close()
{ {
if (!m_fileHandle) if (!m_fileHandle)
THROW_INVALID_OPERATION_EXCEPTION("Cannot close an unopened stream"); {
atError("Cannot close an unopened stream");
return;
}
fclose(m_fileHandle); fclose(m_fileHandle);
m_fileHandle = NULL; m_fileHandle = NULL;
@ -55,7 +57,7 @@ void FileWriter::close()
void FileWriter::seek(atInt64 pos, SeekOrigin origin) void FileWriter::seek(atInt64 pos, SeekOrigin origin)
{ {
if (fseeko64(m_fileHandle, pos, (int)origin) != 0) if (fseeko64(m_fileHandle, pos, (int)origin) != 0)
THROW_IO_EXCEPTION("Unable to seek in file"); atError("Unable to seek in file");
} }
atUint64 FileWriter::position() const atUint64 FileWriter::position() const
@ -71,10 +73,13 @@ atUint64 FileWriter::length() const
void FileWriter::writeUBytes(const atUint8* data, atUint64 len) void FileWriter::writeUBytes(const atUint8* data, atUint64 len)
{ {
if (!isOpen()) if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing"); {
atError("File not open for writing");
return;
}
if (fwrite(data, 1, len, m_fileHandle) != len) if (fwrite(data, 1, len, m_fileHandle) != len)
THROW_IO_EXCEPTION("Unable to write to stream"); atError("Unable to write to stream");
} }
} }

View File

@ -1,4 +1,7 @@
#include "Athena/Global.hpp" #include "Athena/Global.hpp"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin) std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin)
{ {
@ -38,7 +41,31 @@ std::ostream& operator<<(std::ostream& os, const Athena::Endian& endian)
} }
static atEXCEPTION_HANDLER g_atExceptionHandler = nullptr; static void __defaultExceptionHandler(const Athena::error::Level& level, const std::string& file, const std::string& function, int line, const char* fmt, ...)
{
std::string levelStr;
switch(level)
{
case Athena::error::WARNING:
levelStr = "[WARNING] ";
break;
case Athena::error::ERROR:
levelStr = "[ERROR ] ";
break;
case Athena::error::FATAL:
levelStr = "[FATAL ] ";
break;
default: break;
}
va_list vl;
va_start(vl, fmt);
std::string msg = Athena::utility::vsprintf(fmt, vl);
va_end(vl);
std::cerr << levelStr << " " << file << " " << function << "(" << line << "): " << msg << std::endl;
}
static atEXCEPTION_HANDLER g_atExceptionHandler = __defaultExceptionHandler;
atEXCEPTION_HANDLER atGetExceptionHandler() atEXCEPTION_HANDLER atGetExceptionHandler()
{ {
@ -48,5 +75,8 @@ atEXCEPTION_HANDLER atGetExceptionHandler()
void atSetExceptionHandler(atEXCEPTION_HANDLER func) void atSetExceptionHandler(atEXCEPTION_HANDLER func)
{ {
g_atExceptionHandler = func; if (func)
g_atExceptionHandler = func;
else
g_atExceptionHandler = __defaultExceptionHandler;
} }

View File

@ -1,8 +1,4 @@
#include "Athena/MemoryReader.hpp" #include "Athena/MemoryReader.hpp"
#include "Athena/IOException.hpp"
#include "Athena/FileNotFoundException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -24,20 +20,32 @@ MemoryReader::MemoryReader(const atUint8* data, atUint64 length)
m_position(0) m_position(0)
{ {
if (!data) if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL"); {
atError("data cannot be NULL");
return;
}
if (length == 0) if (length == 0)
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0"); {
atError("length cannot be 0");
return;
}
} }
MemoryCopyReader::MemoryCopyReader(const atUint8* data, atUint64 length) MemoryCopyReader::MemoryCopyReader(const atUint8* data, atUint64 length)
: MemoryReader(data, length) : MemoryReader(data, length)
{ {
if (!data) if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL"); {
atError("data cannot be NULL");
return;
}
if (length == 0) if (length == 0)
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0"); {
atError("length cannot be 0");
return;
}
m_dataCopy.reset(new atUint8[m_length]); m_dataCopy.reset(new atUint8[m_length]);
m_data = m_dataCopy.get(); m_data = m_dataCopy.get();
@ -50,21 +58,30 @@ void MemoryReader::seek(atInt64 position, SeekOrigin origin)
{ {
case SeekOrigin::Begin: case SeekOrigin::Begin:
if ((position < 0 || (atInt64)position > (atInt64)m_length)) if ((position < 0 || (atInt64)position > (atInt64)m_length))
THROW_IO_EXCEPTION("Position %0.8X outside stream bounds ", position); {
atError("Position %0.8X outside stream bounds ", position);
return;
}
m_position = position; m_position = position;
break; break;
case SeekOrigin::Current: case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0 || (m_position + position) > m_length)) if ((((atInt64)m_position + position) < 0 || (m_position + position) > m_length))
THROW_IO_EXCEPTION("Position %0.8X outside stream bounds ", position); {
atError("Position %0.8X outside stream bounds ", position);
return;
}
m_position += position; m_position += position;
break; break;
case SeekOrigin::End: case SeekOrigin::End:
if ((((atInt64)m_length - position < 0) || (m_length - position) > m_length)) if ((((atInt64)m_length - position < 0) || (m_length - position) > m_length))
THROW_IO_EXCEPTION("Position %0.8X outside stream bounds ", position); {
atError("Position %0.8X outside stream bounds ", position);
return;
}
m_position = m_length - position; m_position = m_length - position;
break; break;
@ -98,7 +115,10 @@ atUint8* MemoryReader::data() const
atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length) atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 length)
{ {
if (m_position + length > m_length) if (m_position + length > m_length)
THROW_IO_EXCEPTION_RETURN(0, "Position %0.8X outside stream bounds ", m_position); {
atError("Position %0.8X outside stream bounds ", m_position);
return 0;
}
memcpy(buf, (const atUint8*)(m_data + m_position), length); memcpy(buf, (const atUint8*)(m_data + m_position), length);
m_position += length; m_position += length;
@ -112,7 +132,10 @@ void MemoryCopyReader::loadData()
in = fopen(m_filepath.c_str(), "rb"); in = fopen(m_filepath.c_str(), "rb");
if (!in) if (!in)
THROW_FILE_NOT_FOUND_EXCEPTION(m_filepath); {
atError("Unable to open file '%s'", m_filepath.c_str());
return;
}
rewind(in); rewind(in);
@ -131,7 +154,10 @@ void MemoryCopyReader::loadData()
atInt64 ret = fread(m_dataCopy.get() + done, 1, blocksize, in); atInt64 ret = fread(m_dataCopy.get() + done, 1, blocksize, in);
if (ret < 0) if (ret < 0)
THROW_IO_EXCEPTION("Error reading data from disk"); {
atError("Error reading data from disk");
return;
}
else if (ret == 0) else if (ret == 0)
break; break;

View File

@ -1,8 +1,4 @@
#include "Athena/MemoryWriter.hpp" #include "Athena/MemoryWriter.hpp"
#include "Athena/IOException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/FileNotFoundException.hpp"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -24,10 +20,16 @@ MemoryWriter::MemoryWriter(atUint8* data, atUint64 length)
m_position(0) m_position(0)
{ {
if (!data) if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL"); {
atError("data cannot be NULL");
return;
}
if (length == 0) if (length == 0)
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0"); {
atError("length cannot be 0");
return;
}
} }
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length) MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
@ -37,7 +39,10 @@ MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
m_position = 0; m_position = 0;
if (length == 0) if (length == 0)
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0"); {
atError("length cannot be 0");
return;
}
m_dataCopy.reset(new atUint8[length]); m_dataCopy.reset(new atUint8[length]);
m_data = m_dataCopy.get(); m_data = m_dataCopy.get();
@ -55,7 +60,10 @@ MemoryCopyWriter::MemoryCopyWriter(const std::string& filename)
m_data = m_dataCopy.get(); m_data = m_dataCopy.get();
if (!m_data) if (!m_data)
THROW_IO_EXCEPTION("Could not allocate memory!"); {
atError("Could not allocate memory!");
return;
}
memset(m_data, 0, m_length); memset(m_data, 0, m_length);
} }
@ -66,30 +74,48 @@ void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
{ {
case SeekOrigin::Begin: case SeekOrigin::Begin:
if (position < 0) if (position < 0)
THROW_IO_EXCEPTION("Position outside stream bounds"); {
atError("Position outside stream bounds");
return;
}
if ((atUint64)position > m_length) if ((atUint64)position > m_length)
THROW_IO_EXCEPTION("data exceeds available buffer space"); {
atError("data exceeds available buffer space");
return;
}
m_position = position; m_position = position;
break; break;
case SeekOrigin::Current: case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0)) if ((((atInt64)m_position + position) < 0))
THROW_IO_EXCEPTION("Position outside stream bounds"); {
atError("Position outside stream bounds");
return;
}
if (m_position + position > m_length) if (m_position + position > m_length)
THROW_IO_EXCEPTION("data exceeds available buffer space"); {
atError("data exceeds available buffer space");
return;
}
m_position += position; m_position += position;
break; break;
case SeekOrigin::End: case SeekOrigin::End:
if (((atInt64)m_length - position) < 0) if (((atInt64)m_length - position) < 0)
THROW_IO_EXCEPTION("Position outside stream bounds"); {
atError("Position outside stream bounds");
return;
}
if ((atUint64)position > m_length) if ((atUint64)position > m_length)
THROW_IO_EXCEPTION("data exceeds available buffer space"); {
atError("data exceeds available buffer space");
return;
}
m_position = m_length - position; m_position = m_length - position;
break; break;
@ -102,7 +128,10 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
{ {
case SeekOrigin::Begin: case SeekOrigin::Begin:
if (position < 0) if (position < 0)
THROW_IO_EXCEPTION("Position outside stream bounds"); {
atError("Position outside stream bounds");
return;
}
if ((atUint64)position > m_length) if ((atUint64)position > m_length)
resize(position); resize(position);
@ -112,7 +141,10 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
case SeekOrigin::Current: case SeekOrigin::Current:
if ((((atInt64)m_position + position) < 0)) if ((((atInt64)m_position + position) < 0))
THROW_IO_EXCEPTION("Position outside stream bounds"); {
atError("Position outside stream bounds");
return;
}
if (m_position + position > m_length) if (m_position + position > m_length)
resize(m_position + position); resize(m_position + position);
@ -122,7 +154,10 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
case SeekOrigin::End: case SeekOrigin::End:
if (((atInt64)m_length - position) < 0) if (((atInt64)m_length - position) < 0)
THROW_IO_EXCEPTION("Position outside stream bounds"); {
atError("Position outside stream bounds");
return;
}
if ((atUint64)position > m_length) if ((atUint64)position > m_length)
resize(position); resize(position);
@ -160,7 +195,10 @@ atUint8* MemoryWriter::data() const
void MemoryWriter::save(const std::string& filename) void MemoryWriter::save(const std::string& filename)
{ {
if (filename.empty() && m_filepath.empty()) if (filename.empty() && m_filepath.empty())
THROW_INVALID_OPERATION_EXCEPTION("No file specified, cannot save."); {
atError("No file specified, cannot save.");
return;
}
if (!filename.empty()) if (!filename.empty())
m_filepath = filename; m_filepath = filename;
@ -168,7 +206,10 @@ void MemoryWriter::save(const std::string& filename)
FILE* out = fopen(m_filepath.c_str(), "wb"); FILE* out = fopen(m_filepath.c_str(), "wb");
if (!out) if (!out)
THROW_FILE_NOT_FOUND_EXCEPTION(m_filepath); {
atError("Unable to open file '%s'", m_filepath.c_str());
return;
}
atUint64 done = 0; atUint64 done = 0;
atUint64 blocksize = BLOCKSZ; atUint64 blocksize = BLOCKSZ;
@ -181,7 +222,10 @@ void MemoryWriter::save(const std::string& filename)
atInt64 ret = fwrite(m_data + done, 1, blocksize, out); atInt64 ret = fwrite(m_data + done, 1, blocksize, out);
if (ret < 0) if (ret < 0)
THROW_IO_EXCEPTION("Error writing data to disk"); {
atError("Error writing data to disk");
return;
}
else if (ret == 0) else if (ret == 0)
break; break;
@ -195,10 +239,16 @@ void MemoryWriter::save(const std::string& filename)
void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length) void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
{ {
if (!data) if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannnot be NULL"); {
atError("data cannnot be NULL");
return;
}
if (m_position + length > m_length) if (m_position + length > m_length)
THROW_IO_EXCEPTION("data length exceeds available buffer space"); {
atError("data length exceeds available buffer space");
return;
}
memcpy((atInt8*)(m_data + m_position), data, length); memcpy((atInt8*)(m_data + m_position), data, length);
@ -208,7 +258,10 @@ void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length) void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
{ {
if (!data) if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannnot be NULL"); {
atError("data cannnot be NULL");
return;
}
if (m_position + length > m_length) if (m_position + length > m_length)
resize(m_position + length); resize(m_position + length);
@ -221,7 +274,10 @@ void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
void MemoryCopyWriter::resize(atUint64 newSize) void MemoryCopyWriter::resize(atUint64 newSize)
{ {
if (newSize < m_length) if (newSize < m_length)
THROW_INVALID_OPERATION_EXCEPTION("Stream::resize() -> New size cannot be less to the old size."); {
atError("New size cannot be less to the old size.");
return;
}
// Allocate and copy new buffer // Allocate and copy new buffer
atUint8* newArray = new atUint8[newSize]; atUint8* newArray = new atUint8[newSize];

View File

@ -16,7 +16,6 @@
#include "Athena/SkywardSwordFile.hpp" #include "Athena/SkywardSwordFile.hpp"
#include "Athena/SkywardSwordQuest.hpp" #include "Athena/SkywardSwordQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
namespace Athena namespace Athena
{ {
@ -48,7 +47,10 @@ void SkywardSwordFile::addQuest(Athena::SkywardSwordQuest* q)
SkywardSwordQuest* SkywardSwordFile::quest(atUint32 id) SkywardSwordQuest* SkywardSwordFile::quest(atUint32 id)
{ {
if (id > m_quests.size() - 1) if (id > m_quests.size() - 1)
THROW_INVALID_OPERATION_EXCEPTION_RETURN(nullptr, "index out of range"); {
atWarning("index out of range");
return nullptr;
}
return m_quests[id]; return m_quests[id];
} }

View File

@ -17,8 +17,6 @@
#include "Athena/SkywardSwordFileReader.hpp" #include "Athena/SkywardSwordFileReader.hpp"
#include "Athena/SkywardSwordFile.hpp" #include "Athena/SkywardSwordFile.hpp"
#include "Athena/SkywardSwordQuest.hpp" #include "Athena/SkywardSwordQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include <iostream> #include <iostream>
namespace Athena namespace Athena
@ -45,18 +43,27 @@ SkywardSwordFile* SkywardSwordFileReader::read()
try try
{ {
if (base::length() != 0xFBE0) if (base::length() != 0xFBE0)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "File not the expected size of 0xFBE0"); {
atError("File not the expected size of 0xFBE0");
return nullptr;
}
atUint32 magic = base::readUint32(); atUint32 magic = base::readUint32();
if (magic != SkywardSwordFile::USMagic && magic != SkywardSwordFile::JAMagic && magic != SkywardSwordFile::EUMagic) if (magic != SkywardSwordFile::USMagic && magic != SkywardSwordFile::JAMagic && magic != SkywardSwordFile::EUMagic)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Not a valid Skyward Sword save file"); {
atError("Not a valid Skyward Sword save file");
return nullptr;
}
base::seek(0x01C, SeekOrigin::Begin); base::seek(0x01C, SeekOrigin::Begin);
atUint32 headerSize = base::readUint32(); // Seems to be (headerSize - 1) atUint32 headerSize = base::readUint32(); // Seems to be (headerSize - 1)
if (headerSize != 0x1D) if (headerSize != 0x1D)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Invalid header size, Corrupted data?"); {
atError("Invalid header size, Corrupted data?");
return nullptr;
}
// Time to read in each slot // Time to read in each slot
file = new SkywardSwordFile; file = new SkywardSwordFile;

View File

@ -17,8 +17,6 @@
#include "Athena/SkywardSwordFileWriter.hpp" #include "Athena/SkywardSwordFileWriter.hpp"
#include "Athena/SkywardSwordFile.hpp" #include "Athena/SkywardSwordFile.hpp"
#include "Athena/SkywardSwordQuest.hpp" #include "Athena/SkywardSwordQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
namespace Athena namespace Athena
{ {
@ -40,7 +38,10 @@ SkywardSwordFileWriter::SkywardSwordFileWriter(const std::string& filename)
void SkywardSwordFileWriter::write(SkywardSwordFile* file) void SkywardSwordFileWriter::write(SkywardSwordFile* file)
{ {
if (!file) if (!file)
THROW_INVALID_OPERATION_EXCEPTION("file cannot be NULL"); {
atError("file cannot be NULL");
return;
}
atUint32 magic = (file->region() == Region::NTSC ? SkywardSwordFile::USMagic : atUint32 magic = (file->region() == Region::NTSC ? SkywardSwordFile::USMagic :
(file->region() == Region::NTSCJ ? SkywardSwordFile::JAMagic : SkywardSwordFile::EUMagic)); (file->region() == Region::NTSCJ ? SkywardSwordFile::JAMagic : SkywardSwordFile::EUMagic));
@ -55,7 +56,10 @@ void SkywardSwordFileWriter::write(SkywardSwordFile* file)
for (SkywardSwordQuest* q : quests) for (SkywardSwordQuest* q : quests)
{ {
if (q->length() != 0x53C0) if (q->length() != 0x53C0)
THROW_INVALID_DATA_EXCEPTION("q->data() not 0x53C0 bytes in length"); {
atError("q->data() not 0x53C0 bytes in length");
return;
}
// Update the checksums // Update the checksums
q->fixChecksums(); q->fixChecksums();

View File

@ -79,7 +79,7 @@ atUint8* SkywardSwordQuest::skipData() const
void SkywardSwordQuest::setPlayerName(const std::string& name) void SkywardSwordQuest::setPlayerName(const std::string& name)
{ {
if (name.length() > 8) if (name.length() > 8)
aDebug() << "WARNING: name cannot be greater than 8 characters, automatically truncating" << std::endl; atDebug("WARNING: name cannot be greater than 8 characters, automatically truncating");
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv; std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring val = conv.from_bytes(name); std::wstring val = conv.from_bytes(name);

View File

@ -19,9 +19,6 @@
#include "Athena/Sprite.hpp" #include "Athena/Sprite.hpp"
#include "Athena/SpritePart.hpp" #include "Athena/SpritePart.hpp"
#include "Athena/SpriteFrame.hpp" #include "Athena/SpriteFrame.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/IOException.hpp"
#include "Athena/Utility.hpp" #include "Athena/Utility.hpp"
namespace Athena namespace Athena
@ -48,13 +45,19 @@ Sakura::SpriteFile* SpriteFileReader::readFile()
atUint32 magic = base::readUint32(); atUint32 magic = base::readUint32();
if (magic != Sakura::SpriteFile::Magic) if (magic != Sakura::SpriteFile::Magic)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Not a valid Sakura Sprite container"); {
atError("Not a valid Sakura Sprite container");
return nullptr;
}
atUint32 version = base::readUint32(); atUint32 version = base::readUint32();
// TODO: Make this more verbose // TODO: Make this more verbose
if (version != Sakura::SpriteFile::Version) if (version != Sakura::SpriteFile::Version)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Unsupported version"); {
atError("Unsupported version");
return nullptr;
}
// After reading in the magic and version we need to load some // After reading in the magic and version we need to load some
// metadata about the file. // metadata about the file.
@ -209,7 +212,10 @@ Sakura::SpriteFile* SpriteFileReader::readFile()
#endif #endif
else else
THROW_IO_EXCEPTION_RETURN(nullptr, "Sprite names cannot be empty"); {
atError("Sprite names cannot be empty");
return nullptr;
}
} }
ret->setSprites(sprites); ret->setSprites(sprites);

View File

@ -19,8 +19,6 @@
#include "Athena/Sprite.hpp" #include "Athena/Sprite.hpp"
#include "Athena/SpritePart.hpp" #include "Athena/SpritePart.hpp"
#include "Athena/SpriteFrame.hpp" #include "Athena/SpriteFrame.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
namespace Athena namespace Athena
{ {
@ -39,7 +37,10 @@ SpriteFileWriter::SpriteFileWriter(const std::string& filepath)
void SpriteFileWriter::writeFile(Sakura::SpriteFile* file) void SpriteFileWriter::writeFile(Sakura::SpriteFile* file)
{ {
if (!file) if (!file)
THROW_INVALID_OPERATION_EXCEPTION("SSpriteFileWriter::writeFile -> file cannot be NULL"); {
atError("file cannot be NULL");
return;
}
base::writeUint32(Sakura::SpriteFile::Magic); base::writeUint32(Sakura::SpriteFile::Magic);
base::writeUint32(Sakura::SpriteFile::Version); base::writeUint32(Sakura::SpriteFile::Version);

View File

@ -9,7 +9,6 @@
#include <cstdio> #include <cstdio>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <Athena/Exception.hpp>
#include <random> #include <random>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -25,8 +24,22 @@ namespace utility
void fillRandom(atUint8* rndArea, atUint64 count) void fillRandom(atUint8* rndArea, atUint64 count)
{ {
for (atUint64 i = 0; i < count; i++) atUint8* buf = rndArea;
rndArea[i] = rand(); for (atUint64 i = 0; i < count / 4; i++)
{
*(atUint32*)(buf) = rand();
buf += 4;
}
atUint64 rem = count % 4;
if (rem)
{
for (atUint64 j = 0; j < rem; j++)
{
*buf = rand();
buf++;
}
}
} }
std::vector<std::string>& split(const std::string& s, char delim, std::vector<std::string>& elems) std::vector<std::string>& split(const std::string& s, char delim, std::vector<std::string>& elems)

View File

@ -15,7 +15,6 @@
// along with libAthena. If not, see <http://www.gnu.org/licenses/> // along with libAthena. If not, see <http://www.gnu.org/licenses/>
#include "Athena/WiiFile.hpp" #include "Athena/WiiFile.hpp"
#include "Athena/InvalidOperationException.hpp"
#include <algorithm> #include <algorithm>
namespace Athena namespace Athena
@ -144,7 +143,10 @@ bool WiiFile::isFile() const
void WiiFile::addChild(WiiFile* file) void WiiFile::addChild(WiiFile* file)
{ {
if (!isDirectory()) if (!isDirectory())
THROW_INVALID_OPERATION_EXCEPTION("%s is not a directory", filename().c_str()); {
atWarning("%s is not a directory", filename().c_str());
return;
}
if (std::find(m_children.begin(), m_children.end(), file) != m_children.end()) if (std::find(m_children.begin(), m_children.end(), file) != m_children.end())
return; return;

View File

@ -20,9 +20,6 @@
#include "Athena/WiiImage.hpp" #include "Athena/WiiImage.hpp"
#include "Athena/WiiBanner.hpp" #include "Athena/WiiBanner.hpp"
#include "Athena/Utility.hpp" #include "Athena/Utility.hpp"
#include "Athena/IOException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/FileWriter.hpp" #include "Athena/FileWriter.hpp"
#include "md5.h" #include "md5.h"
#include "aes.hpp" #include "aes.hpp"
@ -57,23 +54,35 @@ WiiSave* WiiSaveReader::readSave()
try try
{ {
if (length() < 0xF0C0) if (length() < 0xF0C0)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Not a valid WiiSave"); {
atError("Not a valid WiiSave");
return nullptr;
}
WiiBanner* banner = this->readBanner(); WiiBanner* banner = this->readBanner();
if (!banner) if (!banner)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Invalid banner"); {
atError("Invalid banner");
return nullptr;
}
ret->setBanner(banner); ret->setBanner(banner);
atUint32 bkVer = base::readUint32(); atUint32 bkVer = base::readUint32();
if (bkVer != 0x00000070) if (bkVer != 0x00000070)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Invalid BacKup header size"); {
atError("Invalid BacKup header size");
return nullptr;
}
atUint32 bkMagic = base::readUint32(); atUint32 bkMagic = base::readUint32();
if (bkMagic != 0x426B0001) if (bkMagic != 0x426B0001)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Invalid BacKup header magic"); {
atError("Invalid BacKup header magic");
return nullptr;
}
/*atUint32 ngId =*/ base::readUint32(); /*atUint32 ngId =*/ base::readUint32();
atUint32 numFiles = base::readUint32(); atUint32 numFiles = base::readUint32();
@ -163,7 +172,8 @@ WiiBanner* WiiSaveReader::readBanner()
std::cerr << std::endl; std::cerr << std::endl;
base::setData(oldData, oldLen); base::setData(oldData, oldLen);
base::seek(oldPos, SeekOrigin::Begin); base::seek(oldPos, SeekOrigin::Begin);
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "MD5 Mismatch"); atError("MD5 Mismatch");
return nullptr;
} }
// Set the binary reader buffer; // Set the binary reader buffer;
@ -191,7 +201,8 @@ WiiBanner* WiiSaveReader::readBanner()
// Make sure to reset m_reader values back to the old ones. // Make sure to reset m_reader values back to the old ones.
base::setData(oldData, oldLen); base::setData(oldData, oldLen);
base::seek(oldPos, SeekOrigin::Begin); base::seek(oldPos, SeekOrigin::Begin);
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Invalid Header Magic"); atError("Invalid Header Magic");
return nullptr;
} }
flags = base::readUint32(); flags = base::readUint32();

View File

@ -24,8 +24,6 @@
#include "Athena/WiiBanner.hpp" #include "Athena/WiiBanner.hpp"
#include "Athena/MemoryWriter.hpp" #include "Athena/MemoryWriter.hpp"
#include "Athena/Utility.hpp" #include "Athena/Utility.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "aes.hpp" #include "aes.hpp"
#include "ec.h" #include "ec.h"
@ -55,7 +53,10 @@ WiiSaveWriter::WiiSaveWriter(const std::string& filename)
bool WiiSaveWriter::writeSave(WiiSave* save, atUint8* macAddress, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId, const std::string& filepath) bool WiiSaveWriter::writeSave(WiiSave* save, atUint8* macAddress, atUint32 ngId, atUint8* ngPriv, atUint8* ngSig, atUint32 ngKeyId, const std::string& filepath)
{ {
if (!save) if (!save)
THROW_INVALID_OPERATION_EXCEPTION_RETURN(false, "save cannot be NULL"); {
atError("save cannot be NULL");
return false;
}
if (filepath != "") if (filepath != "")
m_filepath = filepath; m_filepath = filepath;

View File

@ -16,9 +16,7 @@
#include "Athena/ZQuestFileReader.hpp" #include "Athena/ZQuestFileReader.hpp"
#include "Athena/ZQuestFile.hpp" #include "Athena/ZQuestFile.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/Compression.hpp" #include "Athena/Compression.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/Checksums.hpp" #include "Athena/Checksums.hpp"
#include "Athena/Utility.hpp" #include "Athena/Utility.hpp"
@ -52,12 +50,18 @@ ZQuestFile* ZQuestFileReader::read()
magic = base::readUint32(); magic = base::readUint32();
if ((magic & 0x00FFFFFF) != (ZQuestFile::Magic & 0x00FFFFFF)) if ((magic & 0x00FFFFFF) != (ZQuestFile::Magic & 0x00FFFFFF))
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Not a valid ZQuest file"); {
atError("Not a valid ZQuest file");
return nullptr;
}
version = base::readUint32(); version = base::readUint32();
if (version > ZQuestFile::Version) if (version > ZQuestFile::Version)
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Unsupported ZQuest version"); {
atError("Unsupported ZQuest version");
return nullptr;
}
compressedLen = base::readUint32(); compressedLen = base::readUint32();
uncompressedLen = base::readUint32(); uncompressedLen = base::readUint32();
@ -93,7 +97,8 @@ ZQuestFile* ZQuestFileReader::read()
if (checksum != Athena::Checksums::crc32(data, compressedLen)) if (checksum != Athena::Checksums::crc32(data, compressedLen))
{ {
delete[] data; delete[] data;
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Checksum mismatch, data corrupt"); atError("Checksum mismatch, data corrupt");
return nullptr;
} }
} }
else else
@ -111,7 +116,8 @@ ZQuestFile* ZQuestFileReader::read()
{ {
delete[] dst; delete[] dst;
delete[] data; delete[] data;
THROW_INVALID_DATA_EXCEPTION_RETURN(nullptr, "Error decompressing data"); atError("Error decompressing data");
return nullptr;
} }
delete[] data; delete[] data;

View File

@ -15,7 +15,6 @@
// along with libAthena. If not, see <http://www.gnu.org/licenses/> // along with libAthena. If not, see <http://www.gnu.org/licenses/>
#include "Athena/ZQuestFileWriter.hpp" #include "Athena/ZQuestFileWriter.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/ZQuestFile.hpp" #include "Athena/ZQuestFile.hpp"
#include "Athena/Compression.hpp" #include "Athena/Compression.hpp"
#include "Athena/Checksums.hpp" #include "Athena/Checksums.hpp"
@ -38,7 +37,10 @@ ZQuestFileWriter::ZQuestFileWriter(const std::string& filename)
void ZQuestFileWriter::write(ZQuestFile* quest, bool compress) void ZQuestFileWriter::write(ZQuestFile* quest, bool compress)
{ {
if (!quest) if (!quest)
THROW_INVALID_OPERATION_EXCEPTION("quest cannot be NULL"); {
atError("quest cannot be NULL");
return;
}
base::writeUint32(ZQuestFile::Magic); base::writeUint32(ZQuestFile::Magic);
base::writeUint32(ZQuestFile::Version); base::writeUint32(ZQuestFile::Version);