12 Commits
2.1.0 ... 2.3.0

Author SHA1 Message Date
Jack Andersen
f06afb429c Windows build fixes 2015-08-03 17:42:44 -10:00
Jack Andersen
3d220841c0 version macro fix 2015-08-02 15:47:09 -10:00
Jack Andersen
7a90a0f6d0 Embedded atdna in Athena 2015-08-02 15:42:47 -10:00
Jack Andersen
3edc800e10 Bumped version to 2.3.0 2015-08-02 18:29:39 -07:00
Jack Andersen
84591d4260 Added YAML serialization DNA subclass 2015-08-02 18:29:39 -07:00
Jack Andersen
43c317529c AES optimization and aligned SSE allocators 2015-08-02 18:29:39 -07:00
Jack Andersen
b38d7533c5 Exception args should be passed as c-string
(it's a compiled literal after-all)
2015-08-02 18:29:39 -07:00
Jack Andersen
b7d4c51979 more precise MSVC specification 2015-08-02 18:29:38 -07:00
Jack Andersen
ac36bb4f4a added support for wchar_t file paths and more stable windows builds 2015-08-02 18:29:38 -07:00
Jack Andersen
8e5e4d7603 Bumped CMake package to 2.2.0 2015-08-02 18:29:38 -07:00
d9c4d3b79b Add error state 2015-08-02 18:29:38 -07:00
8ea5071e0f Remove and replace exceptions 2015-08-02 18:29:38 -07:00
64 changed files with 16983 additions and 618 deletions

View File

@@ -6,7 +6,7 @@ project(Athena)
##################
set(ATHENA_MAJOR_VERSION 2)
set(ATHENA_MINOR_VERSION 1)
set(ATHENA_MINOR_VERSION 3)
set(ATHENA_PATCH_VERSION 0)
set(ATHENA_VERSION
${ATHENA_MAJOR_VERSION}.${ATHENA_MINOR_VERSION}.${ATHENA_PATCH_VERSION})
@@ -17,8 +17,10 @@ set(ATHENA_VERSION
add_subdirectory(extern)
include_directories(include ${LZO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
include_directories(include ${LZO_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR} ${YAML_INCLUDE_DIR})
if (NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()
if(WIN32)
list(APPEND CORE_EXTRA src/win32_largefilewrapper.c)
@@ -43,6 +45,7 @@ add_library(AthenaCore
src/LZ77/LZBase.cpp
src/Athena/FileInfo.cpp
src/Athena/Dir.cpp
src/Athena/DNAYaml.cpp
${CORE_EXTRA}
include/Athena/IStream.hpp
@@ -51,16 +54,10 @@ add_library(AthenaCore
include/Athena/Types.hpp
include/Athena/Utility.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/FileWriter.hpp
include/Athena/MemoryReader.hpp
include/Athena/MemoryWriter.hpp
include/Athena/NotImplementedException.hpp
include/Athena/Checksums.hpp
include/Athena/Compression.hpp
include/LZ77/LZBase.hpp
@@ -71,6 +68,7 @@ add_library(AthenaCore
include/Athena/Dir.hpp
include/gekko_support.h
include/Athena/DNA.hpp
include/Athena/DNAYaml.hpp
)
add_library(AthenaSakura
@@ -114,7 +112,9 @@ add_library(AthenaWiiSave
include/md5.h
include/sha1.h
)
if(NOT MSVC)
set_source_files_properties(src/aes.cpp PROPERTIES COMPILE_FLAGS -maes)
endif()
add_library(AthenaZelda
src/Athena/ALTTPFile.cpp
@@ -148,6 +148,9 @@ add_library(AthenaZelda
include/Athena/SkywardSwordQuest.hpp
)
# Icon
set(ATHENA_ICO ${CMAKE_CURRENT_SOURCE_DIR}/Athena.ico)
# Offer the user the choice of overriding the installation directories
set(INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries")
set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
@@ -218,9 +221,7 @@ install(EXPORT AthenaTargets DESTINATION ${INSTALL_CMAKE_DIR} COMPONENT Athena)
# atdna import #
################
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/atdna/CMakeLists.txt")
add_subdirectory(atdna)
endif()
add_subdirectory(atdna)
#########
# CPack #

View File

@@ -1,8 +1,7 @@
# PKGBUILD for libAthena
_pkgname=libathena
pkgname=$_pkgname-git
pkgver=2.0.0.9.gf3ba881
pkgrel=1
pkgver=2.3.0
pkgdesc="Basic cross platform IO library"
arch=('i686' 'x86_64')
source=("${pkgname%-*}::git+https://github.com/libAthena/Athena.git")

119
atdna/CMakeLists.txt Normal file
View File

@@ -0,0 +1,119 @@
###############
# ATDNA Build #
###############
# Find dependencies
include(FindLLVM.cmake)
if(NOT LLVM_FOUND)
message("-- Unable to locate LLVM installation; skipping atdna")
else()
list(APPEND LLVM_LIBS
clangFrontend
clangTooling
clangDriver
clangSerialization
clangParse
clangSema
clangAnalysis
clangEdit
clangAST
clangLex
clangBasic
LLVMOption
LLVMMCParser
LLVMBitReader
LLVMMC
LLVMSupport)
set(CLANG_INCLUDE_DIR ${LLVM_LIBRARY_DIRS}/clang/${LLVM_VERSION_STRING}/include)
if(UNIX)
list(APPEND PLAT_LIBS z pthread curses dl)
endif()
# Offer the user the choice of overriding the installation directories
set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files")
set(INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables")
if(WIN32 AND NOT CYGWIN)
set(INSTALL_CMAKE_DIR cmake)
else()
set(INSTALL_CMAKE_DIR lib/cmake/atdna)
endif()
# Make relative paths absolute (needed later on)
foreach(p BIN INCLUDE CMAKE)
set(var INSTALL_${p}_DIR)
if(NOT IS_ABSOLUTE "${${var}}")
set(ABS_${var} "${CMAKE_INSTALL_PREFIX}/${${var}}")
else()
set(ABS_${var} "${${var}}")
endif()
endforeach()
# Windows resource
if(WIN32)
configure_file(main.rc.in main.rc @ONLY)
set(PLAT_SRCS ${CMAKE_CURRENT_BINARY_DIR}/main.rc)
endif()
# ATDNA target
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
include_directories(${LLVM_INCLUDE_DIRS})
link_directories(${LLVM_LIBRARY_DIRS})
add_executable(atdna main.cpp test.hpp ${PLAT_SRCS})
target_link_libraries(atdna ${LLVM_LIBS} ${PLAT_LIBS})
set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS
"INSTALL_PREFIX=${ABS_INSTALL_BIN_DIR};__STDC_LIMIT_MACROS=1;__STDC_CONSTANT_MACROS=1")
if(MSVC)
set_target_properties(atdna PROPERTIES
COMPILE_FLAGS "/GR-")
else()
set_target_properties(atdna PROPERTIES
COMPILE_FLAGS "-std=c++11 -fno-rtti -Wno-unused-parameter"
LINK_FLAGS -std=c++11)
endif()
# Define installs
install(TARGETS atdna DESTINATION ${INSTALL_BIN_DIR} EXPORT atdnaTargets COMPONENT atdna)
install(DIRECTORY ${CLANG_INCLUDE_DIR}/ DESTINATION ${INSTALL_INCLUDE_DIR}/Athena/clang COMPONENT atdna)
##################
# Package Export #
##################
# Add all targets to the build-tree export set
export(TARGETS atdna FILE "${PROJECT_BINARY_DIR}/atdnaTargets.cmake")
# Export the package for use from the build-tree
# (this registers the build-tree with a global CMake-registry)
export(PACKAGE atdna)
# Create the atdnaConfig.cmake
# ... for the build tree
set(CONF_CLANG_INCLUDE_DIR "${CLANG_INCLUDE_DIR}")
configure_file(atdnaConfig.cmake.in "${PROJECT_BINARY_DIR}/atdnaConfig.cmake" @ONLY)
# ... for the install tree
set(CONF_CLANG_INCLUDE_DIR "\${ATHENA_INCLUDE_DIR}/clang")
configure_file(atdnaConfig.cmake.in "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/atdnaConfig.cmake" @ONLY)
# ... for both
configure_file(atdnaConfigVersion.cmake.in "${PROJECT_BINARY_DIR}/atdnaConfigVersion.cmake" @ONLY)
# Install atdnaConfig.cmake
install(FILES
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/atdnaConfig.cmake"
"${PROJECT_BINARY_DIR}/atdnaConfigVersion.cmake"
DESTINATION ${INSTALL_CMAKE_DIR} COMPONENT atdna)
# Install the export set for use with the install-tree
install(EXPORT atdnaTargets DESTINATION ${INSTALL_CMAKE_DIR} COMPONENT atdna)
#########
# CTest #
#########
enable_testing()
add_test(NAME test-dna COMMAND $<TARGET_FILE:atdna> -o test.cpp
"-I${ATHENA_INCLUDE_DIR}" -isystem "${CLANG_INCLUDE_DIR}"
${CMAKE_SOURCE_DIR}/test.hpp)
endif()

205
atdna/FindLLVM.cmake Normal file
View File

@@ -0,0 +1,205 @@
# - Find LLVM headers and libraries.
# This module locates LLVM and adapts the llvm-config output for use with
# CMake.
#
# A given list of COMPONENTS is passed to llvm-config.
#
# The following variables are defined:
# LLVM_FOUND - true if LLVM was found
# LLVM_CXXFLAGS - C++ compiler flags for files that include LLVM headers.
# LLVM_HOST_TARGET - Target triple used to configure LLVM.
# LLVM_INCLUDE_DIRS - Directory containing LLVM include files.
# LLVM_LDFLAGS - Linker flags to add when linking against LLVM
# (includes -LLLVM_LIBRARY_DIRS).
# LLVM_LIBRARIES - Full paths to the library files to link against.
# LLVM_LIBRARY_DIRS - Directory containing LLVM libraries.
# LLVM_ROOT_DIR - The root directory of the LLVM installation.
# llvm-config is searched for in ${LLVM_ROOT_DIR}/bin.
# LLVM_VERSION_MAJOR - Major version of LLVM.
# LLVM_VERSION_MINOR - Minor version of LLVM.
# LLVM_VERSION_STRING - Full LLVM version string (e.g. 2.9).
#
# Note: The variable names were chosen in conformance with the offical CMake
# guidelines, see ${CMAKE_ROOT}/Modules/readme.txt.
# Try suffixed versions to pick up the newest LLVM install available on Debian
# derivatives.
# We also want an user-specified LLVM_ROOT_DIR to take precedence over the
# system default locations such as /usr/local/bin. Executing find_program()
# multiples times is the approach recommended in the docs.
set(LLVM_FIND_COMPONENTS "")
if(WIN32)
get_filename_component(LLVM_ROOT_DIR [HKEY_LOCAL_MACHINE\\Software\\LLVM\\LLVM] ABSOLUTE)
endif()
set(llvm_config_names llvm-config-3.7 llvm-config37
llvm-config-3.6 llvm-config36
llvm-config-3.5 llvm-config35
llvm-config-3.4 llvm-config34
llvm-config-3.3 llvm-config33
llvm-config-3.2 llvm-config32
llvm-config-3.1 llvm-config31 llvm-config)
find_program(LLVM_CONFIG
NAMES ${llvm_config_names}
PATHS ${LLVM_ROOT_DIR}/bin NO_DEFAULT_PATH
DOC "Path to llvm-config tool.")
find_program(LLVM_CONFIG NAMES ${llvm_config_names})
if ((WIN32 AND NOT(MINGW OR CYGWIN)) OR NOT LLVM_CONFIG)
if (WIN32)
# A bit of a sanity check:
if( NOT EXISTS ${LLVM_ROOT_DIR}/include/llvm )
message(FATAL_ERROR "LLVM_ROOT_DIR (${LLVM_ROOT_DIR}) is not a valid LLVM install")
endif()
# We incorporate the CMake features provided by LLVM:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${LLVM_ROOT_DIR}/share/llvm/cmake")
include(LLVMConfig)
# Set properties
set(LLVM_HOST_TARGET ${TARGET_TRIPLE})
set(LLVM_VERSION_STRING ${LLVM_PACKAGE_VERSION})
set(LLVM_CXXFLAGS ${LLVM_DEFINITIONS})
set(LLVM_LDFLAGS "")
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "all-targets" index)
list(APPEND LLVM_FIND_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
# Work around LLVM bug 21016
list(FIND LLVM_TARGETS_TO_BUILD "X86" TARGET_X86)
if(TARGET_X86 GREATER -1)
list(APPEND LLVM_FIND_COMPONENTS x86utils)
endif()
# Similar to the work around above, but for AArch64
list(FIND LLVM_TARGETS_TO_BUILD "AArch64" TARGET_AArch64)
if(TARGET_AArch64 GREATER -1)
list(APPEND LLVM_FIND_COMPONENTS AArch64Utils)
endif()
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "backend" index)
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-2][\\.0-9A-Za-z]*")
# Versions below 3.3 do not support components objcarcopts, option
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "objcarcopts" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "option" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
# Versions below 3.5 do not support components lto, profiledata
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "lto" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "profiledata" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-6][\\.0-9A-Za-z]*")
# Versions below 3.7 do not support components debuginfodwarf
# Only debuginfo is available
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
llvm_map_components_to_libraries(tmplibs ${LLVM_FIND_COMPONENTS})
else()
llvm_map_components_to_libnames(tmplibs ${LLVM_FIND_COMPONENTS})
endif()
if(MSVC)
foreach(lib ${tmplibs})
list(APPEND LLVM_LIBRARIES "${LLVM_LIBRARY_DIRS}/${CMAKE_STATIC_LIBRARY_PREFIX}${lib}${CMAKE_STATIC_LIBRARY_SUFFIX}")
endforeach()
else()
# Rely on the library search path being set correctly via -L on
# MinGW and others, as the library list returned by
# llvm_map_components_to_libraries also includes imagehlp and psapi.
set(LLVM_LDFLAGS "-L${LLVM_LIBRARY_DIRS}")
set(LLVM_LIBRARIES ${tmplibs})
endif()
# When using the CMake LLVM module, LLVM_DEFINITIONS is a list
# instead of a string. Later, the list seperators would entirely
# disappear, replace them by spaces instead. A better fix would be
# to switch to add_definitions() instead of throwing strings around.
string(REPLACE ";" " " LLVM_CXXFLAGS "${LLVM_CXXFLAGS}")
else()
if (NOT FIND_LLVM_QUIETLY)
message(WARNING "Could not find llvm-config. Try manually setting LLVM_ROOT_DIR to the prebuilt LLVM prefix to use.")
endif()
endif()
else()
macro(llvm_set var flag)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
execute_process(
COMMAND ${LLVM_CONFIG} --${flag}
OUTPUT_VARIABLE LLVM_${var}
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
if(${ARGV2})
file(TO_CMAKE_PATH "${LLVM_${var}}" LLVM_${var})
endif()
endmacro()
macro(llvm_set_libs var flag prefix)
if(LLVM_FIND_QUIETLY)
set(_quiet_arg ERROR_QUIET)
endif()
execute_process(
COMMAND ${LLVM_CONFIG} --${flag} ${LLVM_FIND_COMPONENTS}
OUTPUT_VARIABLE tmplibs
OUTPUT_STRIP_TRAILING_WHITESPACE
${_quiet_arg}
)
file(TO_CMAKE_PATH "${tmplibs}" tmplibs)
string(REGEX REPLACE "([$^.[|*+?()]|])" "\\\\\\1" pattern "${prefix}/")
string(REGEX MATCHALL "${pattern}[^ ]+" LLVM_${var} ${tmplibs})
endmacro()
llvm_set(VERSION_STRING version)
llvm_set(CXXFLAGS cxxflags)
llvm_set(HOST_TARGET host-target)
llvm_set(INCLUDE_DIRS includedir true)
llvm_set(ROOT_DIR prefix true)
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-2][\\.0-9A-Za-z]*")
# Versions below 3.3 do not support components objcarcopts, option
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "objcarcopts" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "option" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
# Versions below 3.5 do not support components lto, profiledata
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "lto" index)
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "profiledata" index)
endif()
if(${LLVM_VERSION_STRING} MATCHES "^3\\.[0-6][\\.0-9A-Za-z]*")
# Versions below 3.7 do not support components debuginfodwarf
# Only debuginfo is available
list(REMOVE_ITEM LLVM_FIND_COMPONENTS "debuginfodwarf" index)
list(APPEND LLVM_FIND_COMPONENTS "debuginfo")
endif()
llvm_set(LDFLAGS ldflags)
if(NOT ${LLVM_VERSION_STRING} MATCHES "^3\\.[0-4][\\.0-9A-Za-z]*")
# In LLVM 3.5+, the system library dependencies (e.g. "-lz") are accessed
# using the separate "--system-libs" flag.
llvm_set(SYSTEM_LIBS system-libs)
string(REPLACE "\n" " " LLVM_LDFLAGS "${LLVM_LDFLAGS} ${LLVM_SYSTEM_LIBS}")
endif()
llvm_set(LIBRARY_DIRS libdir true)
llvm_set_libs(LIBRARIES libfiles "${LLVM_LIBRARY_DIRS}")
endif()
# On CMake builds of LLVM, the output of llvm-config --cxxflags does not
# include -fno-rtti, leading to linker errors. Be sure to add it.
if(CMAKE_COMPILER_IS_GNUCXX OR (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
if(NOT ${LLVM_CXXFLAGS} MATCHES "-fno-rtti")
set(LLVM_CXXFLAGS "${LLVM_CXXFLAGS} -fno-rtti")
endif()
endif()
string(REGEX REPLACE "([0-9]+).*" "\\1" LLVM_VERSION_MAJOR "${LLVM_VERSION_STRING}" )
string(REGEX REPLACE "[0-9]+\\.([0-9]+).*[A-Za-z]*" "\\1" LLVM_VERSION_MINOR "${LLVM_VERSION_STRING}" )
# Use the default CMake facilities for handling QUIET/REQUIRED.
include(FindPackageHandleStandardArgs)
if(${CMAKE_VERSION} VERSION_LESS "2.8.4")
# The VERSION_VAR argument is not supported on pre-2.8.4, work around this.
set(VERSION_VAR dummy)
endif()
find_package_handle_standard_args(LLVM
REQUIRED_VARS LLVM_ROOT_DIR LLVM_HOST_TARGET
VERSION_VAR LLVM_VERSION_STRING)

3
atdna/README.md Normal file
View File

@@ -0,0 +1,3 @@
# atdna
[User Overview](http://libAthena.github.io/doc/atdna.html)
[DNA Record Reference](http://libAthena.github.io/doc/atdna-ref.html)

View File

@@ -0,0 +1,52 @@
# - Config file for the atdna package
# Compute paths
get_filename_component(ATHENA_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# Our library dependencies (contains definitions for IMPORTED targets)
if(NOT TARGET atdna AND NOT atdna_BINARY_DIR)
include("${ATHENA_CMAKE_DIR}/atdnaTargets.cmake")
endif()
# Find Athena
find_package(Athena REQUIRED)
# Super handy macro for adding atdna target
macro(atdna out)
# Make input files source-relative
set(ins "")
foreach(arg ${ARGN})
list(APPEND ins ${CMAKE_CURRENT_SOURCE_DIR}/${arg})
endforeach()
# Get local include directories for atdna
get_property(incdirs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
set(inccli "")
foreach(dir ${incdirs})
list(APPEND inccli "-I${dir}")
endforeach()
# Get local defines for atdna
get_property(cdefs DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY COMPILE_DEFINITIONS)
set(cdefcli "")
foreach(def ${cdefs})
list(APPEND cdefcli "-D${def}")
endforeach()
# MS extra
unset(extraargs)
if(MSVC)
list(APPEND extraargs -fms-compatibility -fexceptions)
if(MSVC_VERSION EQUAL 1800)
list(APPEND extraargs -fms-compatibility-version=18.00)
elseif(MSVC_VERSION EQUAL 1900)
list(APPEND extraargs -fms-compatibility-version=19.00)
endif()
endif()
# Make target
add_custom_command(OUTPUT ${out} COMMAND $<TARGET_FILE:atdna>
ARGS ${extraargs} -o ${out} ${cdefcli} ${inccli} "-I${ATHENA_INCLUDE_DIR}" -isystem "@CONF_CLANG_INCLUDE_DIR@" ${ins}
DEPENDS ${ins} COMMENT "Generating DNA ${out}")
endmacro()

View File

@@ -0,0 +1,12 @@
set(PACKAGE_VERSION "@ATHENA_VERSION@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()

1654
atdna/main.cpp Normal file

File diff suppressed because it is too large Load Diff

32
atdna/main.rc.in Normal file
View File

@@ -0,0 +1,32 @@
#include "winver.h"
IDI_ICON1 ICON DISCARDABLE "@ATHENA_ICO@"
VS_VERSION_INFO VERSIONINFO
FILEVERSION @ATHENA_MAJOR_VERSION@,@ATHENA_MINOR_VERSION@,@ATHENA_PATCH_VERSION@,0
PRODUCTVERSION @ATHENA_MAJOR_VERSION@,@ATHENA_MINOR_VERSION@,@ATHENA_PATCH_VERSION@,0
FILEFLAGS 0x0L
FILEFLAGSMASK 0x3fL
FILEOS 0x00040004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "000004b0"
BEGIN
VALUE "CompanyName", "Jackoalan / Antidote"
VALUE "FileDescription", "ATDNA"
VALUE "FileVersion", "@ATHENA_MAJOR_VERSION@.@ATHENA_MINOR_VERSION@.@ATHENA_PATCH_VERSION@"
VALUE "LegalCopyright", "Copyright (C) 2015 Jackoalan / Antidote"
VALUE "InternalName", "atdna"
VALUE "OriginalFilename", "atdna.exe"
VALUE "ProductName", "ATDNA"
VALUE "ProductVersion", "@ATHENA_MAJOR_VERSION@.@ATHENA_MINOR_VERSION@.@ATHENA_PATCH_VERSION@"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0, 1200
END
END

75
atdna/test.hpp Normal file
View File

@@ -0,0 +1,75 @@
#include <Athena/DNAYaml.hpp>
using namespace Athena;
typedef io::DNAYaml<BigEndian> BigDNA;
struct TESTSubFile : public BigDNA
{
DECL_DNA
DECL_YAML
Value<atUint32> sub1;
Value<atUint32> sub2;
};
struct TESTSubClassFile : public TESTSubFile
{
DECL_DNA
DECL_YAML
Value<atUint32> sub3;
Value<atUint32> sub4;
};
struct TESTSubSubClassFile : public TESTSubClassFile
{
DECL_DNA
DECL_YAML
Value<atUint32> sub5;
Value<atUint32> sub6;
};
struct TESTFile : public BigDNA
{
DECL_DNA
DECL_YAML
Value<bool> varBool;
Value<atUint32> var32;
Value<atUint16> var16;
Value<atVec3f> vec3;
Value<atVec4f> vec4;
struct TESTNestedSubFile : public BigDNA
{
DECL_DNA
DECL_YAML
Value<atUint32> nestSub1;
Value<atUint32> nestSub2;
} nestedSubFile;
TESTSubFile subFile;
Align<4> align;
struct TESTExplicitSubFile : public BigDNA
{
DECL_EXPLICIT_DNA
DECL_YAML
Value<atUint32> explSub1;
Value<atUint32> explSub2;
} explSubFile;
Value<atUint32> arrCount[2];
Vector<atUint32, DNA_COUNT(arrCount[0])> array;
Seek<21, Current> seek;
Value<atUint32> arrCount2;
Vector<TESTSubFile, DNA_COUNT(arrCount[1] + arrCount2)> array2;
Value<atUint32> bufSz;
Buffer<DNA_COUNT(bufSz)> buf;
String<32> str;
WString<64> wstr;
WStringAsString<> utf8str[5];
};

View File

@@ -1,2 +1,3 @@
add_subdirectory(lzo)
add_subdirectory(zlib)
add_subdirectory(yaml)

21
extern/yaml/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,21 @@
# Minimal CMake project for building a static library under Windows.
cmake_minimum_required(VERSION 2.8)
project(yaml C)
set(YAML_VERSION_MAJOR 0)
set(YAML_VERSION_MINOR 1)
set(YAML_VERSION_PATCH 6)
set(YAML_VERSION_STRING "${YAML_VERSION_MAJOR}.${YAML_VERSION_MINOR}.${YAML_VERSION_PATCH}")
file(GLOB SRC src/*.c)
include_directories(include win32)
add_definitions(-DYAML_DECLARE_STATIC)
add_library(yaml STATIC ${SRC} include/yaml.h)
set(YAML_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE PATH "YAML include path" FORCE)
if(WIN32 AND NOT UNIX)
install(DIRECTORY include/ DESTINATION include COMPONENT yaml)
install(TARGETS yaml DESTINATION lib COMPONENT yaml)
endif()

19
extern/yaml/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2006 Kirill Simonov
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

27
extern/yaml/README vendored Normal file
View File

@@ -0,0 +1,27 @@
LibYAML - A C library for parsing and emitting YAML.
To build and install the library, run:
$ ./configure
$ make
# make install
If you checked the source code from the Subversion repository, run
$ ./bootstrap
$ ./configure
$ make
# make install
For more information, check the LibYAML homepage:
'http://pyyaml.org/wiki/LibYAML'.
Post your questions and opinions to the YAML-Core mailing list:
'http://lists.sourceforge.net/lists/listinfo/yaml-core'.
Submit bug reports and feature requests to the LibYAML bug tracker:
'http://pyyaml.org/newticket?component=libyaml'.
LibYAML is written by Kirill Simonov <xi@resolvent.net>. It is released
under the MIT license. See the file LICENSE for more details.
This project is developed for Python Software Foundation as a part of
Google Summer of Code under the mentorship of Clark Evans.

28
extern/yaml/announcement.msg vendored Normal file
View File

@@ -0,0 +1,28 @@
From: Kirill Simonov <xi@resolvent.net>
To: yaml-core@lists.sourceforge.net
Subject: LibYAML-0.1.4: A minor bugfix release
This is a minor bugfix release of LibYAML, a YAML parser and emitter
written in C:
* Fixed a bug that prevented an empty mapping being used as a simple key
(thank to spitzak(at)rhythm(dot)com).
* Fixed pointer overflow when calculating the position of a potential
simple key (thank to ppelletier(at)oblong(dot)com).
* Fixed yaml.dll not exporting any symbols
(thank to pxn11432(at)nifty(dot)com).
* Added pkg-config support (thank to rainwoodman(at)gmail(dot)com).
LibYAML homepage: http://pyyaml.org/wiki/LibYAML
TAR.GZ package: http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
SVN repository: http://svn.pyyaml.org/libyaml/branches/stable
Bug tracker: http://pyyaml.org/newticket?component=libyaml
The library is functionally complete, but the documentation is scarce
and the API may change. For more information, you may check the project
homepage, the doxygen-generated documentation in the `doc` directory of
the source distribution, and examples in the `tests` directory.
LibYAML is written by Kirill Simonov <xi@resolvent.net> and released
under the MIT license; see the file LICENSE for more details.

1971
extern/yaml/include/yaml.h vendored Normal file

File diff suppressed because it is too large Load Diff

1392
extern/yaml/src/api.c vendored Normal file

File diff suppressed because it is too large Load Diff

4
extern/yaml/src/config.h vendored Normal file
View File

@@ -0,0 +1,4 @@
#define YAML_VERSION_MAJOR 0
#define YAML_VERSION_MINOR 1
#define YAML_VERSION_PATCH 6
#define YAML_VERSION_STRING "0.1.6"

394
extern/yaml/src/dumper.c vendored Normal file
View File

@@ -0,0 +1,394 @@
#include "yaml_private.h"
/*
* API functions.
*/
YAML_DECLARE(int)
yaml_emitter_open(yaml_emitter_t *emitter);
YAML_DECLARE(int)
yaml_emitter_close(yaml_emitter_t *emitter);
YAML_DECLARE(int)
yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document);
/*
* Clean up functions.
*/
static void
yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter);
/*
* Anchor functions.
*/
static void
yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index);
static yaml_char_t *
yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id);
/*
* Serialize functions.
*/
static int
yaml_emitter_dump_node(yaml_emitter_t *emitter, int index);
static int
yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor);
static int
yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor);
static int
yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor);
static int
yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor);
/*
* Issue a STREAM-START event.
*/
YAML_DECLARE(int)
yaml_emitter_open(yaml_emitter_t *emitter)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
assert(emitter); /* Non-NULL emitter object is required. */
assert(!emitter->opened); /* Emitter should not be opened yet. */
STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) {
return 0;
}
emitter->opened = 1;
return 1;
}
/*
* Issue a STREAM-END event.
*/
YAML_DECLARE(int)
yaml_emitter_close(yaml_emitter_t *emitter)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
assert(emitter); /* Non-NULL emitter object is required. */
assert(emitter->opened); /* Emitter should be opened. */
if (emitter->closed) return 1;
STREAM_END_EVENT_INIT(event, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) {
return 0;
}
emitter->closed = 1;
return 1;
}
/*
* Dump a YAML document.
*/
YAML_DECLARE(int)
yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
assert(emitter); /* Non-NULL emitter object is required. */
assert(document); /* Non-NULL emitter object is expected. */
emitter->document = document;
if (!emitter->opened) {
if (!yaml_emitter_open(emitter)) goto error;
}
if (STACK_EMPTY(emitter, document->nodes)) {
if (!yaml_emitter_close(emitter)) goto error;
yaml_emitter_delete_document_and_anchors(emitter);
return 1;
}
assert(emitter->opened); /* Emitter should be opened. */
emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors))
* (document->nodes.top - document->nodes.start));
if (!emitter->anchors) goto error;
memset(emitter->anchors, 0, sizeof(*(emitter->anchors))
* (document->nodes.top - document->nodes.start));
DOCUMENT_START_EVENT_INIT(event, document->version_directive,
document->tag_directives.start, document->tag_directives.end,
document->start_implicit, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) goto error;
yaml_emitter_anchor_node(emitter, 1);
if (!yaml_emitter_dump_node(emitter, 1)) goto error;
DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) goto error;
yaml_emitter_delete_document_and_anchors(emitter);
return 1;
error:
yaml_emitter_delete_document_and_anchors(emitter);
return 0;
}
/*
* Clean up the emitter object after a document is dumped.
*/
static void
yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter)
{
int index;
if (!emitter->anchors) {
yaml_document_delete(emitter->document);
emitter->document = NULL;
return;
}
for (index = 0; emitter->document->nodes.start + index
< emitter->document->nodes.top; index ++) {
yaml_node_t node = emitter->document->nodes.start[index];
if (!emitter->anchors[index].serialized) {
yaml_free(node.tag);
if (node.type == YAML_SCALAR_NODE) {
yaml_free(node.data.scalar.value);
}
}
if (node.type == YAML_SEQUENCE_NODE) {
STACK_DEL(emitter, node.data.sequence.items);
}
if (node.type == YAML_MAPPING_NODE) {
STACK_DEL(emitter, node.data.mapping.pairs);
}
}
STACK_DEL(emitter, emitter->document->nodes);
yaml_free(emitter->anchors);
emitter->anchors = NULL;
emitter->last_anchor_id = 0;
emitter->document = NULL;
}
/*
* Check the references of a node and assign the anchor id if needed.
*/
static void
yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index)
{
yaml_node_t *node = emitter->document->nodes.start + index - 1;
yaml_node_item_t *item;
yaml_node_pair_t *pair;
emitter->anchors[index-1].references ++;
if (emitter->anchors[index-1].references == 1) {
switch (node->type) {
case YAML_SEQUENCE_NODE:
for (item = node->data.sequence.items.start;
item < node->data.sequence.items.top; item ++) {
yaml_emitter_anchor_node(emitter, *item);
}
break;
case YAML_MAPPING_NODE:
for (pair = node->data.mapping.pairs.start;
pair < node->data.mapping.pairs.top; pair ++) {
yaml_emitter_anchor_node(emitter, pair->key);
yaml_emitter_anchor_node(emitter, pair->value);
}
break;
default:
break;
}
}
else if (emitter->anchors[index-1].references == 2) {
emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id);
}
}
/*
* Generate a textual representation for an anchor.
*/
#define ANCHOR_TEMPLATE "id%03d"
#define ANCHOR_TEMPLATE_LENGTH 16
static yaml_char_t *
yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id)
{
yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH);
if (!anchor) return NULL;
sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id);
return anchor;
}
/*
* Serialize a node.
*/
static int
yaml_emitter_dump_node(yaml_emitter_t *emitter, int index)
{
yaml_node_t *node = emitter->document->nodes.start + index - 1;
int anchor_id = emitter->anchors[index-1].anchor;
yaml_char_t *anchor = NULL;
if (anchor_id) {
anchor = yaml_emitter_generate_anchor(emitter, anchor_id);
if (!anchor) return 0;
}
if (emitter->anchors[index-1].serialized) {
return yaml_emitter_dump_alias(emitter, anchor);
}
emitter->anchors[index-1].serialized = 1;
switch (node->type) {
case YAML_SCALAR_NODE:
return yaml_emitter_dump_scalar(emitter, node, anchor);
case YAML_SEQUENCE_NODE:
return yaml_emitter_dump_sequence(emitter, node, anchor);
case YAML_MAPPING_NODE:
return yaml_emitter_dump_mapping(emitter, node, anchor);
default:
assert(0); /* Could not happen. */
break;
}
return 0; /* Could not happen. */
}
/*
* Serialize an alias.
*/
static int
yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
ALIAS_EVENT_INIT(event, anchor, mark, mark);
return yaml_emitter_emit(emitter, &event);
}
/*
* Serialize a scalar.
*/
static int
yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
int plain_implicit = (strcmp((char *)node->tag,
YAML_DEFAULT_SCALAR_TAG) == 0);
int quoted_implicit = (strcmp((char *)node->tag,
YAML_DEFAULT_SCALAR_TAG) == 0);
SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value,
node->data.scalar.length, plain_implicit, quoted_implicit,
node->data.scalar.style, mark, mark);
return yaml_emitter_emit(emitter, &event);
}
/*
* Serialize a sequence.
*/
static int
yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0);
yaml_node_item_t *item;
SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit,
node->data.sequence.style, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
for (item = node->data.sequence.items.start;
item < node->data.sequence.items.top; item ++) {
if (!yaml_emitter_dump_node(emitter, *item)) return 0;
}
SEQUENCE_END_EVENT_INIT(event, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
return 1;
}
/*
* Serialize a mapping.
*/
static int
yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node,
yaml_char_t *anchor)
{
yaml_event_t event;
yaml_mark_t mark = { 0, 0, 0 };
int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0);
yaml_node_pair_t *pair;
MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit,
node->data.mapping.style, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
for (pair = node->data.mapping.pairs.start;
pair < node->data.mapping.pairs.top; pair ++) {
if (!yaml_emitter_dump_node(emitter, pair->key)) return 0;
if (!yaml_emitter_dump_node(emitter, pair->value)) return 0;
}
MAPPING_END_EVENT_INIT(event, mark, mark);
if (!yaml_emitter_emit(emitter, &event)) return 0;
return 1;
}

2329
extern/yaml/src/emitter.c vendored Normal file

File diff suppressed because it is too large Load Diff

444
extern/yaml/src/loader.c vendored Normal file
View File

@@ -0,0 +1,444 @@
#include "yaml_private.h"
/*
* API functions.
*/
YAML_DECLARE(int)
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);
/*
* Error handling.
*/
static int
yaml_parser_set_composer_error(yaml_parser_t *parser,
const char *problem, yaml_mark_t problem_mark);
static int
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
const char *context, yaml_mark_t context_mark,
const char *problem, yaml_mark_t problem_mark);
/*
* Alias handling.
*/
static int
yaml_parser_register_anchor(yaml_parser_t *parser,
int index, yaml_char_t *anchor);
/*
* Clean up functions.
*/
static void
yaml_parser_delete_aliases(yaml_parser_t *parser);
/*
* Composer functions.
*/
static int
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);
static int
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);
/*
* Load the next document of the stream.
*/
YAML_DECLARE(int)
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
{
yaml_event_t event;
assert(parser); /* Non-NULL parser object is expected. */
assert(document); /* Non-NULL document object is expected. */
memset(document, 0, sizeof(yaml_document_t));
if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
goto error;
if (!parser->stream_start_produced) {
if (!yaml_parser_parse(parser, &event)) goto error;
assert(event.type == YAML_STREAM_START_EVENT);
/* STREAM-START is expected. */
}
if (parser->stream_end_produced) {
return 1;
}
if (!yaml_parser_parse(parser, &event)) goto error;
if (event.type == YAML_STREAM_END_EVENT) {
return 1;
}
if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
goto error;
parser->document = document;
if (!yaml_parser_load_document(parser, &event)) goto error;
yaml_parser_delete_aliases(parser);
parser->document = NULL;
return 1;
error:
yaml_parser_delete_aliases(parser);
yaml_document_delete(document);
parser->document = NULL;
return 0;
}
/*
* Set composer error.
*/
static int
yaml_parser_set_composer_error(yaml_parser_t *parser,
const char *problem, yaml_mark_t problem_mark)
{
parser->error = YAML_COMPOSER_ERROR;
parser->problem = problem;
parser->problem_mark = problem_mark;
return 0;
}
/*
* Set composer error with context.
*/
static int
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
const char *context, yaml_mark_t context_mark,
const char *problem, yaml_mark_t problem_mark)
{
parser->error = YAML_COMPOSER_ERROR;
parser->context = context;
parser->context_mark = context_mark;
parser->problem = problem;
parser->problem_mark = problem_mark;
return 0;
}
/*
* Delete the stack of aliases.
*/
static void
yaml_parser_delete_aliases(yaml_parser_t *parser)
{
while (!STACK_EMPTY(parser, parser->aliases)) {
yaml_free(POP(parser, parser->aliases).anchor);
}
STACK_DEL(parser, parser->aliases);
}
/*
* Compose a document object.
*/
static int
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_event_t event;
assert(first_event->type == YAML_DOCUMENT_START_EVENT);
/* DOCUMENT-START is expected. */
parser->document->version_directive
= first_event->data.document_start.version_directive;
parser->document->tag_directives.start
= first_event->data.document_start.tag_directives.start;
parser->document->tag_directives.end
= first_event->data.document_start.tag_directives.end;
parser->document->start_implicit
= first_event->data.document_start.implicit;
parser->document->start_mark = first_event->start_mark;
if (!yaml_parser_parse(parser, &event)) return 0;
if (!yaml_parser_load_node(parser, &event)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
assert(event.type == YAML_DOCUMENT_END_EVENT);
/* DOCUMENT-END is expected. */
parser->document->end_implicit = event.data.document_end.implicit;
parser->document->end_mark = event.end_mark;
return 1;
}
/*
* Compose a node.
*/
static int
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
{
switch (first_event->type) {
case YAML_ALIAS_EVENT:
return yaml_parser_load_alias(parser, first_event);
case YAML_SCALAR_EVENT:
return yaml_parser_load_scalar(parser, first_event);
case YAML_SEQUENCE_START_EVENT:
return yaml_parser_load_sequence(parser, first_event);
case YAML_MAPPING_START_EVENT:
return yaml_parser_load_mapping(parser, first_event);
default:
assert(0); /* Could not happen. */
return 0;
}
return 0;
}
/*
* Add an anchor.
*/
static int
yaml_parser_register_anchor(yaml_parser_t *parser,
int index, yaml_char_t *anchor)
{
yaml_alias_data_t data;
yaml_alias_data_t *alias_data;
if (!anchor) return 1;
data.anchor = anchor;
data.index = index;
data.mark = parser->document->nodes.start[index-1].start_mark;
for (alias_data = parser->aliases.start;
alias_data != parser->aliases.top; alias_data ++) {
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
return yaml_parser_set_composer_error_context(parser,
"found duplicate anchor; first occurence",
alias_data->mark, "second occurence", data.mark);
}
}
if (!PUSH(parser, parser->aliases, data)) {
yaml_free(anchor);
return 0;
}
return 1;
}
/*
* Compose a node corresponding to an alias.
*/
static int
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_char_t *anchor = first_event->data.alias.anchor;
yaml_alias_data_t *alias_data;
for (alias_data = parser->aliases.start;
alias_data != parser->aliases.top; alias_data ++) {
if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
yaml_free(anchor);
return alias_data->index;
}
}
yaml_free(anchor);
return yaml_parser_set_composer_error(parser, "found undefined alias",
first_event->start_mark);
}
/*
* Compose a scalar node.
*/
static int
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_node_t node;
int index;
yaml_char_t *tag = first_event->data.scalar.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
if (!tag || strcmp((char *)tag, "!") == 0) {
yaml_free(tag);
tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
if (!tag) goto error;
}
SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
first_event->data.scalar.length, first_event->data.scalar.style,
first_event->start_mark, first_event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
first_event->data.scalar.anchor)) return 0;
return index;
error:
yaml_free(tag);
yaml_free(first_event->data.scalar.anchor);
yaml_free(first_event->data.scalar.value);
return 0;
}
/*
* Compose a sequence node.
*/
static int
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_event_t event;
yaml_node_t node;
struct {
yaml_node_item_t *start;
yaml_node_item_t *end;
yaml_node_item_t *top;
} items = { NULL, NULL, NULL };
int index, item_index;
yaml_char_t *tag = first_event->data.sequence_start.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
if (!tag || strcmp((char *)tag, "!") == 0) {
yaml_free(tag);
tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
if (!tag) goto error;
}
if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;
SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
first_event->data.sequence_start.style,
first_event->start_mark, first_event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
first_event->data.sequence_start.anchor)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
while (event.type != YAML_SEQUENCE_END_EVENT) {
if (!STACK_LIMIT(parser,
parser->document->nodes.start[index-1].data.sequence.items,
INT_MAX-1)) return 0;
item_index = yaml_parser_load_node(parser, &event);
if (!item_index) return 0;
if (!PUSH(parser,
parser->document->nodes.start[index-1].data.sequence.items,
item_index)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
}
parser->document->nodes.start[index-1].end_mark = event.end_mark;
return index;
error:
yaml_free(tag);
yaml_free(first_event->data.sequence_start.anchor);
return 0;
}
/*
* Compose a mapping node.
*/
static int
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
{
yaml_event_t event;
yaml_node_t node;
struct {
yaml_node_pair_t *start;
yaml_node_pair_t *end;
yaml_node_pair_t *top;
} pairs = { NULL, NULL, NULL };
int index;
yaml_node_pair_t pair;
yaml_char_t *tag = first_event->data.mapping_start.tag;
if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error;
if (!tag || strcmp((char *)tag, "!") == 0) {
yaml_free(tag);
tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
if (!tag) goto error;
}
if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;
MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
first_event->data.mapping_start.style,
first_event->start_mark, first_event->end_mark);
if (!PUSH(parser, parser->document->nodes, node)) goto error;
index = parser->document->nodes.top - parser->document->nodes.start;
if (!yaml_parser_register_anchor(parser, index,
first_event->data.mapping_start.anchor)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
while (event.type != YAML_MAPPING_END_EVENT) {
if (!STACK_LIMIT(parser,
parser->document->nodes.start[index-1].data.mapping.pairs,
INT_MAX-1)) return 0;
pair.key = yaml_parser_load_node(parser, &event);
if (!pair.key) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
pair.value = yaml_parser_load_node(parser, &event);
if (!pair.value) return 0;
if (!PUSH(parser,
parser->document->nodes.start[index-1].data.mapping.pairs,
pair)) return 0;
if (!yaml_parser_parse(parser, &event)) return 0;
}
parser->document->nodes.start[index-1].end_mark = event.end_mark;
return index;
error:
yaml_free(tag);
yaml_free(first_event->data.mapping_start.anchor);
return 0;
}

1374
extern/yaml/src/parser.c vendored Normal file

File diff suppressed because it is too large Load Diff

469
extern/yaml/src/reader.c vendored Normal file
View File

@@ -0,0 +1,469 @@
#include "yaml_private.h"
/*
* Declarations.
*/
static int
yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
size_t offset, int value);
static int
yaml_parser_update_raw_buffer(yaml_parser_t *parser);
static int
yaml_parser_determine_encoding(yaml_parser_t *parser);
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
/*
* Set the reader error and return 0.
*/
static int
yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem,
size_t offset, int value)
{
parser->error = YAML_READER_ERROR;
parser->problem = problem;
parser->problem_offset = offset;
parser->problem_value = value;
return 0;
}
/*
* Byte order marks.
*/
#define BOM_UTF8 "\xef\xbb\xbf"
#define BOM_UTF16LE "\xff\xfe"
#define BOM_UTF16BE "\xfe\xff"
/*
* Determine the input stream encoding by checking the BOM symbol. If no BOM is
* found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure.
*/
static int
yaml_parser_determine_encoding(yaml_parser_t *parser)
{
/* Ensure that we had enough bytes in the raw buffer. */
while (!parser->eof
&& parser->raw_buffer.last - parser->raw_buffer.pointer < 3) {
if (!yaml_parser_update_raw_buffer(parser)) {
return 0;
}
}
/* Determine the encoding. */
if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
&& !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) {
parser->encoding = YAML_UTF16LE_ENCODING;
parser->raw_buffer.pointer += 2;
parser->offset += 2;
}
else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2
&& !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) {
parser->encoding = YAML_UTF16BE_ENCODING;
parser->raw_buffer.pointer += 2;
parser->offset += 2;
}
else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3
&& !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) {
parser->encoding = YAML_UTF8_ENCODING;
parser->raw_buffer.pointer += 3;
parser->offset += 3;
}
else {
parser->encoding = YAML_UTF8_ENCODING;
}
return 1;
}
/*
* Update the raw buffer.
*/
static int
yaml_parser_update_raw_buffer(yaml_parser_t *parser)
{
size_t size_read = 0;
/* Return if the raw buffer is full. */
if (parser->raw_buffer.start == parser->raw_buffer.pointer
&& parser->raw_buffer.last == parser->raw_buffer.end)
return 1;
/* Return on EOF. */
if (parser->eof) return 1;
/* Move the remaining bytes in the raw buffer to the beginning. */
if (parser->raw_buffer.start < parser->raw_buffer.pointer
&& parser->raw_buffer.pointer < parser->raw_buffer.last) {
memmove(parser->raw_buffer.start, parser->raw_buffer.pointer,
parser->raw_buffer.last - parser->raw_buffer.pointer);
}
parser->raw_buffer.last -=
parser->raw_buffer.pointer - parser->raw_buffer.start;
parser->raw_buffer.pointer = parser->raw_buffer.start;
/* Call the read handler to fill the buffer. */
if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last,
parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) {
return yaml_parser_set_reader_error(parser, "input error",
parser->offset, -1);
}
parser->raw_buffer.last += size_read;
if (!size_read) {
parser->eof = 1;
}
return 1;
}
/*
* Ensure that the buffer contains at least `length` characters.
* Return 1 on success, 0 on failure.
*
* The length is supposed to be significantly less that the buffer size.
*/
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length)
{
int first = 1;
assert(parser->read_handler); /* Read handler must be set. */
/* If the EOF flag is set and the raw buffer is empty, do nothing. */
if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last)
return 1;
/* Return if the buffer contains enough characters. */
if (parser->unread >= length)
return 1;
/* Determine the input encoding if it is not known yet. */
if (!parser->encoding) {
if (!yaml_parser_determine_encoding(parser))
return 0;
}
/* Move the unread characters to the beginning of the buffer. */
if (parser->buffer.start < parser->buffer.pointer
&& parser->buffer.pointer < parser->buffer.last) {
size_t size = parser->buffer.last - parser->buffer.pointer;
memmove(parser->buffer.start, parser->buffer.pointer, size);
parser->buffer.pointer = parser->buffer.start;
parser->buffer.last = parser->buffer.start + size;
}
else if (parser->buffer.pointer == parser->buffer.last) {
parser->buffer.pointer = parser->buffer.start;
parser->buffer.last = parser->buffer.start;
}
/* Fill the buffer until it has enough characters. */
while (parser->unread < length)
{
/* Fill the raw buffer if necessary. */
if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) {
if (!yaml_parser_update_raw_buffer(parser)) return 0;
}
first = 0;
/* Decode the raw buffer. */
while (parser->raw_buffer.pointer != parser->raw_buffer.last)
{
unsigned int value = 0, value2 = 0;
int incomplete = 0;
unsigned char octet;
unsigned int width = 0;
int low, high;
size_t k;
size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer;
/* Decode the next character. */
switch (parser->encoding)
{
case YAML_UTF8_ENCODING:
/*
* Decode a UTF-8 character. Check RFC 3629
* (http://www.ietf.org/rfc/rfc3629.txt) for more details.
*
* The following table (taken from the RFC) is used for
* decoding.
*
* Char. number range | UTF-8 octet sequence
* (hexadecimal) | (binary)
* --------------------+------------------------------------
* 0000 0000-0000 007F | 0xxxxxxx
* 0000 0080-0000 07FF | 110xxxxx 10xxxxxx
* 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
* 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*
* Additionally, the characters in the range 0xD800-0xDFFF
* are prohibited as they are reserved for use with UTF-16
* surrogate pairs.
*/
/* Determine the length of the UTF-8 sequence. */
octet = parser->raw_buffer.pointer[0];
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
(octet & 0xF8) == 0xF0 ? 4 : 0;
/* Check if the leading octet is valid. */
if (!width)
return yaml_parser_set_reader_error(parser,
"invalid leading UTF-8 octet",
parser->offset, octet);
/* Check if the raw buffer contains an incomplete character. */
if (width > raw_unread) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"incomplete UTF-8 octet sequence",
parser->offset, -1);
}
incomplete = 1;
break;
}
/* Decode the leading octet. */
value = (octet & 0x80) == 0x00 ? octet & 0x7F :
(octet & 0xE0) == 0xC0 ? octet & 0x1F :
(octet & 0xF0) == 0xE0 ? octet & 0x0F :
(octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
/* Check and decode the trailing octets. */
for (k = 1; k < width; k ++)
{
octet = parser->raw_buffer.pointer[k];
/* Check if the octet is valid. */
if ((octet & 0xC0) != 0x80)
return yaml_parser_set_reader_error(parser,
"invalid trailing UTF-8 octet",
parser->offset+k, octet);
/* Decode the octet. */
value = (value << 6) + (octet & 0x3F);
}
/* Check the length of the sequence against the value. */
if (!((width == 1) ||
(width == 2 && value >= 0x80) ||
(width == 3 && value >= 0x800) ||
(width == 4 && value >= 0x10000)))
return yaml_parser_set_reader_error(parser,
"invalid length of a UTF-8 sequence",
parser->offset, -1);
/* Check the range of the value. */
if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF)
return yaml_parser_set_reader_error(parser,
"invalid Unicode character",
parser->offset, value);
break;
case YAML_UTF16LE_ENCODING:
case YAML_UTF16BE_ENCODING:
low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
/*
* The UTF-16 encoding is not as simple as one might
* naively think. Check RFC 2781
* (http://www.ietf.org/rfc/rfc2781.txt).
*
* Normally, two subsequent bytes describe a Unicode
* character. However a special technique (called a
* surrogate pair) is used for specifying character
* values larger than 0xFFFF.
*
* A surrogate pair consists of two pseudo-characters:
* high surrogate area (0xD800-0xDBFF)
* low surrogate area (0xDC00-0xDFFF)
*
* The following formulas are used for decoding
* and encoding characters using surrogate pairs:
*
* U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF)
* U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF)
* W1 = 110110yyyyyyyyyy
* W2 = 110111xxxxxxxxxx
*
* where U is the character value, W1 is the high surrogate
* area, W2 is the low surrogate area.
*/
/* Check for incomplete UTF-16 character. */
if (raw_unread < 2) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"incomplete UTF-16 character",
parser->offset, -1);
}
incomplete = 1;
break;
}
/* Get the character. */
value = parser->raw_buffer.pointer[low]
+ (parser->raw_buffer.pointer[high] << 8);
/* Check for unexpected low surrogate area. */
if ((value & 0xFC00) == 0xDC00)
return yaml_parser_set_reader_error(parser,
"unexpected low surrogate area",
parser->offset, value);
/* Check for a high surrogate area. */
if ((value & 0xFC00) == 0xD800) {
width = 4;
/* Check for incomplete surrogate pair. */
if (raw_unread < 4) {
if (parser->eof) {
return yaml_parser_set_reader_error(parser,
"incomplete UTF-16 surrogate pair",
parser->offset, -1);
}
incomplete = 1;
break;
}
/* Get the next character. */
value2 = parser->raw_buffer.pointer[low+2]
+ (parser->raw_buffer.pointer[high+2] << 8);
/* Check for a low surrogate area. */
if ((value2 & 0xFC00) != 0xDC00)
return yaml_parser_set_reader_error(parser,
"expected low surrogate area",
parser->offset+2, value2);
/* Generate the value of the surrogate pair. */
value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF);
}
else {
width = 2;
}
break;
default:
assert(1); /* Impossible. */
}
/* Check if the raw buffer contains enough bytes to form a character. */
if (incomplete) break;
/*
* Check if the character is in the allowed range:
* #x9 | #xA | #xD | [#x20-#x7E] (8 bit)
* | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit)
* | [#x10000-#x10FFFF] (32 bit)
*/
if (! (value == 0x09 || value == 0x0A || value == 0x0D
|| (value >= 0x20 && value <= 0x7E)
|| (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF)
|| (value >= 0xE000 && value <= 0xFFFD)
|| (value >= 0x10000 && value <= 0x10FFFF)))
return yaml_parser_set_reader_error(parser,
"control characters are not allowed",
parser->offset, value);
/* Move the raw pointers. */
parser->raw_buffer.pointer += width;
parser->offset += width;
/* Finally put the character into the buffer. */
/* 0000 0000-0000 007F -> 0xxxxxxx */
if (value <= 0x7F) {
*(parser->buffer.last++) = value;
}
/* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */
else if (value <= 0x7FF) {
*(parser->buffer.last++) = 0xC0 + (value >> 6);
*(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
/* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */
else if (value <= 0xFFFF) {
*(parser->buffer.last++) = 0xE0 + (value >> 12);
*(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
*(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
/* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
else {
*(parser->buffer.last++) = 0xF0 + (value >> 18);
*(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F);
*(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F);
*(parser->buffer.last++) = 0x80 + (value & 0x3F);
}
parser->unread ++;
}
/* On EOF, put NUL into the buffer and return. */
if (parser->eof) {
*(parser->buffer.last++) = '\0';
parser->unread ++;
return 1;
}
}
if (parser->offset >= PTRDIFF_MAX)
return yaml_parser_set_reader_error(parser, "input is too long",
PTRDIFF_MAX, -1);
return 1;
}

3585
extern/yaml/src/scanner.c vendored Normal file

File diff suppressed because it is too large Load Diff

141
extern/yaml/src/writer.c vendored Normal file
View File

@@ -0,0 +1,141 @@
#include "yaml_private.h"
/*
* Declarations.
*/
static int
yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem);
YAML_DECLARE(int)
yaml_emitter_flush(yaml_emitter_t *emitter);
/*
* Set the writer error and return 0.
*/
static int
yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem)
{
emitter->error = YAML_WRITER_ERROR;
emitter->problem = problem;
return 0;
}
/*
* Flush the output buffer.
*/
YAML_DECLARE(int)
yaml_emitter_flush(yaml_emitter_t *emitter)
{
int low, high;
assert(emitter); /* Non-NULL emitter object is expected. */
assert(emitter->write_handler); /* Write handler must be set. */
assert(emitter->encoding); /* Output encoding must be set. */
emitter->buffer.last = emitter->buffer.pointer;
emitter->buffer.pointer = emitter->buffer.start;
/* Check if the buffer is empty. */
if (emitter->buffer.start == emitter->buffer.last) {
return 1;
}
/* If the output encoding is UTF-8, we don't need to recode the buffer. */
if (emitter->encoding == YAML_UTF8_ENCODING)
{
if (emitter->write_handler(emitter->write_handler_data,
emitter->buffer.start,
emitter->buffer.last - emitter->buffer.start)) {
emitter->buffer.last = emitter->buffer.start;
emitter->buffer.pointer = emitter->buffer.start;
return 1;
}
else {
return yaml_emitter_set_writer_error(emitter, "write error");
}
}
/* Recode the buffer into the raw buffer. */
low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1);
high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0);
while (emitter->buffer.pointer != emitter->buffer.last)
{
unsigned char octet;
unsigned int width;
unsigned int value;
size_t k;
/*
* See the "reader.c" code for more details on UTF-8 encoding. Note
* that we assume that the buffer contains a valid UTF-8 sequence.
*/
/* Read the next UTF-8 character. */
octet = emitter->buffer.pointer[0];
width = (octet & 0x80) == 0x00 ? 1 :
(octet & 0xE0) == 0xC0 ? 2 :
(octet & 0xF0) == 0xE0 ? 3 :
(octet & 0xF8) == 0xF0 ? 4 : 0;
value = (octet & 0x80) == 0x00 ? octet & 0x7F :
(octet & 0xE0) == 0xC0 ? octet & 0x1F :
(octet & 0xF0) == 0xE0 ? octet & 0x0F :
(octet & 0xF8) == 0xF0 ? octet & 0x07 : 0;
for (k = 1; k < width; k ++) {
octet = emitter->buffer.pointer[k];
value = (value << 6) + (octet & 0x3F);
}
emitter->buffer.pointer += width;
/* Write the character. */
if (value < 0x10000)
{
emitter->raw_buffer.last[high] = value >> 8;
emitter->raw_buffer.last[low] = value & 0xFF;
emitter->raw_buffer.last += 2;
}
else
{
/* Write the character using a surrogate pair (check "reader.c"). */
value -= 0x10000;
emitter->raw_buffer.last[high] = 0xD8 + (value >> 18);
emitter->raw_buffer.last[low] = (value >> 10) & 0xFF;
emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF);
emitter->raw_buffer.last[low+2] = value & 0xFF;
emitter->raw_buffer.last += 4;
}
}
/* Write the raw buffer. */
if (emitter->write_handler(emitter->write_handler_data,
emitter->raw_buffer.start,
emitter->raw_buffer.last - emitter->raw_buffer.start)) {
emitter->buffer.last = emitter->buffer.start;
emitter->buffer.pointer = emitter->buffer.start;
emitter->raw_buffer.last = emitter->raw_buffer.start;
emitter->raw_buffer.pointer = emitter->raw_buffer.start;
return 1;
}
else {
return yaml_emitter_set_writer_error(emitter, "write error");
}
}

658
extern/yaml/src/yaml_private.h vendored Normal file
View File

@@ -0,0 +1,658 @@
#include "config.h"
#include <yaml.h>
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#ifndef _MSC_VER
#include <stdint.h>
#else
#ifdef _WIN64
#define PTRDIFF_MAX _I64_MAX
#else
#define PTRDIFF_MAX INT_MAX
#endif
#endif
/*
* Memory management.
*/
YAML_DECLARE(void *)
yaml_malloc(size_t size);
YAML_DECLARE(void *)
yaml_realloc(void *ptr, size_t size);
YAML_DECLARE(void)
yaml_free(void *ptr);
YAML_DECLARE(yaml_char_t *)
yaml_strdup(const yaml_char_t *);
/*
* Reader: Ensure that the buffer contains at least `length` characters.
*/
YAML_DECLARE(int)
yaml_parser_update_buffer(yaml_parser_t *parser, size_t length);
/*
* Scanner: Ensure that the token stack contains at least one token ready.
*/
YAML_DECLARE(int)
yaml_parser_fetch_more_tokens(yaml_parser_t *parser);
/*
* The size of the input raw buffer.
*/
#define INPUT_RAW_BUFFER_SIZE 16384
/*
* The size of the input buffer.
*
* It should be possible to decode the whole raw buffer.
*/
#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3)
/*
* The size of the output buffer.
*/
#define OUTPUT_BUFFER_SIZE 16384
/*
* The size of the output raw buffer.
*
* It should be possible to encode the whole output buffer.
*/
#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2)
/*
* The size of other stacks and queues.
*/
#define INITIAL_STACK_SIZE 16
#define INITIAL_QUEUE_SIZE 16
#define INITIAL_STRING_SIZE 16
/*
* Buffer management.
*/
#define BUFFER_INIT(context,buffer,size) \
(((buffer).start = yaml_malloc(size)) ? \
((buffer).last = (buffer).pointer = (buffer).start, \
(buffer).end = (buffer).start+(size), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define BUFFER_DEL(context,buffer) \
(yaml_free((buffer).start), \
(buffer).start = (buffer).pointer = (buffer).end = 0)
/*
* String management.
*/
typedef struct {
yaml_char_t *start;
yaml_char_t *end;
yaml_char_t *pointer;
} yaml_string_t;
YAML_DECLARE(int)
yaml_string_extend(yaml_char_t **start,
yaml_char_t **pointer, yaml_char_t **end);
YAML_DECLARE(int)
yaml_string_join(
yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end,
yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end);
#define NULL_STRING { NULL, NULL, NULL }
#define STRING(string,length) { (string), (string)+(length), (string) }
#define STRING_ASSIGN(value,string,length) \
((value).start = (string), \
(value).end = (string)+(length), \
(value).pointer = (string))
#define STRING_INIT(context,string,size) \
(((string).start = yaml_malloc(size)) ? \
((string).pointer = (string).start, \
(string).end = (string).start+(size), \
memset((string).start, 0, (size)), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define STRING_DEL(context,string) \
(yaml_free((string).start), \
(string).start = (string).pointer = (string).end = 0)
#define STRING_EXTEND(context,string) \
((((string).pointer+5 < (string).end) \
|| yaml_string_extend(&(string).start, \
&(string).pointer, &(string).end)) ? \
1 : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define CLEAR(context,string) \
((string).pointer = (string).start, \
memset((string).start, 0, (string).end-(string).start))
#define JOIN(context,string_a,string_b) \
((yaml_string_join(&(string_a).start, &(string_a).pointer, \
&(string_a).end, &(string_b).start, \
&(string_b).pointer, &(string_b).end)) ? \
((string_b).pointer = (string_b).start, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
/*
* String check operations.
*/
/*
* Check the octet at the specified position.
*/
#define CHECK_AT(string,octet,offset) \
((string).pointer[offset] == (yaml_char_t)(octet))
/*
* Check the current octet in the buffer.
*/
#define CHECK(string,octet) CHECK_AT((string),(octet),0)
/*
* Check if the character at the specified position is an alphabetical
* character, a digit, '_', or '-'.
*/
#define IS_ALPHA_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) '0' && \
(string).pointer[offset] <= (yaml_char_t) '9') || \
((string).pointer[offset] >= (yaml_char_t) 'A' && \
(string).pointer[offset] <= (yaml_char_t) 'Z') || \
((string).pointer[offset] >= (yaml_char_t) 'a' && \
(string).pointer[offset] <= (yaml_char_t) 'z') || \
(string).pointer[offset] == '_' || \
(string).pointer[offset] == '-')
#define IS_ALPHA(string) IS_ALPHA_AT((string),0)
/*
* Check if the character at the specified position is a digit.
*/
#define IS_DIGIT_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) '0' && \
(string).pointer[offset] <= (yaml_char_t) '9'))
#define IS_DIGIT(string) IS_DIGIT_AT((string),0)
/*
* Get the value of a digit.
*/
#define AS_DIGIT_AT(string,offset) \
((string).pointer[offset] - (yaml_char_t) '0')
#define AS_DIGIT(string) AS_DIGIT_AT((string),0)
/*
* Check if the character at the specified position is a hex-digit.
*/
#define IS_HEX_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) '0' && \
(string).pointer[offset] <= (yaml_char_t) '9') || \
((string).pointer[offset] >= (yaml_char_t) 'A' && \
(string).pointer[offset] <= (yaml_char_t) 'F') || \
((string).pointer[offset] >= (yaml_char_t) 'a' && \
(string).pointer[offset] <= (yaml_char_t) 'f'))
#define IS_HEX(string) IS_HEX_AT((string),0)
/*
* Get the value of a hex-digit.
*/
#define AS_HEX_AT(string,offset) \
(((string).pointer[offset] >= (yaml_char_t) 'A' && \
(string).pointer[offset] <= (yaml_char_t) 'F') ? \
((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \
((string).pointer[offset] >= (yaml_char_t) 'a' && \
(string).pointer[offset] <= (yaml_char_t) 'f') ? \
((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \
((string).pointer[offset] - (yaml_char_t) '0'))
#define AS_HEX(string) AS_HEX_AT((string),0)
/*
* Check if the character is ASCII.
*/
#define IS_ASCII_AT(string,offset) \
((string).pointer[offset] <= (yaml_char_t) '\x7F')
#define IS_ASCII(string) IS_ASCII_AT((string),0)
/*
* Check if the character can be printed unescaped.
*/
#define IS_PRINTABLE_AT(string,offset) \
(((string).pointer[offset] == 0x0A) /* . == #x0A */ \
|| ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \
&& (string).pointer[offset] <= 0x7E) \
|| ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \
&& (string).pointer[offset+1] >= 0xA0) \
|| ((string).pointer[offset] > 0xC2 \
&& (string).pointer[offset] < 0xED) \
|| ((string).pointer[offset] == 0xED \
&& (string).pointer[offset+1] < 0xA0) \
|| ((string).pointer[offset] == 0xEE) \
|| ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \
&& !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \
&& (string).pointer[offset+2] == 0xBF) \
&& !((string).pointer[offset+1] == 0xBF \
&& ((string).pointer[offset+2] == 0xBE \
|| (string).pointer[offset+2] == 0xBF))))
#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0)
/*
* Check if the character at the specified position is NUL.
*/
#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset))
#define IS_Z(string) IS_Z_AT((string),0)
/*
* Check if the character at the specified position is BOM.
*/
#define IS_BOM_AT(string,offset) \
(CHECK_AT((string),'\xEF',(offset)) \
&& CHECK_AT((string),'\xBB',(offset)+1) \
&& CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */
#define IS_BOM(string) IS_BOM_AT(string,0)
/*
* Check if the character at the specified position is space.
*/
#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset))
#define IS_SPACE(string) IS_SPACE_AT((string),0)
/*
* Check if the character at the specified position is tab.
*/
#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset))
#define IS_TAB(string) IS_TAB_AT((string),0)
/*
* Check if the character at the specified position is blank (space or tab).
*/
#define IS_BLANK_AT(string,offset) \
(IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset)))
#define IS_BLANK(string) IS_BLANK_AT((string),0)
/*
* Check if the character at the specified position is a line break.
*/
#define IS_BREAK_AT(string,offset) \
(CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \
|| CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \
|| (CHECK_AT((string),'\xC2',(offset)) \
&& CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \
|| (CHECK_AT((string),'\xE2',(offset)) \
&& CHECK_AT((string),'\x80',(offset)+1) \
&& CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \
|| (CHECK_AT((string),'\xE2',(offset)) \
&& CHECK_AT((string),'\x80',(offset)+1) \
&& CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */
#define IS_BREAK(string) IS_BREAK_AT((string),0)
#define IS_CRLF_AT(string,offset) \
(CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1))
#define IS_CRLF(string) IS_CRLF_AT((string),0)
/*
* Check if the character is a line break or NUL.
*/
#define IS_BREAKZ_AT(string,offset) \
(IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset)))
#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0)
/*
* Check if the character is a line break, space, or NUL.
*/
#define IS_SPACEZ_AT(string,offset) \
(IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0)
/*
* Check if the character is a line break, space, tab, or NUL.
*/
#define IS_BLANKZ_AT(string,offset) \
(IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset)))
#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0)
/*
* Determine the width of the character.
*/
#define WIDTH_AT(string,offset) \
(((string).pointer[offset] & 0x80) == 0x00 ? 1 : \
((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \
((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \
((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0)
#define WIDTH(string) WIDTH_AT((string),0)
/*
* Move the string pointer to the next character.
*/
#define MOVE(string) ((string).pointer += WIDTH((string)))
/*
* Copy a character and move the pointers of both strings.
*/
#define COPY(string_a,string_b) \
((*(string_b).pointer & 0x80) == 0x00 ? \
(*((string_a).pointer++) = *((string_b).pointer++)) : \
(*(string_b).pointer & 0xE0) == 0xC0 ? \
(*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++)) : \
(*(string_b).pointer & 0xF0) == 0xE0 ? \
(*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++)) : \
(*(string_b).pointer & 0xF8) == 0xF0 ? \
(*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++), \
*((string_a).pointer++) = *((string_b).pointer++)) : 0)
/*
* Stack and queue management.
*/
YAML_DECLARE(int)
yaml_stack_extend(void **start, void **top, void **end);
YAML_DECLARE(int)
yaml_queue_extend(void **start, void **head, void **tail, void **end);
#define STACK_INIT(context,stack,size) \
(((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \
((stack).top = (stack).start, \
(stack).end = (stack).start+(size), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define STACK_DEL(context,stack) \
(yaml_free((stack).start), \
(stack).start = (stack).top = (stack).end = 0)
#define STACK_EMPTY(context,stack) \
((stack).start == (stack).top)
#define STACK_LIMIT(context,stack,size) \
((stack).top - (stack).start < (size) ? \
1 : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define PUSH(context,stack,value) \
(((stack).top != (stack).end \
|| yaml_stack_extend((void **)&(stack).start, \
(void **)&(stack).top, (void **)&(stack).end)) ? \
(*((stack).top++) = value, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define POP(context,stack) \
(*(--(stack).top))
#define QUEUE_INIT(context,queue,size) \
(((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \
((queue).head = (queue).tail = (queue).start, \
(queue).end = (queue).start+(size), \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define QUEUE_DEL(context,queue) \
(yaml_free((queue).start), \
(queue).start = (queue).head = (queue).tail = (queue).end = 0)
#define QUEUE_EMPTY(context,queue) \
((queue).head == (queue).tail)
#define ENQUEUE(context,queue,value) \
(((queue).tail != (queue).end \
|| yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
(void **)&(queue).tail, (void **)&(queue).end)) ? \
(*((queue).tail++) = value, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
#define DEQUEUE(context,queue) \
(*((queue).head++))
#define QUEUE_INSERT(context,queue,index,value) \
(((queue).tail != (queue).end \
|| yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \
(void **)&(queue).tail, (void **)&(queue).end)) ? \
(memmove((queue).head+(index)+1,(queue).head+(index), \
((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \
*((queue).head+(index)) = value, \
(queue).tail++, \
1) : \
((context)->error = YAML_MEMORY_ERROR, \
0))
/*
* Token initializers.
*/
#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \
(memset(&(token), 0, sizeof(yaml_token_t)), \
(token).type = (token_type), \
(token).start_mark = (token_start_mark), \
(token).end_mark = (token_end_mark))
#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \
(token).data.stream_start.encoding = (token_encoding))
#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark)))
#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \
(token).data.alias.value = (token_value))
#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \
(token).data.anchor.value = (token_value))
#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \
(token).data.tag.handle = (token_handle), \
(token).data.tag.suffix = (token_suffix))
#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \
(token).data.scalar.value = (token_value), \
(token).data.scalar.length = (token_length), \
(token).data.scalar.style = (token_style))
#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
(token).data.version_directive.major = (token_major), \
(token).data.version_directive.minor = (token_minor))
#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \
(TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \
(token).data.tag_directive.handle = (token_handle), \
(token).data.tag_directive.prefix = (token_prefix))
/*
* Event initializers.
*/
#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \
(memset(&(event), 0, sizeof(yaml_event_t)), \
(event).type = (event_type), \
(event).start_mark = (event_start_mark), \
(event).end_mark = (event_end_mark))
#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \
(EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \
(event).data.stream_start.encoding = (event_encoding))
#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \
(EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark)))
#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \
event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \
(EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \
(event).data.document_start.version_directive = (event_version_directive), \
(event).data.document_start.tag_directives.start = (event_tag_directives_start), \
(event).data.document_start.tag_directives.end = (event_tag_directives_end), \
(event).data.document_start.implicit = (event_implicit))
#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \
(EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \
(event).data.document_end.implicit = (event_implicit))
#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \
(EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \
(event).data.alias.anchor = (event_anchor))
#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \
event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \
(EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \
(event).data.scalar.anchor = (event_anchor), \
(event).data.scalar.tag = (event_tag), \
(event).data.scalar.value = (event_value), \
(event).data.scalar.length = (event_length), \
(event).data.scalar.plain_implicit = (event_plain_implicit), \
(event).data.scalar.quoted_implicit = (event_quoted_implicit), \
(event).data.scalar.style = (event_style))
#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \
event_implicit,event_style,start_mark,end_mark) \
(EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \
(event).data.sequence_start.anchor = (event_anchor), \
(event).data.sequence_start.tag = (event_tag), \
(event).data.sequence_start.implicit = (event_implicit), \
(event).data.sequence_start.style = (event_style))
#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \
(EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark)))
#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \
event_implicit,event_style,start_mark,end_mark) \
(EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \
(event).data.mapping_start.anchor = (event_anchor), \
(event).data.mapping_start.tag = (event_tag), \
(event).data.mapping_start.implicit = (event_implicit), \
(event).data.mapping_start.style = (event_style))
#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \
(EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark)))
/*
* Document initializer.
*/
#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \
document_version_directive,document_tag_directives_start, \
document_tag_directives_end,document_start_implicit, \
document_end_implicit,document_start_mark,document_end_mark) \
(memset(&(document), 0, sizeof(yaml_document_t)), \
(document).nodes.start = (document_nodes_start), \
(document).nodes.end = (document_nodes_end), \
(document).nodes.top = (document_nodes_start), \
(document).version_directive = (document_version_directive), \
(document).tag_directives.start = (document_tag_directives_start), \
(document).tag_directives.end = (document_tag_directives_end), \
(document).start_implicit = (document_start_implicit), \
(document).end_implicit = (document_end_implicit), \
(document).start_mark = (document_start_mark), \
(document).end_mark = (document_end_mark))
/*
* Node initializers.
*/
#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \
(memset(&(node), 0, sizeof(yaml_node_t)), \
(node).type = (node_type), \
(node).tag = (node_tag), \
(node).start_mark = (node_start_mark), \
(node).end_mark = (node_end_mark))
#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \
node_style,start_mark,end_mark) \
(NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \
(node).data.scalar.value = (node_value), \
(node).data.scalar.length = (node_length), \
(node).data.scalar.style = (node_style))
#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \
node_style,start_mark,end_mark) \
(NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \
(node).data.sequence.items.start = (node_items_start), \
(node).data.sequence.items.end = (node_items_end), \
(node).data.sequence.items.top = (node_items_start), \
(node).data.sequence.style = (node_style))
#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \
node_style,start_mark,end_mark) \
(NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \
(node).data.mapping.pairs.start = (node_pairs_start), \
(node).data.mapping.pairs.end = (node_pairs_end), \
(node).data.mapping.pairs.top = (node_pairs_start), \
(node).data.mapping.style = (node_style))

View File

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

View File

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

View File

@@ -53,16 +53,16 @@ struct DNA
using Vector = std::vector<T>;
template <size_t sizeVar>
using Buffer = struct Buffer<sizeVar, DNAE>;
using Buffer = struct Athena::io::Buffer<sizeVar, DNAE>;
template <atInt32 sizeVar = -1>
using String = struct String<sizeVar, DNAE>;
using String = struct Athena::io::String<sizeVar, DNAE>;
template <atInt32 sizeVar = -1, Endian VE = DNAE>
using WString = struct WString<sizeVar, VE>;
using WString = struct Athena::io::WString<sizeVar, VE>;
template <atInt32 sizeVar = -1>
using WStringAsString = struct WStringAsString<sizeVar, DNAE>;
using WStringAsString = struct Athena::io::WStringAsString<sizeVar, DNAE>;
template <off_t offset, SeekOrigin direction>
struct Seek {};
@@ -73,8 +73,6 @@ struct DNA
struct Delete {};
};
/* Concrete DNA types */
template <size_t sizeVar, Endian VE>
struct Buffer : public DNA<VE>, public std::unique_ptr<atUint8[]>
{
@@ -95,7 +93,7 @@ struct String : public DNA<VE>, public std::string
{
typename DNA<VE>::Delete expl;
inline void read(IStreamReader& reader)
{*this = reader.readString(sizeVar);}
{this->assign(std::move(reader.readString(sizeVar)));}
inline void write(IStreamWriter& writer) const
{writer.writeString(*this, sizeVar);}
inline std::string& operator=(const std::string& __str)
@@ -111,7 +109,7 @@ struct WString : public DNA<VE>, public std::wstring
inline void read(IStreamReader& reader)
{
reader.setEndian(VE);
*this = reader.readWString(sizeVar);
this->assign(std::move(reader.readWString(sizeVar)));
}
inline void write(IStreamWriter& writer) const
{

1030
include/Athena/DNAYaml.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -14,6 +14,9 @@ class FileReader : public IStreamReader
{
public:
FileReader(const std::string& filename, atInt32 cacheSize = (32 * 1024));
#if _WIN32
FileReader(const std::wstring& filename, atInt32 cacheSize = (32 * 1024));
#endif
virtual ~FileReader();
inline const std::string& filename() const
{return m_filename;}
@@ -31,6 +34,9 @@ public:
void setCacheSize(const atInt32 blockSize);
protected:
std::string m_filename;
#if _WIN32
std::wstring m_wfilename;
#endif
FILE* m_fileHandle;
std::unique_ptr<atUint8[]> m_cacheData;
atInt32 m_blockSize;

View File

@@ -12,6 +12,9 @@ class FileWriter : public IStreamWriter
{
public:
FileWriter(const std::string& filename, bool overwrite = true);
#if _WIN32
FileWriter(const std::wstring& filename, bool overwrite = true);
#endif
virtual ~FileWriter();
void open(bool overwrite = true);
@@ -25,6 +28,9 @@ public:
private:
std::string m_filename;
#if _WIN32
std::wstring m_wfilename;
#endif
FILE* m_fileHandle;
atUint8 m_currentByte;
atUint64 m_bytePosition;

View File

@@ -51,21 +51,6 @@ typedef struct _stat64 stat64_t;
typedef struct stat64 stat64_t;
#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
#define BLOCKSZ 512
#endif
@@ -75,6 +60,16 @@ typedef struct stat64 stat64_t;
namespace Athena
{
namespace error
{
enum Level
{
MESSAGE,
WARNING,
ERROR,
FATAL
};
}
enum SeekOrigin
{
Begin,
@@ -91,7 +86,6 @@ enum Endian
#ifndef ATHENA_NO_SAKURA
namespace Sakura
{
template <typename T>
class Vector2D
{
@@ -118,11 +112,83 @@ typedef Vector2D<float> Vector2Df;
#endif // ATHENA_NO_SAKURA
} // 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 char* file, const char* function, int line, const char* fmt, ...);
atEXCEPTION_HANDLER atGetExceptionHandler();
void atSetExceptionHandler(atEXCEPTION_HANDLER func);
std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin);
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

View File

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

View File

@@ -2,7 +2,6 @@
#define STREAM_HPP
#include "Global.hpp"
#include "Athena/NotImplementedException.hpp"
namespace Athena
{
@@ -13,6 +12,7 @@ std::ostream& operator<<(std::ostream& os, Endian& endian);
class IStream
{
public:
IStream() : m_hasError(false) {}
virtual ~IStream() {}
virtual void setEndian(Endian) = 0;
@@ -23,6 +23,10 @@ public:
virtual bool atEnd() const = 0;
virtual atUint64 position() const = 0;
virtual atUint64 length() const = 0;
bool hasError() const { return m_hasError; }
protected:
void setError() { m_hasError = true; }
bool m_hasError;
};
}
}

View File

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

View File

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

View File

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

View File

@@ -44,37 +44,54 @@ typedef unsigned long long atUint64;
// Vector types
#if __SSE__
#include <xmmintrin.h>
#ifndef _WIN32
#include <mm_malloc.h>
#endif
#endif
typedef union
#include <new>
#define AT_ALIGNED_ALLOCATOR \
void* operator new(size_t bytes) noexcept \
{return _mm_malloc(bytes, 16);} \
void* operator new[](size_t bytes) noexcept \
{return _mm_malloc(bytes, 16);} \
void operator delete(void* buf) noexcept \
{_mm_free(buf);} \
void operator delete[](void* buf) noexcept \
{_mm_free(buf);} \
typedef union alignas(16)
{
#if __clang__
float clangVec __attribute__((__vector_size__(8)));
#endif
#if __SSE__
__m128 mVec128;
AT_ALIGNED_ALLOCATOR
#endif
float vec[2];
} atVec2f;
typedef union
typedef union alignas(16)
{
#if __clang__
float clangVec __attribute__((__vector_size__(12)));
#endif
#if __SSE__
__m128 mVec128;
AT_ALIGNED_ALLOCATOR
#endif
float vec[3];
} atVec3f;
typedef union
typedef union alignas(16)
{
#if __clang__
float clangVec __attribute__((__vector_size__(16)));
#endif
#if __SSE__
__m128 mVec128;
AT_ALIGNED_ALLOCATOR
#endif
float vec[4];
} atVec4f;

View File

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

View File

@@ -247,7 +247,7 @@ ALTTPDungeonItemFlags ALTTPFileReader::readDungeonFlags()
flags.HyruleCastle = (flagsByte >> 6) & 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;
}

View File

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

View File

@@ -1,5 +1,4 @@
#include "Athena/Compression.hpp"
#include "Athena/Exception.hpp"
#include <lzo/lzo1x.h>
#include <iostream>
#include <zlib.h>
@@ -98,7 +97,7 @@ atInt32 decompressLZO(const atUint8* source, const atInt32 sourceSize, atUint8*
int srcSize = sourceSize;
lzo_uint size = dstSize;
int result = lzo1x_decompress_safe(source, srcSize, dst, &size, NULL);
dstSize -= size;
dstSize -= (atInt32)size;
return result;
}

369
src/Athena/DNAYaml.cpp Normal file
View File

@@ -0,0 +1,369 @@
#include "Athena/DNAYaml.hpp"
namespace Athena
{
namespace io
{
static const char* ErrorString(yaml_error_type_t errt)
{
switch (errt)
{
case YAML_NO_ERROR:
return "No Error";
case YAML_MEMORY_ERROR:
return "Memory Error";
case YAML_READER_ERROR:
return "Reader Error";
case YAML_SCANNER_ERROR:
return "Scanner Error";
case YAML_PARSER_ERROR:
return "Parser Error";
case YAML_COMPOSER_ERROR:
return "Composer Error";
case YAML_WRITER_ERROR:
return "Writer Error";
case YAML_EMITTER_ERROR:
return "Emitter Error";
}
return "Unknown Error";
}
void HandleYAMLParserError(yaml_parser_t* parser)
{
atError("YAML error: %s: %s", ErrorString(parser->error), parser->problem?parser->problem:"");
}
void HandleYAMLEmitterError(yaml_emitter_t* emitter)
{
atError("YAML error: %s: %s", ErrorString(emitter->error), emitter->problem?emitter->problem:"");
}
int YAMLStdStringReader(YAMLStdStringReaderState* reader,
unsigned char* buffer, size_t size, size_t* size_read)
{
size_t diff = reader->end - reader->begin;
if (!diff)
{
*size_read = 0;
}
else if (diff < size)
{
memcpy(buffer, &*reader->begin, diff);
*size_read = diff;
}
else
{
memcpy(buffer, &*reader->begin, size);
*size_read = size;
}
return 1;
}
int YAMLStdStringWriter(std::string* str, unsigned char *buffer, size_t size)
{
str->append((char*)buffer, size);
return 1;
}
static inline void InsertNode(std::vector<YAMLNode*>& nodeStack,
std::unique_ptr<YAMLNode>& mapKey,
std::unique_ptr<YAMLNode>& retVal,
std::unique_ptr<YAMLNode>&& newNode)
{
if (nodeStack.empty())
{
retVal = std::move(newNode);
return;
}
YAMLNode* parent = nodeStack.back();
if (parent->m_type == YAML_SEQUENCE_NODE)
{
parent->m_seqChildren.emplace_back(std::move(newNode));
}
else if (parent->m_type == YAML_MAPPING_NODE)
{
if (!mapKey)
mapKey = std::move(newNode);
else
{
parent->m_mapChildren.emplace_back(std::move(mapKey->m_scalarString), std::move(newNode));
mapKey.reset(nullptr);
}
}
}
std::unique_ptr<YAMLNode> YAMLDocReader::ParseEvents(yaml_parser_t* doc)
{
yaml_event_t event;
if (!yaml_parser_parse(doc, &event))
{
HandleYAMLParserError(doc);
return std::unique_ptr<YAMLNode>();
}
std::vector<YAMLNode*> nodeStack;
std::unique_ptr<YAMLNode> mapKey;
std::unique_ptr<YAMLNode> retVal;
int result;
for (result = yaml_parser_parse(doc, &event);
event.type != YAML_STREAM_END_EVENT;
result = yaml_parser_parse(doc, &event))
{
if (!result)
{
HandleYAMLParserError(doc);
return std::unique_ptr<YAMLNode>();
}
switch (event.type)
{
case YAML_SCALAR_EVENT:
{
if (nodeStack.empty())
{
atWarning("YAML parser stack empty; skipping scalar node");
yaml_event_delete(&event);
continue;
}
std::unique_ptr<YAMLNode> newScalar(new YAMLNode(YAML_SCALAR_NODE));
newScalar->m_scalarString.assign((char*)event.data.scalar.value, event.data.scalar.length);
if (nodeStack.empty())
retVal = std::move(newScalar);
else
InsertNode(nodeStack, mapKey, retVal, std::move(newScalar));
break;
}
case YAML_SEQUENCE_START_EVENT:
{
YAMLNode* newSeq = new YAMLNode(YAML_SEQUENCE_NODE);
InsertNode(nodeStack, mapKey, retVal, std::unique_ptr<YAMLNode>(newSeq));
nodeStack.emplace_back(newSeq);
break;
}
case YAML_SEQUENCE_END_EVENT:
{
nodeStack.pop_back();
break;
}
case YAML_MAPPING_START_EVENT:
{
YAMLNode* newMap = new YAMLNode(YAML_MAPPING_NODE);
InsertNode(nodeStack, mapKey, retVal, std::unique_ptr<YAMLNode>(newMap));
nodeStack.emplace_back(newMap);
break;
}
case YAML_MAPPING_END_EVENT:
{
nodeStack.pop_back();
break;
}
case YAML_DOCUMENT_END_EVENT:
{
yaml_event_delete(&event);
return retVal;
}
default:
break;
}
yaml_event_delete(&event);
}
return std::unique_ptr<YAMLNode>();
}
static inline bool EmitKeyScalar(yaml_emitter_t* doc, const char* val)
{
yaml_event_t event;
if (!yaml_scalar_event_initialize(&event, nullptr, nullptr, (yaml_char_t*)val,
strlen(val), true, true, YAML_PLAIN_SCALAR_STYLE))
return false;
return yaml_emitter_emit(doc, &event);
}
static inline yaml_scalar_style_t ScalarStyle(const YAMLNode& node)
{
for (const auto& ch : node.m_scalarString)
if (ch == '\n')
return YAML_LITERAL_SCALAR_STYLE;
return YAML_ANY_SCALAR_STYLE;
}
static inline yaml_sequence_style_t SequenceStyle(const YAMLNode& node)
{
size_t count = 0;
for (const auto& item : node.m_seqChildren)
{
if (item->m_type != YAML_SCALAR_NODE)
return YAML_BLOCK_SEQUENCE_STYLE;
size_t strLen = item->m_scalarString.size();
size_t thisCount = strLen / 10;
if (!thisCount)
thisCount = 1;
count += thisCount;
}
return (count > 6) ? YAML_BLOCK_SEQUENCE_STYLE : YAML_FLOW_SEQUENCE_STYLE;
}
static inline yaml_mapping_style_t MappingStyle(const YAMLNode& node)
{
size_t count = 0;
for (const auto& item : node.m_mapChildren)
{
if (item.second->m_type != YAML_SCALAR_NODE)
return YAML_BLOCK_MAPPING_STYLE;
size_t strLen = item.second->m_scalarString.size();
size_t thisCount = strLen / 10;
if (!thisCount)
thisCount = 1;
count += thisCount;
}
return (count > 6) ? YAML_BLOCK_MAPPING_STYLE : YAML_FLOW_MAPPING_STYLE;
}
bool YAMLDocWriter::RecursiveFinish(yaml_emitter_t* doc, const YAMLNode& node)
{
yaml_event_t event;
if (node.m_type == YAML_SCALAR_NODE)
{
if (!yaml_scalar_event_initialize(&event, nullptr, nullptr, (yaml_char_t*)node.m_scalarString.c_str(),
node.m_scalarString.length(), true, true, ScalarStyle(node)) ||
!yaml_emitter_emit(doc, &event))
goto err;
}
else if (node.m_type == YAML_SEQUENCE_NODE)
{
if (!yaml_sequence_start_event_initialize(&event, nullptr, nullptr, 1, SequenceStyle(node)) ||
!yaml_emitter_emit(doc, &event))
goto err;
for (const auto& item : node.m_seqChildren)
{
if (!RecursiveFinish(doc, *item.get()))
goto err;
}
if (!yaml_sequence_end_event_initialize(&event) ||
!yaml_emitter_emit(doc, &event))
goto err;
}
else if (node.m_type == YAML_MAPPING_NODE)
{
if (!yaml_mapping_start_event_initialize(&event, nullptr, nullptr, true, MappingStyle(node)) ||
!yaml_emitter_emit(doc, &event))
goto err;
for (const auto& item : node.m_mapChildren)
{
if (!EmitKeyScalar(doc, item.first.c_str()))
goto err;
if (!RecursiveFinish(doc, *item.second.get()))
goto err;
}
event.type = YAML_MAPPING_END_EVENT;
if (!yaml_mapping_end_event_initialize(&event) ||
!yaml_emitter_emit(doc, &event))
goto err;
}
return true;
err:
HandleYAMLEmitterError(doc);
return false;
}
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c)
{
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(const atUint8* bytes_to_encode, size_t in_len)
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
ret.reserve(in_len * 4 / 3);
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++)
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::unique_ptr<atUint8[]> base64_decode(const std::string& encoded_string)
{
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::unique_ptr<atUint8[]> ret(new atUint8[in_len * 3 / 4]);
atUint8* retBuf = ret.get();
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
*retBuf++ = char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) *retBuf++ = char_array_3[j];
}
return ret;
}
}
}

View File

@@ -1,8 +1,4 @@
#include "Athena/FileReader.hpp"
#include "Athena/FileNotFoundException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/IOException.hpp"
#if _WIN32
#include "win32_largefilewrapper.h"
@@ -24,6 +20,18 @@ FileReader::FileReader(const std::string& filename, atInt32 cacheSize)
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()
{
if (isOpen())
@@ -32,10 +40,21 @@ FileReader::~FileReader()
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");
#endif
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
rewind(m_fileHandle);
@@ -44,7 +63,11 @@ void FileReader::open()
void FileReader::close()
{
if (!m_fileHandle)
THROW_INVALID_OPERATION_EXCEPTION("Cannot close an unopened stream");
{
atError("Cannot close an unopened stream");
setError();
return;
}
fclose(m_fileHandle);
m_fileHandle = NULL;
@@ -72,7 +95,8 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
if (m_offset > length())
{
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;
@@ -80,17 +104,20 @@ void FileReader::seek(atInt64 pos, SeekOrigin origin)
{
fseeko64(m_fileHandle, block * m_blockSize, SEEK_SET);
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)
THROW_INVALID_OPERATION_EXCEPTION("Unable to seek in file");
atError("Unable to seek in file");
}
atUint64 FileReader::position() const
{
if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "File not open");
{
atError("File not open");
return 0;
}
if (m_blockSize > 0)
return m_offset;
@@ -101,7 +128,10 @@ atUint64 FileReader::position() const
atUint64 FileReader::length() const
{
if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION_RETURN(0, "File not open");
{
atError("File not open");
return 0;
}
return utility::fileSize(m_filename);
}
@@ -109,7 +139,11 @@ atUint64 FileReader::length() const
atUint64 FileReader::readUBytesToBuf(void* buf, atUint64 len)
{
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)
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);
fread(m_cacheData.get(), 1, m_blockSize, m_fileHandle);
m_curBlock = block;
m_curBlock = (atInt32)block;
}
cacheSize = rem;
@@ -150,7 +184,7 @@ void FileReader::setCacheSize(const atInt32 blockSize)
m_blockSize = blockSize;
if (m_blockSize > length())
m_blockSize = length();
m_blockSize = (atInt32)length();
m_curBlock = -1;
if (m_blockSize > 0)

View File

@@ -1,8 +1,4 @@
#include "Athena/FileWriter.hpp"
#include "Athena/FileNotFoundException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/IOException.hpp"
#if _WIN32
#include "win32_largefilewrapper.h"
@@ -22,6 +18,16 @@ FileWriter::FileWriter(const std::string& filename, bool 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()
{
if (isOpen())
@@ -30,13 +36,36 @@ FileWriter::~FileWriter()
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)
m_fileHandle = fopen(m_filename.c_str(), "w+b");
else
m_fileHandle = fopen(m_filename.c_str(), "r+b");
m_fileHandle = fopen(m_filename.c_str(), "r+b");
#endif
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
rewind(m_fileHandle);
@@ -45,7 +74,11 @@ void FileWriter::open(bool overwrite)
void FileWriter::close()
{
if (!m_fileHandle)
THROW_INVALID_OPERATION_EXCEPTION("Cannot close an unopened stream");
{
atError("Cannot close an unopened stream");
setError();
return;
}
fclose(m_fileHandle);
m_fileHandle = NULL;
@@ -55,7 +88,10 @@ void FileWriter::close()
void FileWriter::seek(atInt64 pos, SeekOrigin origin)
{
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
@@ -71,10 +107,17 @@ atUint64 FileWriter::length() const
void FileWriter::writeUBytes(const atUint8* data, atUint64 len)
{
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)
THROW_IO_EXCEPTION("Unable to write to stream");
{
atError("Unable to write to stream");
setError();
}
}
}

View File

@@ -1,4 +1,7 @@
#include "Athena/Global.hpp"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
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 char* file, const char* 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()
{
@@ -48,5 +75,8 @@ atEXCEPTION_HANDLER atGetExceptionHandler()
void atSetExceptionHandler(atEXCEPTION_HANDLER func)
{
g_atExceptionHandler = func;
if (func)
g_atExceptionHandler = func;
else
g_atExceptionHandler = __defaultExceptionHandler;
}

View File

@@ -1,8 +1,4 @@
#include "Athena/MemoryReader.hpp"
#include "Athena/IOException.hpp"
#include "Athena/FileNotFoundException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include <stdio.h>
#include <stdlib.h>
@@ -24,20 +20,36 @@ MemoryReader::MemoryReader(const atUint8* data, atUint64 length)
m_position(0)
{
if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL");
{
atError("data cannot be NULL");
setError();
return;
}
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)
: MemoryReader(data, length)
{
if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL");
{
atError("data cannot be NULL");
setError();
return;
}
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_data = m_dataCopy.get();
@@ -50,21 +62,33 @@ void MemoryReader::seek(atInt64 position, SeekOrigin origin)
{
case SeekOrigin::Begin:
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;
break;
case SeekOrigin::Current:
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;
break;
case SeekOrigin::End:
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;
break;
@@ -98,7 +122,11 @@ atUint8* MemoryReader::data() const
atUint64 MemoryReader::readUBytesToBuf(void* buf, atUint64 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);
m_position += length;
@@ -112,7 +140,11 @@ void MemoryCopyReader::loadData()
in = fopen(m_filepath.c_str(), "rb");
if (!in)
THROW_FILE_NOT_FOUND_EXCEPTION(m_filepath);
{
atError("Unable to open file '%s'", m_filepath.c_str());
setError();
return;
}
rewind(in);
@@ -131,7 +163,11 @@ void MemoryCopyReader::loadData()
atInt64 ret = fread(m_dataCopy.get() + done, 1, blocksize, in);
if (ret < 0)
THROW_IO_EXCEPTION("Error reading data from disk");
{
atError("Error reading data from disk");
setError();
return;
}
else if (ret == 0)
break;

View File

@@ -1,8 +1,4 @@
#include "Athena/MemoryWriter.hpp"
#include "Athena/IOException.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/FileNotFoundException.hpp"
#include <stdio.h>
#include <string.h>
@@ -24,10 +20,18 @@ MemoryWriter::MemoryWriter(atUint8* data, atUint64 length)
m_position(0)
{
if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannot be NULL");
{
atError("data cannot be NULL");
setError();
return;
}
if (length == 0)
THROW_INVALID_OPERATION_EXCEPTION("length cannot be 0");
{
atError("length cannot be 0");
setError();
return;
}
}
MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
@@ -37,7 +41,11 @@ MemoryCopyWriter::MemoryCopyWriter(atUint8* data, atUint64 length)
m_position = 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_data = m_dataCopy.get();
@@ -55,7 +63,11 @@ MemoryCopyWriter::MemoryCopyWriter(const std::string& filename)
m_data = m_dataCopy.get();
if (!m_data)
THROW_IO_EXCEPTION("Could not allocate memory!");
{
atError("Could not allocate memory!");
setError();
return;
}
memset(m_data, 0, m_length);
}
@@ -66,30 +78,54 @@ void MemoryWriter::seek(atInt64 position, SeekOrigin origin)
{
case SeekOrigin::Begin:
if (position < 0)
THROW_IO_EXCEPTION("Position outside stream bounds");
{
atError("Position outside stream bounds");
setError();
return;
}
if ((atUint64)position > m_length)
THROW_IO_EXCEPTION("data exceeds available buffer space");
{
atError("data exceeds available buffer space");
setError();
return;
}
m_position = position;
break;
case SeekOrigin::Current:
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)
THROW_IO_EXCEPTION("data exceeds available buffer space");
{
atError("data exceeds available buffer space");
setError();
return;
}
m_position += position;
break;
case SeekOrigin::End:
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)
THROW_IO_EXCEPTION("data exceeds available buffer space");
{
atError("data exceeds available buffer space");
setError();
return;
}
m_position = m_length - position;
break;
@@ -102,7 +138,11 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
{
case SeekOrigin::Begin:
if (position < 0)
THROW_IO_EXCEPTION("Position outside stream bounds");
{
atError("Position outside stream bounds");
setError();
return;
}
if ((atUint64)position > m_length)
resize(position);
@@ -112,7 +152,11 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
case SeekOrigin::Current:
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)
resize(m_position + position);
@@ -122,7 +166,11 @@ void MemoryCopyWriter::seek(atInt64 position, SeekOrigin origin)
case SeekOrigin::End:
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)
resize(position);
@@ -160,7 +208,11 @@ atUint8* MemoryWriter::data() const
void MemoryWriter::save(const std::string& filename)
{
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())
m_filepath = filename;
@@ -168,7 +220,11 @@ void MemoryWriter::save(const std::string& filename)
FILE* out = fopen(m_filepath.c_str(), "wb");
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 blocksize = BLOCKSZ;
@@ -181,7 +237,11 @@ void MemoryWriter::save(const std::string& filename)
atInt64 ret = fwrite(m_data + done, 1, blocksize, out);
if (ret < 0)
THROW_IO_EXCEPTION("Error writing data to disk");
{
atError("Error writing data to disk");
setError();
return;
}
else if (ret == 0)
break;
@@ -195,10 +255,18 @@ void MemoryWriter::save(const std::string& filename)
void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
{
if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannnot be NULL");
{
atError("data cannnot be NULL");
setError();
return;
}
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);
@@ -208,7 +276,11 @@ void MemoryWriter::writeUBytes(const atUint8* data, atUint64 length)
void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
{
if (!data)
THROW_INVALID_DATA_EXCEPTION("data cannnot be NULL");
{
atError("data cannnot be NULL");
setError();
return;
}
if (m_position + length > m_length)
resize(m_position + length);
@@ -221,7 +293,10 @@ void MemoryCopyWriter::writeUBytes(const atUint8* data, atUint64 length)
void MemoryCopyWriter::resize(atUint64 newSize)
{
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
atUint8* newArray = new atUint8[newSize];

View File

@@ -16,7 +16,6 @@
#include "Athena/SkywardSwordFile.hpp"
#include "Athena/SkywardSwordQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
namespace Athena
{
@@ -48,7 +47,10 @@ void SkywardSwordFile::addQuest(Athena::SkywardSwordQuest* q)
SkywardSwordQuest* SkywardSwordFile::quest(atUint32 id)
{
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];
}

View File

@@ -17,8 +17,6 @@
#include "Athena/SkywardSwordFileReader.hpp"
#include "Athena/SkywardSwordFile.hpp"
#include "Athena/SkywardSwordQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include <iostream>
namespace Athena
@@ -45,18 +43,27 @@ SkywardSwordFile* SkywardSwordFileReader::read()
try
{
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();
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);
atUint32 headerSize = base::readUint32(); // Seems to be (headerSize - 1)
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
file = new SkywardSwordFile;

View File

@@ -17,8 +17,6 @@
#include "Athena/SkywardSwordFileWriter.hpp"
#include "Athena/SkywardSwordFile.hpp"
#include "Athena/SkywardSwordQuest.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
namespace Athena
{
@@ -40,7 +38,10 @@ SkywardSwordFileWriter::SkywardSwordFileWriter(const std::string& filename)
void SkywardSwordFileWriter::write(SkywardSwordFile* 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 :
(file->region() == Region::NTSCJ ? SkywardSwordFile::JAMagic : SkywardSwordFile::EUMagic));
@@ -55,7 +56,10 @@ void SkywardSwordFileWriter::write(SkywardSwordFile* file)
for (SkywardSwordQuest* q : quests)
{
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
q->fixChecksums();

View File

@@ -79,7 +79,7 @@ atUint8* SkywardSwordQuest::skipData() const
void SkywardSwordQuest::setPlayerName(const std::string& name)
{
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 val = conv.from_bytes(name);

View File

@@ -19,9 +19,6 @@
#include "Athena/Sprite.hpp"
#include "Athena/SpritePart.hpp"
#include "Athena/SpriteFrame.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "Athena/IOException.hpp"
#include "Athena/Utility.hpp"
namespace Athena
@@ -48,13 +45,19 @@ Sakura::SpriteFile* SpriteFileReader::readFile()
atUint32 magic = base::readUint32();
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();
// TODO: Make this more verbose
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
// metadata about the file.
@@ -209,7 +212,10 @@ Sakura::SpriteFile* SpriteFileReader::readFile()
#endif
else
THROW_IO_EXCEPTION_RETURN(nullptr, "Sprite names cannot be empty");
{
atError("Sprite names cannot be empty");
return nullptr;
}
}
ret->setSprites(sprites);

View File

@@ -19,8 +19,6 @@
#include "Athena/Sprite.hpp"
#include "Athena/SpritePart.hpp"
#include "Athena/SpriteFrame.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
namespace Athena
{
@@ -39,7 +37,10 @@ SpriteFileWriter::SpriteFileWriter(const std::string& filepath)
void SpriteFileWriter::writeFile(Sakura::SpriteFile* 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::Version);

View File

@@ -9,7 +9,6 @@
#include <cstdio>
#include <sys/types.h>
#include <sys/stat.h>
#include <Athena/Exception.hpp>
#include <random>
#ifdef _MSC_VER
@@ -25,8 +24,22 @@ namespace utility
void fillRandom(atUint8* rndArea, atUint64 count)
{
for (atUint64 i = 0; i < count; i++)
rndArea[i] = rand();
atUint8* buf = rndArea;
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)

View File

@@ -15,7 +15,6 @@
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
#include "Athena/WiiFile.hpp"
#include "Athena/InvalidOperationException.hpp"
#include <algorithm>
namespace Athena
@@ -144,7 +143,10 @@ bool WiiFile::isFile() const
void WiiFile::addChild(WiiFile* file)
{
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())
return;

View File

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

View File

@@ -24,8 +24,6 @@
#include "Athena/WiiBanner.hpp"
#include "Athena/MemoryWriter.hpp"
#include "Athena/Utility.hpp"
#include "Athena/InvalidOperationException.hpp"
#include "Athena/InvalidDataException.hpp"
#include "aes.hpp"
#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)
{
if (!save)
THROW_INVALID_OPERATION_EXCEPTION_RETURN(false, "save cannot be NULL");
{
atError("save cannot be NULL");
return false;
}
if (filepath != "")
m_filepath = filepath;

View File

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

View File

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

View File

@@ -39,14 +39,7 @@ static inline void unpack(uint32_t a, uint8_t* b)
static inline uint8_t xtime(uint8_t a)
{
uint8_t b;
if (a & 0x80) b = 0x1B;
else b = 0;
a <<= 1;
a ^= b;
return a;
return ((a << 1) ^ (((a>>7) & 1) * 0x11B));
}
static const struct SoftwareAESTables