mirror of
https://github.com/libAthena/athena.git
synced 2025-12-09 05:27:50 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a688a1c33 | ||
|
|
bfb14224e2 | ||
|
|
dd67c6484b | ||
| a7fda281b9 | |||
|
|
5d3dcb57ad | ||
| 572d04a0d5 | |||
| 8068ea0d95 | |||
|
|
602f6b6e15 | ||
|
|
78286b0f67 | ||
|
|
c6a6d3b9c4 | ||
|
|
6405bffdd2 | ||
|
|
7442d618e7 | ||
|
|
f3ba8819a4 | ||
|
|
24fedff58e | ||
|
|
87306a18d8 | ||
|
|
09e3d33ff2 | ||
|
|
11331e068e | ||
|
|
7ec5a5971a | ||
|
|
7ef451c86a | ||
|
|
ece50c6968 | ||
| 4bc6004a6a |
@@ -6,7 +6,7 @@ project(Athena)
|
|||||||
##################
|
##################
|
||||||
|
|
||||||
set(ATHENA_MAJOR_VERSION 2)
|
set(ATHENA_MAJOR_VERSION 2)
|
||||||
set(ATHENA_MINOR_VERSION 0)
|
set(ATHENA_MINOR_VERSION 2)
|
||||||
set(ATHENA_PATCH_VERSION 0)
|
set(ATHENA_PATCH_VERSION 0)
|
||||||
set(ATHENA_VERSION
|
set(ATHENA_VERSION
|
||||||
${ATHENA_MAJOR_VERSION}.${ATHENA_MINOR_VERSION}.${ATHENA_PATCH_VERSION})
|
${ATHENA_MAJOR_VERSION}.${ATHENA_MINOR_VERSION}.${ATHENA_PATCH_VERSION})
|
||||||
@@ -18,7 +18,9 @@ set(ATHENA_VERSION
|
|||||||
add_subdirectory(extern)
|
add_subdirectory(extern)
|
||||||
|
|
||||||
include_directories(include ${LZO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
include_directories(include ${LZO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
||||||
|
if (NOT MSVC)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
list(APPEND CORE_EXTRA src/win32_largefilewrapper.c)
|
list(APPEND CORE_EXTRA src/win32_largefilewrapper.c)
|
||||||
@@ -51,16 +53,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
|
||||||
@@ -114,7 +110,9 @@ add_library(AthenaWiiSave
|
|||||||
include/md5.h
|
include/md5.h
|
||||||
include/sha1.h
|
include/sha1.h
|
||||||
)
|
)
|
||||||
|
if(NOT MSVC)
|
||||||
set_source_files_properties(src/aes.cpp PROPERTIES COMPILE_FLAGS -maes)
|
set_source_files_properties(src/aes.cpp PROPERTIES COMPILE_FLAGS -maes)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(AthenaZelda
|
add_library(AthenaZelda
|
||||||
src/Athena/ALTTPFile.cpp
|
src/Athena/ALTTPFile.cpp
|
||||||
@@ -218,7 +216,7 @@ install(EXPORT AthenaTargets DESTINATION ${INSTALL_CMAKE_DIR} COMPONENT Athena)
|
|||||||
# atdna import #
|
# atdna import #
|
||||||
################
|
################
|
||||||
|
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/atdna/")
|
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/atdna/CMakeLists.txt")
|
||||||
add_subdirectory(atdna)
|
add_subdirectory(atdna)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
4
PKGBUILD
4
PKGBUILD
@@ -1,7 +1,7 @@
|
|||||||
# PKGBUILD for libAthena
|
# PKGBUILD for libAthena
|
||||||
_pkgname=libathena
|
_pkgname=libathena
|
||||||
pkgname=$_pkgname-git
|
pkgname=$_pkgname-git
|
||||||
pkgver=1.1.0.71.ge45679f
|
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')
|
||||||
@@ -21,7 +21,7 @@ build() {
|
|||||||
cd "$srcdir/$_pkgname"
|
cd "$srcdir/$_pkgname"
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_INSTALL_PREFIX="$pkgdir/usr" ..
|
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$pkgdir/usr" ..
|
||||||
make
|
make
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -18,6 +18,20 @@ namespace Athena
|
|||||||
namespace io
|
namespace io
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* forward-declaration dance for recursively-derived types */
|
||||||
|
|
||||||
|
template <size_t sizeVar, Endian VE>
|
||||||
|
struct Buffer;
|
||||||
|
|
||||||
|
template <atInt32 sizeVar, Endian VE>
|
||||||
|
struct String;
|
||||||
|
|
||||||
|
template <atInt32 sizeVar, Endian VE>
|
||||||
|
struct WString;
|
||||||
|
|
||||||
|
template <atInt32 sizeVar, Endian VE>
|
||||||
|
struct WStringAsString;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Base DNA class used against 'atdna'
|
* @brief Base DNA class used against 'atdna'
|
||||||
*
|
*
|
||||||
@@ -38,70 +52,17 @@ struct DNA
|
|||||||
template <typename T, size_t cntVar, Endian VE = DNAE>
|
template <typename T, size_t cntVar, Endian VE = DNAE>
|
||||||
using Vector = std::vector<T>;
|
using Vector = std::vector<T>;
|
||||||
|
|
||||||
struct Delete {};
|
|
||||||
|
|
||||||
template <size_t sizeVar>
|
template <size_t sizeVar>
|
||||||
struct Buffer : public DNA, public std::unique_ptr<atUint8[]>
|
using Buffer = struct Athena::io::Buffer<sizeVar, DNAE>;
|
||||||
{
|
|
||||||
Delete expl;
|
|
||||||
inline void read(IStreamReader& reader)
|
|
||||||
{
|
|
||||||
reset(new atUint8[sizeVar]);
|
|
||||||
reader.readUBytesToBuf(get(), sizeVar);
|
|
||||||
}
|
|
||||||
inline void write(IStreamWriter& writer) const
|
|
||||||
{
|
|
||||||
writer.writeUBytes(get(), sizeVar);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <atInt32 sizeVar = -1>
|
template <atInt32 sizeVar = -1>
|
||||||
struct String : public DNA, public std::string
|
using String = struct Athena::io::String<sizeVar, DNAE>;
|
||||||
{
|
|
||||||
Delete expl;
|
|
||||||
inline void read(IStreamReader& reader)
|
|
||||||
{*this = reader.readString(sizeVar);}
|
|
||||||
inline void write(IStreamWriter& writer) const
|
|
||||||
{writer.writeString(*this, sizeVar);}
|
|
||||||
inline std::string& operator=(const std::string& __str)
|
|
||||||
{return this->assign(__str);}
|
|
||||||
inline std::string& operator=(std::string&& __str)
|
|
||||||
{this->swap(__str); return *this;}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <atInt32 sizeVar = -1, Endian VE = DNAE>
|
template <atInt32 sizeVar = -1, Endian VE = DNAE>
|
||||||
struct WString : public DNA, public std::wstring
|
using WString = struct Athena::io::WString<sizeVar, VE>;
|
||||||
{
|
|
||||||
Delete expl;
|
|
||||||
inline void read(IStreamReader& reader)
|
|
||||||
{
|
|
||||||
reader.setEndian(VE);
|
|
||||||
*this = reader.readWString(sizeVar);
|
|
||||||
}
|
|
||||||
inline void write(IStreamWriter& writer) const
|
|
||||||
{
|
|
||||||
writer.setEndian(VE);
|
|
||||||
writer.writeWString(*this, sizeVar);
|
|
||||||
}
|
|
||||||
inline std::wstring& operator=(const std::wstring& __str)
|
|
||||||
{return this->assign(__str);}
|
|
||||||
inline std::wstring& operator=(std::wstring&& __str)
|
|
||||||
{this->swap(__str); return *this;}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <atInt32 sizeVar = -1>
|
template <atInt32 sizeVar = -1>
|
||||||
struct UTF8 : public DNA, public std::string
|
using WStringAsString = struct Athena::io::WStringAsString<sizeVar, DNAE>;
|
||||||
{
|
|
||||||
Delete expl;
|
|
||||||
inline void read(IStreamReader& reader)
|
|
||||||
{*this = reader.readUnicode(sizeVar);}
|
|
||||||
inline void write(IStreamWriter& writer) const
|
|
||||||
{writer.writeUnicode(*this, sizeVar);}
|
|
||||||
inline std::string& operator=(const std::string& __str)
|
|
||||||
{return this->assign(__str);}
|
|
||||||
inline std::string& operator=(std::string&& __str)
|
|
||||||
{this->swap(__str); return *this;}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <off_t offset, SeekOrigin direction>
|
template <off_t offset, SeekOrigin direction>
|
||||||
struct Seek {};
|
struct Seek {};
|
||||||
@@ -109,6 +70,72 @@ struct DNA
|
|||||||
template <size_t align>
|
template <size_t align>
|
||||||
struct Align {};
|
struct Align {};
|
||||||
|
|
||||||
|
struct Delete {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Concrete DNA types */
|
||||||
|
|
||||||
|
template <size_t sizeVar, Endian VE>
|
||||||
|
struct Buffer : public DNA<VE>, public std::unique_ptr<atUint8[]>
|
||||||
|
{
|
||||||
|
typename DNA<VE>::Delete expl;
|
||||||
|
inline void read(IStreamReader& reader)
|
||||||
|
{
|
||||||
|
reset(new atUint8[sizeVar]);
|
||||||
|
reader.readUBytesToBuf(get(), sizeVar);
|
||||||
|
}
|
||||||
|
inline void write(IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.writeUBytes(get(), sizeVar);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <atInt32 sizeVar, Endian VE>
|
||||||
|
struct String : public DNA<VE>, public std::string
|
||||||
|
{
|
||||||
|
typename DNA<VE>::Delete expl;
|
||||||
|
inline void read(IStreamReader& reader)
|
||||||
|
{*this = reader.readString(sizeVar);}
|
||||||
|
inline void write(IStreamWriter& writer) const
|
||||||
|
{writer.writeString(*this, sizeVar);}
|
||||||
|
inline std::string& operator=(const std::string& __str)
|
||||||
|
{return this->assign(__str);}
|
||||||
|
inline std::string& operator=(std::string&& __str)
|
||||||
|
{this->swap(__str); return *this;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <atInt32 sizeVar, Endian VE>
|
||||||
|
struct WString : public DNA<VE>, public std::wstring
|
||||||
|
{
|
||||||
|
typename DNA<VE>::Delete expl;
|
||||||
|
inline void read(IStreamReader& reader)
|
||||||
|
{
|
||||||
|
reader.setEndian(VE);
|
||||||
|
*this = reader.readWString(sizeVar);
|
||||||
|
}
|
||||||
|
inline void write(IStreamWriter& writer) const
|
||||||
|
{
|
||||||
|
writer.setEndian(VE);
|
||||||
|
writer.writeWString(*this, sizeVar);
|
||||||
|
}
|
||||||
|
inline std::wstring& operator=(const std::wstring& __str)
|
||||||
|
{return this->assign(__str);}
|
||||||
|
inline std::wstring& operator=(std::wstring&& __str)
|
||||||
|
{this->swap(__str); return *this;}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <atInt32 sizeVar, Endian VE>
|
||||||
|
struct WStringAsString : public DNA<VE>, public std::string
|
||||||
|
{
|
||||||
|
typename DNA<VE>::Delete expl;
|
||||||
|
inline void read(IStreamReader& reader)
|
||||||
|
{*this = reader.readWStringAsString(sizeVar);}
|
||||||
|
inline void write(IStreamWriter& writer) const
|
||||||
|
{writer.writeStringAsWString(*this, sizeVar);}
|
||||||
|
inline std::string& operator=(const std::string& __str)
|
||||||
|
{return this->assign(__str);}
|
||||||
|
inline std::string& operator=(std::string&& __str)
|
||||||
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Macro to automatically declare read/write methods in subclasses */
|
/** Macro to automatically declare read/write methods in subclasses */
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -14,6 +14,9 @@ class FileReader : public IStreamReader
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileReader(const std::string& filename, atInt32 cacheSize = (32 * 1024));
|
FileReader(const std::string& filename, atInt32 cacheSize = (32 * 1024));
|
||||||
|
#if _WIN32
|
||||||
|
FileReader(const std::wstring& filename, atInt32 cacheSize = (32 * 1024));
|
||||||
|
#endif
|
||||||
virtual ~FileReader();
|
virtual ~FileReader();
|
||||||
inline const std::string& filename() const
|
inline const std::string& filename() const
|
||||||
{return m_filename;}
|
{return m_filename;}
|
||||||
@@ -31,6 +34,9 @@ public:
|
|||||||
void setCacheSize(const atInt32 blockSize);
|
void setCacheSize(const atInt32 blockSize);
|
||||||
protected:
|
protected:
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
#if _WIN32
|
||||||
|
std::wstring m_wfilename;
|
||||||
|
#endif
|
||||||
FILE* m_fileHandle;
|
FILE* m_fileHandle;
|
||||||
std::unique_ptr<atUint8[]> m_cacheData;
|
std::unique_ptr<atUint8[]> m_cacheData;
|
||||||
atInt32 m_blockSize;
|
atInt32 m_blockSize;
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ class FileWriter : public IStreamWriter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileWriter(const std::string& filename, bool overwrite = true);
|
FileWriter(const std::string& filename, bool overwrite = true);
|
||||||
|
#if _WIN32
|
||||||
|
FileWriter(const std::wstring& filename, bool overwrite = true);
|
||||||
|
#endif
|
||||||
virtual ~FileWriter();
|
virtual ~FileWriter();
|
||||||
|
|
||||||
void open(bool overwrite = true);
|
void open(bool overwrite = true);
|
||||||
@@ -25,6 +28,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
#if _WIN32
|
||||||
|
std::wstring m_wfilename;
|
||||||
|
#endif
|
||||||
FILE* m_fileHandle;
|
FILE* m_fileHandle;
|
||||||
atUint8 m_currentByte;
|
atUint8 m_currentByte;
|
||||||
atUint64 m_bytePosition;
|
atUint64 m_bytePosition;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#define STREAM_HPP
|
#define STREAM_HPP
|
||||||
|
|
||||||
#include "Global.hpp"
|
#include "Global.hpp"
|
||||||
#include "Athena/NotImplementedException.hpp"
|
|
||||||
|
|
||||||
namespace Athena
|
namespace Athena
|
||||||
{
|
{
|
||||||
@@ -13,6 +12,7 @@ std::ostream& operator<<(std::ostream& os, Endian& endian);
|
|||||||
class IStream
|
class IStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
IStream() : m_hasError(false) {}
|
||||||
virtual ~IStream() {}
|
virtual ~IStream() {}
|
||||||
|
|
||||||
virtual void setEndian(Endian) = 0;
|
virtual void setEndian(Endian) = 0;
|
||||||
@@ -23,6 +23,10 @@ public:
|
|||||||
virtual bool atEnd() const = 0;
|
virtual bool atEnd() const = 0;
|
||||||
virtual atUint64 position() const = 0;
|
virtual atUint64 position() const = 0;
|
||||||
virtual atUint64 length() const = 0;
|
virtual atUint64 length() const = 0;
|
||||||
|
bool hasError() const { return m_hasError; }
|
||||||
|
protected:
|
||||||
|
void setError() { m_hasError = true; }
|
||||||
|
bool m_hasError;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,16 +14,16 @@ class IStreamReader : public IStream
|
|||||||
public:
|
public:
|
||||||
virtual ~IStreamReader() {}
|
virtual ~IStreamReader() {}
|
||||||
|
|
||||||
/*! \brief Sets the Endianss of the stream
|
/*! \brief Sets the Endianness of the stream
|
||||||
*
|
*
|
||||||
* \param endian The Endianess to set \sa Endian
|
* \param endian The Endianness to set \sa Endian
|
||||||
*/
|
*/
|
||||||
inline void setEndian(Endian endian)
|
inline void setEndian(Endian endian)
|
||||||
{m_endian = endian;}
|
{m_endian = endian;}
|
||||||
|
|
||||||
/*! \brief Returns the current Endianness of the stream
|
/*! \brief Returns the current Endianness of the stream
|
||||||
*
|
*
|
||||||
* \return Endian The current Stream Endianess
|
* \return Endian The current Stream Endianness
|
||||||
*/
|
*/
|
||||||
inline Endian endian() const
|
inline Endian endian() const
|
||||||
{return m_endian;}
|
{return m_endian;}
|
||||||
@@ -293,13 +293,13 @@ public:
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Reads a Unicode string and advances the position in the file
|
/*! \brief Reads a wide-char string, converts to UTF8 and advances the position in the file
|
||||||
*
|
*
|
||||||
* \param fixedLen If non-negative, this is a fixed-length string read
|
* \param fixedLen If non-negative, this is a fixed-length string read
|
||||||
* \return std::string The value at the current address
|
* \return std::string The value at the current address
|
||||||
* \throw IOException when address is out of range
|
* \throw IOException when address is out of range
|
||||||
*/
|
*/
|
||||||
inline std::string readUnicode(atInt32 fixedLen = -1)
|
inline std::string readWStringAsString(atInt32 fixedLen = -1)
|
||||||
{
|
{
|
||||||
std::wstring tmp;
|
std::wstring tmp;
|
||||||
atUint16 chr = readUint16();
|
atUint16 chr = readUint16();
|
||||||
|
|||||||
@@ -13,16 +13,16 @@ class IStreamWriter : public IStream
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~IStreamWriter() {}
|
virtual ~IStreamWriter() {}
|
||||||
/*! \brief Sets the Endianss of the stream
|
/*! \brief Sets the Endianness of the stream
|
||||||
*
|
*
|
||||||
* \param endian The Endianess to set \sa Endian
|
* \param endian The Endianness to set \sa Endian
|
||||||
*/
|
*/
|
||||||
inline void setEndian(Endian endian)
|
inline void setEndian(Endian endian)
|
||||||
{m_endian = endian;}
|
{m_endian = endian;}
|
||||||
|
|
||||||
/*! \brief Returns the current Endianness of the stream
|
/*! \brief Returns the current Endianness of the stream
|
||||||
*
|
*
|
||||||
* \return Endian The current Stream Endianess
|
* \return Endian The current Stream Endianness
|
||||||
*/
|
*/
|
||||||
inline Endian endian() const
|
inline Endian endian() const
|
||||||
{return m_endian;}
|
{return m_endian;}
|
||||||
@@ -273,14 +273,14 @@ public:
|
|||||||
writeUBytes((atUint8*)&vec, 16);
|
writeUBytes((atUint8*)&vec, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Writes an unicode string to the buffer and advances the buffer.
|
/*! \brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
|
||||||
* It also swaps the bytes depending on the platform and Stream settings.
|
* It also swaps the bytes depending on the platform and Stream settings.
|
||||||
*
|
*
|
||||||
* \sa Endian
|
* \sa Endian
|
||||||
* \param str The string to write to the buffer
|
* \param str The string to write to the buffer
|
||||||
* \param fixedLen If not -1, the number of characters to zero-fill string to
|
* \param fixedLen If not -1, the number of characters to zero-fill string to
|
||||||
*/
|
*/
|
||||||
inline void writeUnicode(const std::string& str, atInt32 fixedLen = -1)
|
inline void writeStringAsWString(const std::string& str, atInt32 fixedLen = -1)
|
||||||
{
|
{
|
||||||
std::string tmpStr = "\xEF\xBB\xBF" + str;
|
std::string tmpStr = "\xEF\xBB\xBF" + str;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -13,7 +13,7 @@ namespace Athena
|
|||||||
namespace utility
|
namespace utility
|
||||||
{
|
{
|
||||||
inline bool isEmpty(atInt8* buf, atUint32 size) {return !memcmp(buf, buf + 1, size - 1);}
|
inline bool isEmpty(atInt8* buf, atUint32 size) {return !memcmp(buf, buf + 1, size - 1);}
|
||||||
bool isSystemBigEndian();
|
inline bool isSystemBigEndian() {return (*(atUint16*)"\xFE\xFF" == 0xFEFF);}
|
||||||
|
|
||||||
inline atInt16 swap16(atInt16 val)
|
inline atInt16 swap16(atInt16 val)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace Athena
|
|||||||
class IAES
|
class IAES
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
virtual ~IAES() {}
|
||||||
virtual void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)=0;
|
virtual void encrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)=0;
|
||||||
virtual void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)=0;
|
virtual void decrypt(const uint8_t* iv, const uint8_t* inbuf, uint8_t* outbuf, uint64_t len)=0;
|
||||||
virtual void setKey(const uint8_t* key)=0;
|
virtual void setKey(const uint8_t* key)=0;
|
||||||
|
|||||||
@@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -98,7 +97,7 @@ atInt32 decompressLZO(const atUint8* source, const atInt32 sourceSize, atUint8*
|
|||||||
int srcSize = sourceSize;
|
int srcSize = sourceSize;
|
||||||
lzo_uint size = dstSize;
|
lzo_uint size = dstSize;
|
||||||
int result = lzo1x_decompress_safe(source, srcSize, dst, &size, NULL);
|
int result = lzo1x_decompress_safe(source, srcSize, dst, &size, NULL);
|
||||||
dstSize -= size;
|
dstSize -= (atInt32)size;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -20,10 +16,22 @@ FileReader::FileReader(const std::string& filename, atInt32 cacheSize)
|
|||||||
m_cacheData(nullptr),
|
m_cacheData(nullptr),
|
||||||
m_offset(0)
|
m_offset(0)
|
||||||
{
|
{
|
||||||
setCacheSize(cacheSize);
|
|
||||||
open();
|
open();
|
||||||
|
setCacheSize(cacheSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
FileReader::FileReader(const std::wstring& filename, atInt32 cacheSize)
|
||||||
|
: m_wfilename(filename),
|
||||||
|
m_fileHandle(nullptr),
|
||||||
|
m_cacheData(nullptr),
|
||||||
|
m_offset(0)
|
||||||
|
{
|
||||||
|
open();
|
||||||
|
setCacheSize(cacheSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
FileReader::~FileReader()
|
FileReader::~FileReader()
|
||||||
{
|
{
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
@@ -32,10 +40,21 @@ FileReader::~FileReader()
|
|||||||
|
|
||||||
void FileReader::open()
|
void FileReader::open()
|
||||||
{
|
{
|
||||||
|
#if _WIN32
|
||||||
|
if (m_wfilename.size())
|
||||||
|
m_fileHandle = _wfopen(m_wfilename.c_str(), L"rb");
|
||||||
|
else
|
||||||
|
m_fileHandle = fopen(m_filename.c_str(), "rb");
|
||||||
|
#else
|
||||||
m_fileHandle = fopen(m_filename.c_str(), "rb");
|
m_fileHandle = fopen(m_filename.c_str(), "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!m_fileHandle)
|
if (!m_fileHandle)
|
||||||
THROW_FILE_NOT_FOUND_EXCEPTION(m_filename);
|
{
|
||||||
|
atError("File not found '%s'", m_filename.c_str());
|
||||||
|
setError();
|
||||||
|
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 +63,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fclose(m_fileHandle);
|
fclose(m_fileHandle);
|
||||||
m_fileHandle = NULL;
|
m_fileHandle = NULL;
|
||||||
@@ -72,7 +95,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;
|
||||||
@@ -80,17 +104,20 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
|
|||||||
{
|
{
|
||||||
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
|
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
|
||||||
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
|
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
|
||||||
m_curBlock = block;
|
m_curBlock = (atInt32)block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 +128,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 +139,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_blockSize <= 0)
|
if (m_blockSize <= 0)
|
||||||
return fread(buf, 1, len, m_fileHandle);
|
return fread(buf, 1, len, m_fileHandle);
|
||||||
@@ -127,7 +161,7 @@ atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
|
|||||||
{
|
{
|
||||||
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
|
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
|
||||||
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
|
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
|
||||||
m_curBlock = block;
|
m_curBlock = (atInt32)block;
|
||||||
}
|
}
|
||||||
|
|
||||||
cacheSize = rem;
|
cacheSize = rem;
|
||||||
@@ -150,7 +184,7 @@ void FileReader::setCacheSize(const atInt32 blockSize)
|
|||||||
m_blockSize = blockSize;
|
m_blockSize = blockSize;
|
||||||
|
|
||||||
if (m_blockSize > length())
|
if (m_blockSize > length())
|
||||||
m_blockSize = length();
|
m_blockSize = (atInt32)length();
|
||||||
|
|
||||||
m_curBlock = -1;
|
m_curBlock = -1;
|
||||||
if (m_blockSize > 0)
|
if (m_blockSize > 0)
|
||||||
|
|||||||
@@ -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"
|
||||||
@@ -22,6 +18,16 @@ FileWriter::FileWriter(const std::string& filename, bool overwrite)
|
|||||||
open(overwrite);
|
open(overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
FileWriter::FileWriter(const std::wstring& filename, bool overwrite)
|
||||||
|
: m_wfilename(filename),
|
||||||
|
m_fileHandle(NULL),
|
||||||
|
m_bytePosition(0)
|
||||||
|
{
|
||||||
|
open(overwrite);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
FileWriter::~FileWriter()
|
FileWriter::~FileWriter()
|
||||||
{
|
{
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
@@ -30,13 +36,36 @@ FileWriter::~FileWriter()
|
|||||||
|
|
||||||
void FileWriter::open(bool overwrite)
|
void FileWriter::open(bool overwrite)
|
||||||
{
|
{
|
||||||
|
#if _WIN32
|
||||||
|
if (m_wfilename.size())
|
||||||
|
{
|
||||||
|
if (overwrite)
|
||||||
|
m_fileHandle = _wfopen(m_wfilename.c_str(), L"w+b");
|
||||||
|
else
|
||||||
|
m_fileHandle = _wfopen(m_wfilename.c_str(), L"r+b");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (overwrite)
|
||||||
|
m_fileHandle = fopen(m_filename.c_str(), "w+b");
|
||||||
|
else
|
||||||
|
m_fileHandle = fopen(m_filename.c_str(), "r+b");
|
||||||
|
}
|
||||||
|
#else
|
||||||
if (overwrite)
|
if (overwrite)
|
||||||
m_fileHandle = fopen(m_filename.c_str(), "w+b");
|
m_fileHandle = fopen(m_filename.c_str(), "w+b");
|
||||||
else
|
else
|
||||||
m_fileHandle = fopen(m_filename.c_str(), "r+b");
|
m_fileHandle = fopen(m_filename.c_str(), "r+b");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!m_fileHandle)
|
if (!m_fileHandle)
|
||||||
THROW_FILE_NOT_FOUND_EXCEPTION(m_filename);
|
{
|
||||||
|
atError("Unable to open file '%s'", m_filename.c_str());
|
||||||
|
setError();
|
||||||
|
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 +74,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fclose(m_fileHandle);
|
fclose(m_fileHandle);
|
||||||
m_fileHandle = NULL;
|
m_fileHandle = NULL;
|
||||||
@@ -55,7 +88,10 @@ 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");
|
||||||
|
setError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint64 FileWriter::position() const
|
atUint64 FileWriter::position() const
|
||||||
@@ -71,10 +107,17 @@ 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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,36 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
{
|
||||||
|
atError("length cannot be 0");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
{
|
||||||
|
atError("length cannot be 0");
|
||||||
|
setError();
|
||||||
|
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 +62,33 @@ 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);
|
||||||
|
setError();
|
||||||
|
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);
|
||||||
|
setError();
|
||||||
|
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);
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_position = m_length - position;
|
m_position = m_length - position;
|
||||||
break;
|
break;
|
||||||
@@ -98,7 +122,11 @@ 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);
|
||||||
|
setError();
|
||||||
|
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 +140,11 @@ 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());
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rewind(in);
|
rewind(in);
|
||||||
|
|
||||||
@@ -131,7 +163,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -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,18 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
|
{
|
||||||
|
atError("length cannot be 0");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
|
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
|
||||||
@@ -37,7 +41,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
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 +63,11 @@ 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!");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(m_data, 0, m_length);
|
memset(m_data, 0, m_length);
|
||||||
}
|
}
|
||||||
@@ -66,30 +78,54 @@ 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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_position = m_length - position;
|
m_position = m_length - position;
|
||||||
break;
|
break;
|
||||||
@@ -102,7 +138,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((atUint64)position > m_length)
|
if ((atUint64)position > m_length)
|
||||||
resize(position);
|
resize(position);
|
||||||
@@ -112,7 +152,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_position + position > m_length)
|
if (m_position + position > m_length)
|
||||||
resize(m_position + position);
|
resize(m_position + position);
|
||||||
@@ -122,7 +166,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((atUint64)position > m_length)
|
if ((atUint64)position > m_length)
|
||||||
resize(position);
|
resize(position);
|
||||||
@@ -160,7 +208,11 @@ 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.");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
m_filepath = filename;
|
m_filepath = filename;
|
||||||
@@ -168,7 +220,11 @@ 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());
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
atUint64 done = 0;
|
atUint64 done = 0;
|
||||||
atUint64 blocksize = BLOCKSZ;
|
atUint64 blocksize = BLOCKSZ;
|
||||||
@@ -181,7 +237,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -195,10 +255,18 @@ 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");
|
||||||
|
setError();
|
||||||
|
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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy((atInt8*)(m_data + m_position), data, length);
|
memcpy((atInt8*)(m_data + m_position), data, length);
|
||||||
|
|
||||||
@@ -208,7 +276,11 @@ 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");
|
||||||
|
setError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_position + length > m_length)
|
if (m_position + length > m_length)
|
||||||
resize(m_position + length);
|
resize(m_position + length);
|
||||||
@@ -221,7 +293,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];
|
||||||
|
|||||||
@@ -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];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -23,16 +22,24 @@ namespace Athena
|
|||||||
namespace utility
|
namespace utility
|
||||||
{
|
{
|
||||||
|
|
||||||
bool isSystemBigEndian()
|
|
||||||
{
|
|
||||||
static const atUint8* test = (atUint8*)"\xFE\xFF";
|
|
||||||
return (*(atUint16*)test == 0xFEFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,19 +201,20 @@ 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();
|
||||||
animSpeed = base::readUint16();
|
animSpeed = base::readUint16();
|
||||||
base::seek(22);
|
base::seek(22);
|
||||||
|
|
||||||
gameTitle = base::readUnicode();
|
gameTitle = base::readWStringAsString();
|
||||||
|
|
||||||
if (base::position() != 0x0080)
|
if (base::position() != 0x0080)
|
||||||
base::seek(0x0080, SeekOrigin::Begin);
|
base::seek(0x0080, SeekOrigin::Begin);
|
||||||
|
|
||||||
subTitle = base::readUnicode();
|
subTitle = base::readWStringAsString();
|
||||||
|
|
||||||
if (base::position() != 0x00C0)
|
if (base::position() != 0x00C0)
|
||||||
base::seek(0x00C0, SeekOrigin::Begin);
|
base::seek(0x00C0, SeekOrigin::Begin);
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -110,12 +111,12 @@ void WiiSaveWriter::writeBanner(WiiBanner* banner)
|
|||||||
base::writeInt16(banner->animationSpeed());
|
base::writeInt16(banner->animationSpeed());
|
||||||
base::seek(22);
|
base::seek(22);
|
||||||
|
|
||||||
base::writeUnicode(banner->title());
|
base::writeStringAsWString(banner->title());
|
||||||
|
|
||||||
if (base::position() != 0x0080)
|
if (base::position() != 0x0080)
|
||||||
base::seek(0x0080, SeekOrigin::Begin);
|
base::seek(0x0080, SeekOrigin::Begin);
|
||||||
|
|
||||||
base::writeUnicode(banner->subtitle());
|
base::writeStringAsWString(banner->subtitle());
|
||||||
|
|
||||||
if (base::position() != 0x00C0)
|
if (base::position() != 0x00C0)
|
||||||
base::seek(0x00C0, SeekOrigin::Begin);
|
base::seek(0x00C0, SeekOrigin::Begin);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
292
src/aes.cpp
292
src/aes.cpp
@@ -20,8 +20,6 @@ namespace Athena
|
|||||||
#define ROTL16(x) (((x)<<16)|((x)>>16))
|
#define ROTL16(x) (((x)<<16)|((x)>>16))
|
||||||
#define ROTL24(x) (((x)<<24)|((x)>>8))
|
#define ROTL24(x) (((x)<<24)|((x)>>8))
|
||||||
|
|
||||||
/* Fixed Data */
|
|
||||||
|
|
||||||
static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */
|
static const uint8_t InCo[4] = {0xB, 0xD, 0x9, 0xE}; /* Inverse Coefficients */
|
||||||
|
|
||||||
static inline uint32_t pack(const uint8_t* b)
|
static inline uint32_t pack(const uint8_t* b)
|
||||||
@@ -51,9 +49,8 @@ static inline uint8_t xtime(uint8_t a)
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SoftwareAES : public IAES
|
static const struct SoftwareAESTables
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
uint8_t fbsub[256];
|
uint8_t fbsub[256];
|
||||||
uint8_t rbsub[256];
|
uint8_t rbsub[256];
|
||||||
uint8_t ptab[256], ltab[256];
|
uint8_t ptab[256], ltab[256];
|
||||||
@@ -61,20 +58,134 @@ protected:
|
|||||||
uint32_t rtable[256];
|
uint32_t rtable[256];
|
||||||
uint32_t rco[30];
|
uint32_t rco[30];
|
||||||
|
|
||||||
/* Parameter-dependent data */
|
uint8_t bmul(uint8_t x, uint8_t y) const
|
||||||
|
{
|
||||||
|
/* x.y= AntiLog(Log(x) + Log(y)) */
|
||||||
|
if (x && y) return ptab[(ltab[x] + ltab[y]) % 255];
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SubByte(uint32_t a) const
|
||||||
|
{
|
||||||
|
uint8_t b[4];
|
||||||
|
unpack(a, b);
|
||||||
|
b[0] = fbsub[b[0]];
|
||||||
|
b[1] = fbsub[b[1]];
|
||||||
|
b[2] = fbsub[b[2]];
|
||||||
|
b[3] = fbsub[b[3]];
|
||||||
|
return pack(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t product(uint32_t x, uint32_t y) const
|
||||||
|
{
|
||||||
|
/* dot product of two 4-byte arrays */
|
||||||
|
uint8_t xb[4], yb[4];
|
||||||
|
unpack(x, xb);
|
||||||
|
unpack(y, yb);
|
||||||
|
return bmul(xb[0], yb[0])^bmul(xb[1], yb[1])^bmul(xb[2], yb[2])^bmul(xb[3], yb[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t InvMixCol(uint32_t x) const
|
||||||
|
{
|
||||||
|
/* matrix Multiplication */
|
||||||
|
uint32_t y, m;
|
||||||
|
uint8_t b[4];
|
||||||
|
|
||||||
|
m = pack(InCo);
|
||||||
|
b[3] = product(m, x);
|
||||||
|
m = ROTL24(m);
|
||||||
|
b[2] = product(m, x);
|
||||||
|
m = ROTL24(m);
|
||||||
|
b[1] = product(m, x);
|
||||||
|
m = ROTL24(m);
|
||||||
|
b[0] = product(m, x);
|
||||||
|
y = pack(b);
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ByteSub(uint8_t x) const
|
||||||
|
{
|
||||||
|
uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */
|
||||||
|
x = y;
|
||||||
|
x = ROTL(x);
|
||||||
|
y ^= x;
|
||||||
|
x = ROTL(x);
|
||||||
|
y ^= x;
|
||||||
|
x = ROTL(x);
|
||||||
|
y ^= x;
|
||||||
|
x = ROTL(x);
|
||||||
|
y ^= x;
|
||||||
|
y ^= 0x63;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
SoftwareAESTables()
|
||||||
|
{
|
||||||
|
/* generate tables */
|
||||||
|
int i;
|
||||||
|
uint8_t y, b[4];
|
||||||
|
|
||||||
|
/* use 3 as primitive root to generate power and log tables */
|
||||||
|
|
||||||
|
ltab[0] = 0;
|
||||||
|
ptab[0] = 1;
|
||||||
|
ltab[1] = 0;
|
||||||
|
ptab[1] = 3;
|
||||||
|
ltab[3] = 1;
|
||||||
|
|
||||||
|
for (i = 2; i < 256; i++)
|
||||||
|
{
|
||||||
|
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
|
||||||
|
ltab[ptab[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* affine transformation:- each bit is xored with itself shifted one bit */
|
||||||
|
|
||||||
|
fbsub[0] = 0x63;
|
||||||
|
rbsub[0x63] = 0;
|
||||||
|
|
||||||
|
for (i = 1; i < 256; i++)
|
||||||
|
{
|
||||||
|
y = ByteSub((uint8_t)i);
|
||||||
|
fbsub[i] = y;
|
||||||
|
rbsub[y] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0, y = 1; i < 30; i++)
|
||||||
|
{
|
||||||
|
rco[i] = y;
|
||||||
|
y = xtime(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate forward and reverse tables */
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
y = fbsub[i];
|
||||||
|
b[3] = y ^ xtime(y);
|
||||||
|
b[2] = y;
|
||||||
|
b[1] = y;
|
||||||
|
b[0] = xtime(y);
|
||||||
|
ftable[i] = pack(b);
|
||||||
|
|
||||||
|
y = rbsub[i];
|
||||||
|
b[3] = bmul(InCo[0], y);
|
||||||
|
b[2] = bmul(InCo[1], y);
|
||||||
|
b[1] = bmul(InCo[2], y);
|
||||||
|
b[0] = bmul(InCo[3], y);
|
||||||
|
rtable[i] = pack(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} AEStb;
|
||||||
|
|
||||||
|
class SoftwareAES : public IAES
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
/* Parameter-dependent data */
|
||||||
int Nk, Nb, Nr;
|
int Nk, Nb, Nr;
|
||||||
uint8_t fi[24], ri[24];
|
uint8_t fi[24], ri[24];
|
||||||
uint32_t fkey[120];
|
uint32_t fkey[120];
|
||||||
uint32_t rkey[120];
|
uint32_t rkey[120];
|
||||||
|
|
||||||
|
|
||||||
uint8_t bmul(uint8_t x, uint8_t y);
|
|
||||||
uint32_t SubByte(uint32_t a);
|
|
||||||
uint8_t product(uint32_t x, uint32_t y);
|
|
||||||
uint32_t InvMixCol(uint32_t x);
|
|
||||||
uint8_t ByteSub(uint8_t x);
|
|
||||||
void gentables(void);
|
|
||||||
void gkey(int nb, int nk, const uint8_t* key);
|
void gkey(int nb, int nk, const uint8_t* key);
|
||||||
void _encrypt(uint8_t* buff);
|
void _encrypt(uint8_t* buff);
|
||||||
void _decrypt(uint8_t* buff);
|
void _decrypt(uint8_t* buff);
|
||||||
@@ -85,124 +196,6 @@ public:
|
|||||||
void setKey(const uint8_t* key);
|
void setKey(const uint8_t* key);
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t SoftwareAES::bmul(uint8_t x, uint8_t y)
|
|
||||||
{
|
|
||||||
/* x.y= AntiLog(Log(x) + Log(y)) */
|
|
||||||
if (x && y) return ptab[(ltab[x] + ltab[y]) % 255];
|
|
||||||
else return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t SoftwareAES::SubByte(uint32_t a)
|
|
||||||
{
|
|
||||||
uint8_t b[4];
|
|
||||||
unpack(a, b);
|
|
||||||
b[0] = fbsub[b[0]];
|
|
||||||
b[1] = fbsub[b[1]];
|
|
||||||
b[2] = fbsub[b[2]];
|
|
||||||
b[3] = fbsub[b[3]];
|
|
||||||
return pack(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t SoftwareAES::product(uint32_t x, uint32_t y)
|
|
||||||
{
|
|
||||||
/* dot product of two 4-byte arrays */
|
|
||||||
uint8_t xb[4], yb[4];
|
|
||||||
unpack(x, xb);
|
|
||||||
unpack(y, yb);
|
|
||||||
return bmul(xb[0], yb[0])^bmul(xb[1], yb[1])^bmul(xb[2], yb[2])^bmul(xb[3], yb[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t SoftwareAES::InvMixCol(uint32_t x)
|
|
||||||
{
|
|
||||||
/* matrix Multiplication */
|
|
||||||
uint32_t y, m;
|
|
||||||
uint8_t b[4];
|
|
||||||
|
|
||||||
m = pack(InCo);
|
|
||||||
b[3] = product(m, x);
|
|
||||||
m = ROTL24(m);
|
|
||||||
b[2] = product(m, x);
|
|
||||||
m = ROTL24(m);
|
|
||||||
b[1] = product(m, x);
|
|
||||||
m = ROTL24(m);
|
|
||||||
b[0] = product(m, x);
|
|
||||||
y = pack(b);
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t SoftwareAES::ByteSub(uint8_t x)
|
|
||||||
{
|
|
||||||
uint8_t y = ptab[255 - ltab[x]]; /* multiplicative inverse */
|
|
||||||
x = y;
|
|
||||||
x = ROTL(x);
|
|
||||||
y ^= x;
|
|
||||||
x = ROTL(x);
|
|
||||||
y ^= x;
|
|
||||||
x = ROTL(x);
|
|
||||||
y ^= x;
|
|
||||||
x = ROTL(x);
|
|
||||||
y ^= x;
|
|
||||||
y ^= 0x63;
|
|
||||||
return y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoftwareAES::gentables(void)
|
|
||||||
{
|
|
||||||
/* generate tables */
|
|
||||||
int i;
|
|
||||||
uint8_t y, b[4];
|
|
||||||
|
|
||||||
/* use 3 as primitive root to generate power and log tables */
|
|
||||||
|
|
||||||
ltab[0] = 0;
|
|
||||||
ptab[0] = 1;
|
|
||||||
ltab[1] = 0;
|
|
||||||
ptab[1] = 3;
|
|
||||||
ltab[3] = 1;
|
|
||||||
|
|
||||||
for (i = 2; i < 256; i++)
|
|
||||||
{
|
|
||||||
ptab[i] = ptab[i - 1] ^ xtime(ptab[i - 1]);
|
|
||||||
ltab[ptab[i]] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* affine transformation:- each bit is xored with itself shifted one bit */
|
|
||||||
|
|
||||||
fbsub[0] = 0x63;
|
|
||||||
rbsub[0x63] = 0;
|
|
||||||
|
|
||||||
for (i = 1; i < 256; i++)
|
|
||||||
{
|
|
||||||
y = ByteSub((uint8_t)i);
|
|
||||||
fbsub[i] = y;
|
|
||||||
rbsub[y] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0, y = 1; i < 30; i++)
|
|
||||||
{
|
|
||||||
rco[i] = y;
|
|
||||||
y = xtime(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate forward and reverse tables */
|
|
||||||
for (i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
y = fbsub[i];
|
|
||||||
b[3] = y ^ xtime(y);
|
|
||||||
b[2] = y;
|
|
||||||
b[1] = y;
|
|
||||||
b[0] = xtime(y);
|
|
||||||
ftable[i] = pack(b);
|
|
||||||
|
|
||||||
y = rbsub[i];
|
|
||||||
b[3] = bmul(InCo[0], y);
|
|
||||||
b[2] = bmul(InCo[1], y);
|
|
||||||
b[1] = bmul(InCo[2], y);
|
|
||||||
b[0] = bmul(InCo[3], y);
|
|
||||||
rtable[i] = pack(b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
|
void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
|
||||||
{
|
{
|
||||||
/* blocksize=32*nb bits. Key=32*nk bits */
|
/* blocksize=32*nb bits. Key=32*nk bits */
|
||||||
@@ -247,7 +240,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
|
|||||||
|
|
||||||
for (j = Nk, k = 0; j < N; j += Nk, k++)
|
for (j = Nk, k = 0; j < N; j += Nk, k++)
|
||||||
{
|
{
|
||||||
fkey[j] = fkey[j - Nk] ^ SubByte(ROTL24(fkey[j - 1]))^rco[k];
|
fkey[j] = fkey[j - Nk] ^ AEStb.SubByte(ROTL24(fkey[j - 1]))^AEStb.rco[k];
|
||||||
|
|
||||||
if (Nk <= 6)
|
if (Nk <= 6)
|
||||||
{
|
{
|
||||||
@@ -259,7 +252,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
|
|||||||
for (i = 1; i < 4 && (i + j) < N; i++)
|
for (i = 1; i < 4 && (i + j) < N; i++)
|
||||||
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
|
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
|
||||||
|
|
||||||
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ SubByte(fkey[j + 3]);
|
if ((j + 4) < N) fkey[j + 4] = fkey[j + 4 - Nk] ^ AEStb.SubByte(fkey[j + 3]);
|
||||||
|
|
||||||
for (i = 5; i < Nk && (i + j) < N; i++)
|
for (i = 5; i < Nk && (i + j) < N; i++)
|
||||||
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
|
fkey[i + j] = fkey[i + j - Nk] ^ fkey[i + j - 1];
|
||||||
@@ -275,7 +268,7 @@ void SoftwareAES::gkey(int nb, int nk, const uint8_t* key)
|
|||||||
{
|
{
|
||||||
k = N - Nb - i;
|
k = N - Nb - i;
|
||||||
|
|
||||||
for (j = 0; j < Nb; j++) rkey[k + j] = InvMixCol(fkey[i + j]);
|
for (j = 0; j < Nb; j++) rkey[k + j] = AEStb.InvMixCol(fkey[i + j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = N - Nb; j < N; j++) rkey[j - N + Nb] = fkey[j];
|
for (j = N - Nb; j < N; j++) rkey[j - N + Nb] = fkey[j];
|
||||||
@@ -313,10 +306,10 @@ void SoftwareAES::_encrypt(uint8_t* buff)
|
|||||||
{
|
{
|
||||||
/* deal with each 32-bit element of the State */
|
/* deal with each 32-bit element of the State */
|
||||||
/* This is the time-critical bit */
|
/* This is the time-critical bit */
|
||||||
y[j] = fkey[k++] ^ ftable[(uint8_t)x[j]] ^
|
y[j] = fkey[k++] ^ AEStb.ftable[(uint8_t)x[j]] ^
|
||||||
ROTL8(ftable[(uint8_t)(x[fi[m]] >> 8)])^
|
ROTL8(AEStb.ftable[(uint8_t)(x[fi[m]] >> 8)])^
|
||||||
ROTL16(ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^
|
ROTL16(AEStb.ftable[(uint8_t)(x[fi[m + 1]] >> 16)])^
|
||||||
ROTL24(ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
|
ROTL24(AEStb.ftable[(uint8_t)(x[fi[m + 2]] >> 24)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = x;
|
t = x;
|
||||||
@@ -327,10 +320,10 @@ void SoftwareAES::_encrypt(uint8_t* buff)
|
|||||||
/* Last Round - unroll if possible */
|
/* Last Round - unroll if possible */
|
||||||
for (m = j = 0; j < Nb; j++, m += 3)
|
for (m = j = 0; j < Nb; j++, m += 3)
|
||||||
{
|
{
|
||||||
y[j] = fkey[k++] ^ (uint32_t)fbsub[(uint8_t)x[j]] ^
|
y[j] = fkey[k++] ^ (uint32_t)AEStb.fbsub[(uint8_t)x[j]] ^
|
||||||
ROTL8((uint32_t)fbsub[(uint8_t)(x[fi[m]] >> 8)])^
|
ROTL8((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m]] >> 8)])^
|
||||||
ROTL16((uint32_t)fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^
|
ROTL16((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 1]] >> 16)])^
|
||||||
ROTL24((uint32_t)fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]);
|
ROTL24((uint32_t)AEStb.fbsub[(uint8_t)(x[fi[m + 2]] >> 24)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = j = 0; i < Nb; i++, j += 4)
|
for (i = j = 0; i < Nb; i++, j += 4)
|
||||||
@@ -368,10 +361,10 @@ void SoftwareAES::_decrypt(uint8_t* buff)
|
|||||||
for (m = j = 0; j < Nb; j++, m += 3)
|
for (m = j = 0; j < Nb; j++, m += 3)
|
||||||
{
|
{
|
||||||
/* This is the time-critical bit */
|
/* This is the time-critical bit */
|
||||||
y[j] = rkey[k++] ^ rtable[(uint8_t)x[j]] ^
|
y[j] = rkey[k++] ^ AEStb.rtable[(uint8_t)x[j]] ^
|
||||||
ROTL8(rtable[(uint8_t)(x[ri[m]] >> 8)])^
|
ROTL8(AEStb.rtable[(uint8_t)(x[ri[m]] >> 8)])^
|
||||||
ROTL16(rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^
|
ROTL16(AEStb.rtable[(uint8_t)(x[ri[m + 1]] >> 16)])^
|
||||||
ROTL24(rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
|
ROTL24(AEStb.rtable[(uint8_t)(x[ri[m + 2]] >> 24)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = x;
|
t = x;
|
||||||
@@ -382,10 +375,10 @@ void SoftwareAES::_decrypt(uint8_t* buff)
|
|||||||
/* Last Round - unroll if possible */
|
/* Last Round - unroll if possible */
|
||||||
for (m = j = 0; j < Nb; j++, m += 3)
|
for (m = j = 0; j < Nb; j++, m += 3)
|
||||||
{
|
{
|
||||||
y[j] = rkey[k++] ^ (uint32_t)rbsub[(uint8_t)x[j]] ^
|
y[j] = rkey[k++] ^ (uint32_t)AEStb.rbsub[(uint8_t)x[j]] ^
|
||||||
ROTL8((uint32_t)rbsub[(uint8_t)(x[ri[m]] >> 8)])^
|
ROTL8((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m]] >> 8)])^
|
||||||
ROTL16((uint32_t)rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^
|
ROTL16((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 1]] >> 16)])^
|
||||||
ROTL24((uint32_t)rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]);
|
ROTL24((uint32_t)AEStb.rbsub[(uint8_t)(x[ri[m + 2]] >> 24)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = j = 0; i < Nb; i++, j += 4)
|
for (i = j = 0; i < Nb; i++, j += 4)
|
||||||
@@ -399,7 +392,6 @@ void SoftwareAES::_decrypt(uint8_t* buff)
|
|||||||
|
|
||||||
void SoftwareAES::setKey(const uint8_t* key)
|
void SoftwareAES::setKey(const uint8_t* key)
|
||||||
{
|
{
|
||||||
gentables();
|
|
||||||
gkey(4, 4, key);
|
gkey(4, 4, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user