mirror of https://github.com/libAthena/athena.git
lots of new 'atdna' types; travis update
This commit is contained in:
parent
1aa3a705af
commit
7cdfcab55a
16
.travis.yml
16
.travis.yml
|
@ -1,17 +1,17 @@
|
||||||
compiler:
|
compiler:
|
||||||
- gcc-4.8
|
- clang
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
|
- sudo add-apt-repository --yes "deb http://llvm.org/apt/precise/ llvm-toolchain-precise-3.6 main"
|
||||||
|
- wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -;
|
||||||
- sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa
|
- sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa
|
||||||
- sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
|
- sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq g++-4.8
|
- sudo apt-get install -qq qt5-default clang-3.6 libclang-3.6-dev
|
||||||
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.8
|
|
||||||
- sudo update-alternatives --config gcc
|
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- qmake Athena.pro
|
- qmake QMAKE_CXX=clang++-3.6 QMAKE_CC=clang-3.6 Athena.pro
|
||||||
|
- make
|
||||||
|
- cd atdna
|
||||||
|
- qmake QMAKE_CXX=clang++-3.6 QMAKE_CC=clang-3.6 QMAKE_LINK=clang++-3.6 LLVM_CONFIG=llvm-config-3.6 atdna.pro
|
||||||
- make
|
- make
|
||||||
|
|
||||||
notifications:
|
|
||||||
irc: "irc.wiiking2.com#wiiking2"
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# PKGBUILD for atdna
|
# PKGBUILD for atdna
|
||||||
_pkgname=atdna
|
_pkgname=atdna
|
||||||
pkgname=$_pkgname-git
|
pkgname=$_pkgname-git
|
||||||
pkgver=1.1.0.31.gd6a4897
|
pkgver=1.1.0.32.g1aa3a70
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Companion DNA utility for libAthena"
|
pkgdesc="Companion DNA utility for libAthena"
|
||||||
arch=('i686' 'x86_64')
|
arch=('i686' 'x86_64')
|
||||||
|
|
|
@ -7,7 +7,13 @@ DEFINES += __STDC_LIMIT_MACROS=1 __STDC_CONSTANT_MACROS=1
|
||||||
QMAKE_CXXFLAGS += -fno-rtti
|
QMAKE_CXXFLAGS += -fno-rtti
|
||||||
QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter
|
QMAKE_CXXFLAGS_WARN_ON = -Wno-unused-parameter
|
||||||
|
|
||||||
|
isEmpty(LLVM_CONFIG) {
|
||||||
|
LLVM_CONFIG = llvm-config
|
||||||
|
}
|
||||||
|
|
||||||
INCLUDEPATH += ../include
|
INCLUDEPATH += ../include
|
||||||
|
INCLUDEPATH += $$system($$LLVM_CONFIG --includedir)
|
||||||
|
LIBS += -L$$system($$LLVM_CONFIG --libdir)
|
||||||
|
|
||||||
CONFIG(debug, debug|release) {
|
CONFIG(debug, debug|release) {
|
||||||
# FOR FULL DEBUGGING, PLEASE UNCOMMENT THESE AND POINT THEM TO
|
# FOR FULL DEBUGGING, PLEASE UNCOMMENT THESE AND POINT THEM TO
|
||||||
|
|
785
atdna/main.cpp
785
atdna/main.cpp
|
@ -1,3 +1,4 @@
|
||||||
|
#include <stdio.h>
|
||||||
#include "clang/AST/ASTConsumer.h"
|
#include "clang/AST/ASTConsumer.h"
|
||||||
#include "clang/AST/RecursiveASTVisitor.h"
|
#include "clang/AST/RecursiveASTVisitor.h"
|
||||||
#include "clang/Frontend/CompilerInstance.h"
|
#include "clang/Frontend/CompilerInstance.h"
|
||||||
|
@ -35,6 +36,9 @@ static llvm::cl::list<std::string> IncludeSearchPaths("I",
|
||||||
llvm::cl::desc("Header search path"),
|
llvm::cl::desc("Header search path"),
|
||||||
llvm::cl::Prefix);
|
llvm::cl::Prefix);
|
||||||
|
|
||||||
|
static unsigned AthenaError = 0;
|
||||||
|
#define ATHENA_DNA_BASETYPE "struct Athena::io::DNA"
|
||||||
|
|
||||||
class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
{
|
{
|
||||||
clang::ASTContext& context;
|
clang::ASTContext& context;
|
||||||
|
@ -106,7 +110,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const clang::CXXBaseSpecifier& base : rDecl->bases())
|
for (const clang::CXXBaseSpecifier& base : rDecl->bases())
|
||||||
if (!base.getType().getCanonicalType().getAsString().compare(0, 22, "struct Athena::io::DNA"))
|
if (!base.getType().getCanonicalType().getAsString().compare(0, sizeof(ATHENA_DNA_BASETYPE)-1, ATHENA_DNA_BASETYPE))
|
||||||
{
|
{
|
||||||
isDNAType = true;
|
isDNAType = true;
|
||||||
return "write(writer);";
|
return "write(writer);";
|
||||||
|
@ -174,7 +178,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const clang::CXXBaseSpecifier& base : rDecl->bases())
|
for (const clang::CXXBaseSpecifier& base : rDecl->bases())
|
||||||
if (!base.getType().getCanonicalType().getAsString().compare(0, 22, "struct Athena::io::DNA"))
|
if (!base.getType().getCanonicalType().getAsString().compare(0, sizeof(ATHENA_DNA_BASETYPE)-1, ATHENA_DNA_BASETYPE))
|
||||||
{
|
{
|
||||||
isDNAType = true;
|
isDNAType = true;
|
||||||
return "read(reader);";
|
return "read(reader);";
|
||||||
|
@ -202,7 +206,7 @@ public:
|
||||||
for (const clang::CXXBaseSpecifier& base : decl->bases())
|
for (const clang::CXXBaseSpecifier& base : decl->bases())
|
||||||
{
|
{
|
||||||
clang::QualType canonType = base.getType().getCanonicalType();
|
clang::QualType canonType = base.getType().getCanonicalType();
|
||||||
if (!canonType.getAsString().compare(0, 22, "struct Athena::io::DNA"))
|
if (!canonType.getAsString().compare(0, sizeof(ATHENA_DNA_BASETYPE)-1, ATHENA_DNA_BASETYPE))
|
||||||
{
|
{
|
||||||
foundDNA = true;
|
foundDNA = true;
|
||||||
break;
|
break;
|
||||||
|
@ -211,12 +215,13 @@ public:
|
||||||
if (!foundDNA)
|
if (!foundDNA)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
/* Two passes - read then write */
|
||||||
for (int p=0 ; p<2 ; ++p)
|
for (int p=0 ; p<2 ; ++p)
|
||||||
{
|
{
|
||||||
if (p)
|
if (p)
|
||||||
fileOut << "void " << decl->getQualifiedNameAsString() << "::write(Athena::IStreamWriter& writer) const\n{\n";
|
fileOut << "void " << decl->getQualifiedNameAsString() << "::write(Athena::io::IStreamWriter& writer) const\n{\n";
|
||||||
else
|
else
|
||||||
fileOut << "void " << decl->getQualifiedNameAsString() << "::read(Athena::IStreamReader& reader)\n{\n";
|
fileOut << "void " << decl->getQualifiedNameAsString() << "::read(Athena::io::IStreamReader& reader)\n{\n";
|
||||||
int currentEndian = -1;
|
int currentEndian = -1;
|
||||||
|
|
||||||
for (const clang::FieldDecl* field : decl->fields())
|
for (const clang::FieldDecl* field : decl->fields())
|
||||||
|
@ -227,205 +232,644 @@ public:
|
||||||
if (regType->getTypeClass() == clang::Type::Elaborated)
|
if (regType->getTypeClass() == clang::Type::Elaborated)
|
||||||
regType = regType->getUnqualifiedDesugaredType();
|
regType = regType->getUnqualifiedDesugaredType();
|
||||||
|
|
||||||
if (regType->getTypeClass() == clang::Type::TemplateSpecialization)
|
/* Resolve constant array */
|
||||||
|
size_t arraySize = 1;
|
||||||
|
bool isArray = false;
|
||||||
|
if (regType->getTypeClass() == clang::Type::ConstantArray)
|
||||||
{
|
{
|
||||||
const clang::TemplateSpecializationType* tsType = (const clang::TemplateSpecializationType*)regType;
|
isArray = true;
|
||||||
const clang::TemplateDecl* tsDecl = tsType->getTemplateName().getAsTemplateDecl();
|
const clang::ConstantArrayType* caType = (clang::ConstantArrayType*)regType;
|
||||||
const clang::TemplateParameterList* classParms = tsDecl->getTemplateParameters();
|
arraySize = caType->getSize().getZExtValue();
|
||||||
|
qualType = caType->getElementType();
|
||||||
|
regTypeInfo = context.getTypeInfo(qualType);
|
||||||
|
regType = qualType.getTypePtrOrNull();
|
||||||
|
if (regType->getTypeClass() == clang::Type::Elaborated)
|
||||||
|
regType = regType->getUnqualifiedDesugaredType();
|
||||||
|
}
|
||||||
|
|
||||||
if (!tsDecl->getNameAsString().compare("Value"))
|
for (int e=0 ; e<arraySize ; ++e)
|
||||||
|
{
|
||||||
|
std::string fieldName;
|
||||||
|
if (isArray)
|
||||||
{
|
{
|
||||||
int endian = -1;
|
char subscript[16];
|
||||||
if (classParms->size() >= 2)
|
snprintf(subscript, 16, "[%d]", e);
|
||||||
{
|
fieldName = field->getNameAsString() + subscript;
|
||||||
const clang::NamedDecl* endianParm = classParms->getParam(1);
|
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
|
||||||
{
|
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
|
||||||
llvm::APSInt result;
|
|
||||||
if (defArg->isIntegerConstantExpr(result, context))
|
|
||||||
endian = result.getSExtValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clang::QualType templateType;
|
|
||||||
std::string ioOp;
|
|
||||||
bool isDNAType = false;
|
|
||||||
const clang::TemplateArgument* typeArg = nullptr;
|
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
|
||||||
{
|
|
||||||
if (arg.getKind() == clang::TemplateArgument::Type)
|
|
||||||
{
|
|
||||||
typeArg = &arg;
|
|
||||||
templateType = arg.getAsType().getCanonicalType();
|
|
||||||
const clang::Type* type = arg.getAsType().getCanonicalType().getTypePtr();
|
|
||||||
std::string fieldName = field->getName().str();
|
|
||||||
ioOp = GetOpString(type, regTypeInfo.Width, fieldName, p, isDNAType);
|
|
||||||
}
|
|
||||||
else if (arg.getKind() == clang::TemplateArgument::Expression)
|
|
||||||
{
|
|
||||||
llvm::APSInt value;
|
|
||||||
if (arg.getAsExpr()->isIntegerConstantExpr(value, context))
|
|
||||||
endian = value.getSExtValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioOp.empty())
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), context.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Fatal, "Athena error: %0"));
|
|
||||||
diag.AddString("Unable to use type '" + tsDecl->getNameAsString() + "' with Athena");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentEndian != endian)
|
|
||||||
{
|
|
||||||
if (endian == 0)
|
|
||||||
fileOut << (p ? " writer.setEndian(Athena::LittleEndian);\n" : " reader.setEndian(Athena::LittleEndian);\n");
|
|
||||||
else if (endian == 1)
|
|
||||||
fileOut << (p ? " writer.setEndian(Athena::BigEndian);\n" : " reader.setEndian(Athena::BigEndian);\n");
|
|
||||||
currentEndian = endian;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileOut << " /* " << field->getName() << " */\n";
|
|
||||||
if (!p)
|
|
||||||
fileOut << " " << field->getName() << " = " << ioOp << ";\n";
|
|
||||||
else
|
|
||||||
fileOut << " " << ioOp << "\n";
|
|
||||||
}
|
}
|
||||||
else if (!tsDecl->getNameAsString().compare("Vector"))
|
else
|
||||||
{
|
fieldName = field->getNameAsString();
|
||||||
int endian = -1;
|
|
||||||
if (classParms->size() >= 3)
|
|
||||||
{
|
|
||||||
const clang::NamedDecl* endianParm = classParms->getParam(2);
|
|
||||||
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
|
||||||
{
|
|
||||||
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
|
||||||
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
|
||||||
llvm::APSInt result;
|
|
||||||
if (defArg->isIntegerConstantExpr(result, context))
|
|
||||||
endian = result.getSExtValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clang::QualType templateType;
|
if (regType->getTypeClass() == clang::Type::TemplateSpecialization)
|
||||||
const clang::DeclRefExpr* cntRefExpr = nullptr;
|
{
|
||||||
std::string ioOp;
|
const clang::TemplateSpecializationType* tsType = (const clang::TemplateSpecializationType*)regType;
|
||||||
bool isDNAType = false;
|
const clang::TemplateDecl* tsDecl = tsType->getTemplateName().getAsTemplateDecl();
|
||||||
std::string sizeVar;
|
const clang::TemplateParameterList* classParms = tsDecl->getTemplateParameters();
|
||||||
const clang::TemplateArgument* typeArg = nullptr;
|
|
||||||
const clang::TemplateArgument* sizeArg = nullptr;
|
if (!tsDecl->getNameAsString().compare("Value"))
|
||||||
size_t idx = 0;
|
|
||||||
for (const clang::TemplateArgument& arg : *tsType)
|
|
||||||
{
|
{
|
||||||
if (arg.getKind() == clang::TemplateArgument::Type)
|
llvm::APSInt endian(64, -1);
|
||||||
|
const clang::Expr* endianExpr = nullptr;
|
||||||
|
if (classParms->size() >= 2)
|
||||||
{
|
{
|
||||||
typeArg = &arg;
|
const clang::NamedDecl* endianParm = classParms->getParam(1);
|
||||||
templateType = arg.getAsType().getCanonicalType();
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
clang::TypeInfo typeInfo = context.getTypeInfo(templateType);
|
|
||||||
static const std::string itStr = "*it";
|
|
||||||
ioOp = GetOpString(templateType.getTypePtr(), typeInfo.Width, itStr, p, isDNAType);
|
|
||||||
}
|
|
||||||
else if (arg.getKind() == clang::TemplateArgument::Expression)
|
|
||||||
{
|
|
||||||
const clang::Expr* expr = arg.getAsExpr();
|
|
||||||
if (idx == 1)
|
|
||||||
{
|
{
|
||||||
sizeArg = &arg;
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
||||||
|
endianExpr = defArg;
|
||||||
|
if (!defArg->isIntegerConstantExpr(endian, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clang::QualType templateType;
|
||||||
|
std::string ioOp;
|
||||||
|
bool isDNAType = false;
|
||||||
|
const clang::TemplateArgument* typeArg = nullptr;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Type)
|
||||||
|
{
|
||||||
|
typeArg = &arg;
|
||||||
|
templateType = arg.getAsType().getCanonicalType();
|
||||||
|
const clang::Type* type = arg.getAsType().getCanonicalType().getTypePtr();
|
||||||
|
ioOp = GetOpString(type, regTypeInfo.Width, fieldName, p, isDNAType);
|
||||||
|
}
|
||||||
|
else if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
endianExpr = expr;
|
||||||
|
if (expr->isIntegerConstantExpr(endian, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int endianVal = endian.getSExtValue();
|
||||||
|
if (endianVal != 0 && endianVal != 1)
|
||||||
|
{
|
||||||
|
if (endianExpr)
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioOp.empty())
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use type '" + tsDecl->getNameAsString() + "' with Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentEndian != endianVal)
|
||||||
|
{
|
||||||
|
if (endianVal == 0)
|
||||||
|
fileOut << (p ? " writer.setEndian(Athena::LittleEndian);\n" : " reader.setEndian(Athena::LittleEndian);\n");
|
||||||
|
else if (endianVal == 1)
|
||||||
|
fileOut << (p ? " writer.setEndian(Athena::BigEndian);\n" : " reader.setEndian(Athena::BigEndian);\n");
|
||||||
|
currentEndian = endianVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (!p)
|
||||||
|
fileOut << " " << fieldName << " = " << ioOp << ";\n";
|
||||||
|
else
|
||||||
|
fileOut << " " << ioOp << "\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getNameAsString().compare("Vector"))
|
||||||
|
{
|
||||||
|
llvm::APSInt endian(64, -1);
|
||||||
|
const clang::Expr* endianExpr = nullptr;
|
||||||
|
if (classParms->size() >= 3)
|
||||||
|
{
|
||||||
|
const clang::NamedDecl* endianParm = classParms->getParam(2);
|
||||||
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
|
{
|
||||||
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
|
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
||||||
|
endianExpr = defArg;
|
||||||
|
if (!defArg->isIntegerConstantExpr(endian, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clang::QualType templateType;
|
||||||
|
std::string ioOp;
|
||||||
|
bool isDNAType = false;
|
||||||
|
std::string sizeExpr;
|
||||||
|
const clang::TemplateArgument* typeArg = nullptr;
|
||||||
|
const clang::TemplateArgument* sizeArg = nullptr;
|
||||||
|
size_t idx = 0;
|
||||||
|
bool bad = false;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Type)
|
||||||
|
{
|
||||||
|
typeArg = &arg;
|
||||||
|
templateType = arg.getAsType().getCanonicalType();
|
||||||
|
clang::TypeInfo typeInfo = context.getTypeInfo(templateType);
|
||||||
|
static const std::string elemStr = "elem";
|
||||||
|
ioOp = GetOpString(templateType.getTypePtr(), typeInfo.Width, elemStr, p, isDNAType);
|
||||||
|
}
|
||||||
|
else if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
if (idx == 1)
|
||||||
|
{
|
||||||
|
sizeArg = &arg;
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
||||||
|
if (uExpr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
|
||||||
|
uExpr->getKind() == clang::UETT_SizeOf)
|
||||||
|
{
|
||||||
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
|
llvm::raw_string_ostream strStream(sizeExpr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (idx == 2)
|
||||||
|
{
|
||||||
|
endianExpr = expr;
|
||||||
|
if (!expr->isIntegerConstantExpr(endian, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
if (bad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int endianVal = endian.getSExtValue();
|
||||||
|
if (endianVal != 0 && endianVal != 1)
|
||||||
|
{
|
||||||
|
if (endianExpr)
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioOp.empty())
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use type '" + templateType.getAsString() + "' with Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeExpr.empty())
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use count variable with Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentEndian != endianVal)
|
||||||
|
{
|
||||||
|
if (endianVal == 0)
|
||||||
|
fileOut << (p ? " writer.setEndian(Athena::LittleEndian);\n" : " reader.setEndian(Athena::LittleEndian);\n");
|
||||||
|
else if (endianVal == 1)
|
||||||
|
fileOut << (p ? " writer.setEndian(Athena::BigEndian);\n" : " reader.setEndian(Athena::BigEndian);\n");
|
||||||
|
currentEndian = endianVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
fileOut << " " << fieldName << ".clear();\n";
|
||||||
|
fileOut << " " << fieldName << ".reserve(" << sizeExpr << ");\n";
|
||||||
|
if (isDNAType)
|
||||||
|
fileOut << " for (int i=0 ; i<(" << sizeExpr << ") ; ++i)\n"
|
||||||
|
" {\n"
|
||||||
|
" " << fieldName << ".emplace_back();\n"
|
||||||
|
" " << fieldName << ".back()." << ioOp << "\n"
|
||||||
|
" }\n";
|
||||||
|
else
|
||||||
|
fileOut << " for (int i=0 ; i<(" << sizeExpr << ") ; ++i)\n " << fieldName << ".push_back(" << ioOp << ");\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileOut << " for (auto elem : " << fieldName << ")\n";
|
||||||
|
if (isDNAType)
|
||||||
|
fileOut << " elem." << ioOp << "\n";
|
||||||
|
else
|
||||||
|
fileOut << " " << ioOp << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getNameAsString().compare("Buffer"))
|
||||||
|
{
|
||||||
|
const clang::Expr* sizeExpr = nullptr;
|
||||||
|
std::string sizeExprStr;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)arg.getAsExpr();
|
||||||
if (uExpr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
|
if (uExpr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
|
||||||
uExpr->getKind() == clang::UETT_SizeOf)
|
uExpr->getKind() == clang::UETT_SizeOf)
|
||||||
{
|
{
|
||||||
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
if (argExpr->getStmtClass() == clang::Stmt::DeclRefExprClass)
|
sizeExpr = argExpr;
|
||||||
|
llvm::raw_string_ostream strStream(sizeExprStr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sizeExprStr.empty())
|
||||||
|
{
|
||||||
|
if (sizeExpr)
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(sizeExpr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use size variable with Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(sizeExpr->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use size variable with Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (!p)
|
||||||
|
{
|
||||||
|
fileOut << " " << fieldName << ".reset(new atUint8[" << sizeExprStr << "]);\n";
|
||||||
|
fileOut << " reader.readUBytesToBuf(" << fieldName << ".get(), " << sizeExprStr << ");\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileOut << " writer.writeUBytes(" << fieldName << ".get(), " << sizeExprStr << ");\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getNameAsString().compare("String"))
|
||||||
|
{
|
||||||
|
const clang::Expr* sizeExpr = nullptr;
|
||||||
|
std::string sizeExprStr;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
||||||
|
llvm::APSInt sizeLiteral;
|
||||||
|
if (expr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
|
||||||
|
uExpr->getKind() == clang::UETT_SizeOf)
|
||||||
|
{
|
||||||
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
|
sizeExpr = argExpr;
|
||||||
|
llvm::raw_string_ostream strStream(sizeExprStr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
||||||
|
{
|
||||||
|
sizeExprStr = sizeLiteral.toString(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (!p)
|
||||||
|
fileOut << " " << fieldName << " = reader.readString(" << sizeExprStr << ");\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.writeString(" << fieldName << ");\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getNameAsString().compare("WString"))
|
||||||
|
{
|
||||||
|
llvm::APSInt endian(64, -1);
|
||||||
|
const clang::Expr* endianExpr = nullptr;
|
||||||
|
if (classParms->size() >= 2)
|
||||||
|
{
|
||||||
|
const clang::NamedDecl* endianParm = classParms->getParam(1);
|
||||||
|
if (endianParm->getKind() == clang::Decl::NonTypeTemplateParm)
|
||||||
|
{
|
||||||
|
const clang::NonTypeTemplateParmDecl* nttParm = (clang::NonTypeTemplateParmDecl*)endianParm;
|
||||||
|
const clang::Expr* defArg = nttParm->getDefaultArgument();
|
||||||
|
endianExpr = defArg;
|
||||||
|
if (!defArg->isIntegerConstantExpr(endian, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(defArg->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(defArg->getSourceRange(), true));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const clang::Expr* sizeExpr = nullptr;
|
||||||
|
std::string sizeExprStr;
|
||||||
|
size_t idx = 0;
|
||||||
|
bool bad = false;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
llvm::APSInt sizeLiteral;
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
||||||
|
if (expr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
|
||||||
|
uExpr->getKind() == clang::UETT_SizeOf)
|
||||||
{
|
{
|
||||||
cntRefExpr = (clang::DeclRefExpr*)argExpr;
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
sizeVar = cntRefExpr->getFoundDecl()->getNameAsString();
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
|
sizeExpr = argExpr;
|
||||||
|
llvm::raw_string_ostream strStream(sizeExprStr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
||||||
|
{
|
||||||
|
sizeExprStr = sizeLiteral.toString(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (idx == 1)
|
||||||
|
{
|
||||||
|
endianExpr = expr;
|
||||||
|
if (!expr->isIntegerConstantExpr(endian, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (idx == 2)
|
++idx;
|
||||||
|
}
|
||||||
|
if (bad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int endianVal = endian.getSExtValue();
|
||||||
|
if (endianVal != 0 && endianVal != 1)
|
||||||
|
{
|
||||||
|
if (endianExpr)
|
||||||
{
|
{
|
||||||
llvm::APSInt value;
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(endianExpr->getLocStart(), AthenaError);
|
||||||
if (expr->isIntegerConstantExpr(value, context))
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
endian = value.getSExtValue();
|
diag.AddSourceRange(clang::CharSourceRange(endianExpr->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Endian value must be 'BigEndian' or 'LittleEndian'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentEndian != endianVal)
|
||||||
|
{
|
||||||
|
if (endianVal == 0)
|
||||||
|
fileOut << (p ? " writer.setEndian(Athena::LittleEndian);\n" : " reader.setEndian(Athena::LittleEndian);\n");
|
||||||
|
else if (endianVal == 1)
|
||||||
|
fileOut << (p ? " writer.setEndian(Athena::BigEndian);\n" : " reader.setEndian(Athena::BigEndian);\n");
|
||||||
|
currentEndian = endianVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (!p)
|
||||||
|
fileOut << " " << fieldName << " = reader.readWString(" << sizeExprStr << ");\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.writeWString(" << fieldName << ");\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getNameAsString().compare("UTF8"))
|
||||||
|
{
|
||||||
|
const clang::Expr* sizeExpr = nullptr;
|
||||||
|
std::string sizeExprStr;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
||||||
|
llvm::APSInt sizeLiteral;
|
||||||
|
if (expr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
|
||||||
|
uExpr->getKind() == clang::UETT_SizeOf)
|
||||||
|
{
|
||||||
|
const clang::Expr* argExpr = uExpr->getArgumentExpr();
|
||||||
|
while (argExpr->getStmtClass() == clang::Stmt::ParenExprClass)
|
||||||
|
argExpr = ((clang::ParenExpr*)argExpr)->getSubExpr();
|
||||||
|
sizeExpr = argExpr;
|
||||||
|
llvm::raw_string_ostream strStream(sizeExprStr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
else if (expr->isIntegerConstantExpr(sizeLiteral, context))
|
||||||
|
{
|
||||||
|
sizeExprStr = sizeLiteral.toString(10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ioOp.empty())
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
{
|
if (!p)
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), context.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Fatal, "Athena error: %0"));
|
fileOut << " " << fieldName << " = reader.readUnicode(" << sizeExprStr << ");\n";
|
||||||
diag.AddString("Unable to use type '" + templateType.getAsString() + "' with Athena");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sizeVar.empty())
|
|
||||||
{
|
|
||||||
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), context.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Fatal, "Athena error: %0"));
|
|
||||||
diag.AddString("Unable to use count variable with Athena");
|
|
||||||
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentEndian != endian)
|
|
||||||
{
|
|
||||||
if (endian == 0)
|
|
||||||
fileOut << (p ? " writer.setEndian(Athena::LittleEndian);\n" : " reader.setEndian(Athena::LittleEndian);\n");
|
|
||||||
else if (endian == 1)
|
|
||||||
fileOut << (p ? " writer.setEndian(Athena::BigEndian);\n" : " reader.setEndian(Athena::BigEndian);\n");
|
|
||||||
currentEndian = endian;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileOut << " /* " << field->getName() << " */\n";
|
|
||||||
if (!p)
|
|
||||||
{
|
|
||||||
fileOut << " " << field->getName() << ".clear();\n";
|
|
||||||
fileOut << " " << field->getName() << ".reserve(" << sizeVar << ");\n";
|
|
||||||
if (isDNAType)
|
|
||||||
fileOut << " for (int i=0 ; i<" << sizeVar << " ; ++i)\n"
|
|
||||||
" {\n"
|
|
||||||
" " << field->getName() << ".emplace_back();\n"
|
|
||||||
" " << field->getName() << ".back()." << ioOp << "\n"
|
|
||||||
" }\n";
|
|
||||||
else
|
else
|
||||||
fileOut << " for (int i=0 ; i<" << sizeVar << " ; ++i)\n " << field->getName() << ".push_back(" << ioOp << ");\n";
|
fileOut << " writer.writeUnicode(" << fieldName << ");\n";
|
||||||
}
|
}
|
||||||
else
|
else if (!tsDecl->getNameAsString().compare("Seek"))
|
||||||
{
|
{
|
||||||
if (isDNAType)
|
size_t idx = 0;
|
||||||
fileOut << " for (int i=0, auto it=" << field->getName() << ".begin() ; i<" << sizeVar << " && it!=" << field->getName() << ".end() ; ++i, ++it)\n it->" << ioOp << "\n";
|
llvm::APSInt offset(64, 0);
|
||||||
else
|
llvm::APSInt direction(64, 0);
|
||||||
fileOut << " for (int i=0, auto it=" << field->getName() << ".begin() ; i<" << sizeVar << " && it!=" << field->getName() << ".end() ; ++i, ++it)\n " << ioOp << "\n";
|
const clang::Expr* directionExpr = nullptr;
|
||||||
|
bool bad = false;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
if (!idx)
|
||||||
|
{
|
||||||
|
if (!expr->isIntegerConstantExpr(offset, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use non-constant offset expression in Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directionExpr = expr;
|
||||||
|
if (!expr->isIntegerConstantExpr(direction, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use non-constant direction expression in Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
if (bad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int64_t offsetVal = offset.getSExtValue();
|
||||||
|
int64_t directionVal = direction.getSExtValue();
|
||||||
|
if (directionVal < 0 || directionVal > 2)
|
||||||
|
{
|
||||||
|
if (directionExpr)
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(directionExpr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Direction parameter must be 'Begin', 'Current', or 'End'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(directionExpr->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(field->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Direction parameter must be 'Begin', 'Current', or 'End'");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(field->getSourceRange(), true));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (directionVal == 0)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
fileOut << " reader.seek(" << offsetVal << ", Athena::Begin);\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.seek(" << offsetVal << ", Athena::Begin);\n";
|
||||||
|
}
|
||||||
|
else if (directionVal == 1)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
fileOut << " reader.seek(" << offsetVal << ", Athena::Current);\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.seek(" << offsetVal << ", Athena::Current);\n";
|
||||||
|
}
|
||||||
|
else if (directionVal == 2)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
fileOut << " reader.seek(" << offsetVal << ", Athena::End);\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.seek(" << offsetVal << ", Athena::End);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getNameAsString().compare("Align"))
|
||||||
|
{
|
||||||
|
llvm::APSInt align(64, 0);
|
||||||
|
bool bad = false;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr();
|
||||||
|
if (!expr->isIntegerConstantExpr(align, context))
|
||||||
|
{
|
||||||
|
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
|
||||||
|
diag.AddString("Unable to use non-constant align expression in Athena");
|
||||||
|
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int64_t alignVal = align.getSExtValue();
|
||||||
|
if (alignVal)
|
||||||
|
{
|
||||||
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
if (alignVal == 32)
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
fileOut << " reader.seekAlign32();\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.seekAlign32();\n";
|
||||||
|
}
|
||||||
|
else if (align.isPowerOf2())
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
fileOut << " reader.seek((reader.position() + " << alignVal-1 << ") & ~" << alignVal-1 << ", SeekOrigin::Begin);\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.seek((writer.position() + " << alignVal-1 << ") & ~" << alignVal-1 << ", SeekOrigin::Begin);\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!p)
|
||||||
|
fileOut << " reader.seek((reader.position() + " << alignVal-1 << ") / " << alignVal << " * " << alignVal << ", SeekOrigin::Begin);\n";
|
||||||
|
else
|
||||||
|
fileOut << " writer.seek((writer.position() + " << alignVal-1 << ") / " << alignVal << " * " << alignVal << ", SeekOrigin::Begin);\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
else if (regType->getTypeClass() == clang::Type::Record)
|
||||||
|
|
||||||
else if (regType->getTypeClass() == clang::Type::Record)
|
|
||||||
{
|
|
||||||
const clang::CXXRecordDecl* cxxRDecl = regType->getAsCXXRecordDecl();
|
|
||||||
if (cxxRDecl)
|
|
||||||
{
|
{
|
||||||
for (const clang::CXXBaseSpecifier& base : cxxRDecl->bases())
|
const clang::CXXRecordDecl* cxxRDecl = regType->getAsCXXRecordDecl();
|
||||||
|
if (cxxRDecl)
|
||||||
{
|
{
|
||||||
clang::QualType canonType = base.getType().getCanonicalType();
|
for (const clang::CXXBaseSpecifier& base : cxxRDecl->bases())
|
||||||
if (!canonType.getAsString().compare(0, 22, "struct Athena::io::DNA"))
|
|
||||||
{
|
{
|
||||||
fileOut << " /* " << field->getName() << " */\n";
|
clang::QualType canonType = base.getType().getCanonicalType();
|
||||||
fileOut << " " << field->getName() << (p ? ".write(writer);\n" : ".read(reader);\n");
|
if (!canonType.getAsString().compare(0, sizeof(ATHENA_DNA_BASETYPE)-1, ATHENA_DNA_BASETYPE))
|
||||||
currentEndian = -1;
|
{
|
||||||
break;
|
fileOut << " /* " << fieldName << " */\n";
|
||||||
|
fileOut << " " << fieldName << (p ? ".write(writer);\n" : ".read(reader);\n");
|
||||||
|
currentEndian = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -457,7 +901,7 @@ public:
|
||||||
fileOut << "#include \"" << inputf << "\"\n";
|
fileOut << "#include \"" << inputf << "\"\n";
|
||||||
fileOut << "\n";
|
fileOut << "\n";
|
||||||
|
|
||||||
/* Second pass - emit file */
|
/* Emit file */
|
||||||
emitVisitor.TraverseDecl(context.getTranslationUnitDecl());
|
emitVisitor.TraverseDecl(context.getTranslationUnitDecl());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -474,6 +918,7 @@ public:
|
||||||
fileout = compiler.createOutputFile(OutputFilename, false, true, "", "", true);
|
fileout = compiler.createOutputFile(OutputFilename, false, true, "", "", true);
|
||||||
else
|
else
|
||||||
fileout = compiler.createDefaultOutputFile(false, "a", "cpp");
|
fileout = compiler.createDefaultOutputFile(false, "a", "cpp");
|
||||||
|
AthenaError = compiler.getASTContext().getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "Athena error: %0");
|
||||||
return std::unique_ptr<clang::ASTConsumer>(new ATDNAConsumer(compiler.getASTContext(), *fileout));
|
return std::unique_ptr<clang::ASTConsumer>(new ATDNAConsumer(compiler.getASTContext(), *fileout));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,10 +27,21 @@ struct ANCSFile : public io::DNA<BigEndian>
|
||||||
|
|
||||||
ANCSSubFile subFile;
|
ANCSSubFile subFile;
|
||||||
|
|
||||||
Value<atUint32> arrCount;
|
Align<4> align;
|
||||||
Vector<atUint32, sizeof(arrCount)> array;
|
|
||||||
|
Value<atUint32> arrCount[2];
|
||||||
|
Vector<atUint32, sizeof(arrCount[0])> array;
|
||||||
|
|
||||||
|
Seek<21, Current> seek;
|
||||||
|
|
||||||
Value<atUint32> arrCount2;
|
Value<atUint32> arrCount2;
|
||||||
Vector<ANCSSubFile, sizeof(arrCount2)> array2;
|
Vector<ANCSSubFile, sizeof(arrCount[1] + arrCount2)> array2;
|
||||||
|
|
||||||
|
Value<atUint32> bufSz;
|
||||||
|
Buffer<sizeof(bufSz)> buf;
|
||||||
|
|
||||||
|
String<32> str;
|
||||||
|
WString<64> wstr;
|
||||||
|
UTF8<> utf8str[5];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef CHECKSUMS_HPP
|
#ifndef CHECKSUMS_HPP
|
||||||
#define CHECKSUMS_HPP
|
#define CHECKSUMS_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef COMPRESSION_HPP
|
#ifndef COMPRESSION_HPP
|
||||||
#define COMPRESSION_HPP
|
#define COMPRESSION_HPP
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "IStreamReader.hpp"
|
#include "IStreamReader.hpp"
|
||||||
#include "IStreamWriter.hpp"
|
#include "IStreamWriter.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Athena
|
namespace Athena
|
||||||
{
|
{
|
||||||
|
@ -34,6 +35,24 @@ struct DNA
|
||||||
template <typename T, size_t cntVar, Endian VE = DNAE>
|
template <typename T, size_t cntVar, Endian VE = DNAE>
|
||||||
using Vector = std::vector<T>;
|
using Vector = std::vector<T>;
|
||||||
|
|
||||||
|
template <size_t sizeVar>
|
||||||
|
using Buffer = std::unique_ptr<atUint8[]>;
|
||||||
|
|
||||||
|
template <atInt32 sizeVar = -1>
|
||||||
|
using String = std::string;
|
||||||
|
|
||||||
|
template <atInt32 sizeVar = -1, Endian VE = DNAE>
|
||||||
|
using WString = std::wstring;
|
||||||
|
|
||||||
|
template <atInt32 sizeVar = -1>
|
||||||
|
using UTF8 = std::string;
|
||||||
|
|
||||||
|
template <off_t offset, SeekOrigin direction>
|
||||||
|
struct Seek {};
|
||||||
|
|
||||||
|
template <size_t align>
|
||||||
|
struct Align {};
|
||||||
|
|
||||||
virtual void read(IStreamReader&)=0;
|
virtual void read(IStreamReader&)=0;
|
||||||
virtual void write(IStreamWriter&) const=0;
|
virtual void write(IStreamWriter&) const=0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef EXCEPTION_HPP
|
#ifndef EXCEPTION_HPP
|
||||||
#define EXCEPTION_HPP
|
#define EXCEPTION_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef FILENOTFOUNDEXCEPTION_HPP
|
#ifndef FILENOTFOUNDEXCEPTION_HPP
|
||||||
#define FILENOTFOUNDEXCEPTION_HPP
|
#define FILENOTFOUNDEXCEPTION_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef FILESTREAM_HPP
|
#ifndef FILESTREAM_HPP
|
||||||
#define FILESTREAM_HPP
|
#define FILESTREAM_HPP
|
||||||
|
|
||||||
|
@ -63,7 +48,10 @@ public:
|
||||||
double readDouble();
|
double readDouble();
|
||||||
float readFloat();
|
float readFloat();
|
||||||
bool readBool();
|
bool readBool();
|
||||||
|
atVec3f readVec3f();
|
||||||
|
atVec4f readVec4f();
|
||||||
std::string readString(atInt32 maxlen = -1);
|
std::string readString(atInt32 maxlen = -1);
|
||||||
|
std::wstring readWString(atInt32 maxLen = -1);
|
||||||
std::string readUnicode(atInt32 maxlen = -1);
|
std::string readUnicode(atInt32 maxlen = -1);
|
||||||
protected:
|
protected:
|
||||||
std::string m_filename;
|
std::string m_filename;
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef FILEWRITER_HPP
|
#ifndef FILEWRITER_HPP
|
||||||
#define FILEWRITER_HPP
|
#define FILEWRITER_HPP
|
||||||
|
|
||||||
|
@ -57,7 +42,10 @@ public:
|
||||||
void writeDouble(double val);
|
void writeDouble(double val);
|
||||||
void writeFloat(float val);
|
void writeFloat(float val);
|
||||||
void writeBool(bool val);
|
void writeBool(bool val);
|
||||||
|
void writeVec3f(atVec3f vec);
|
||||||
|
void writeVec4f(atVec4f vec);
|
||||||
void writeString(const std::string& val);
|
void writeString(const std::string& val);
|
||||||
|
void writeWString(const std::wstring& str);
|
||||||
void writeUnicode(const std::string& str);
|
void writeUnicode(const std::string& str);
|
||||||
void fill(atInt8 byte, atUint64 len);
|
void fill(atInt8 byte, atUint64 len);
|
||||||
void fill(atUint8 byte, atUint64 len);
|
void fill(atUint8 byte, atUint64 len);
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef GLOBAL_HPP
|
#ifndef GLOBAL_HPP
|
||||||
#define GLOBAL_HPP
|
#define GLOBAL_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef IOEXCEPTION_HPP
|
#ifndef IOEXCEPTION_HPP
|
||||||
#define IOEXCEPTION_HPP
|
#define IOEXCEPTION_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef STREAM_HPP
|
#ifndef STREAM_HPP
|
||||||
#define STREAM_HPP
|
#define STREAM_HPP
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,11 @@ public:
|
||||||
virtual double readDouble() = 0;
|
virtual double readDouble() = 0;
|
||||||
virtual float readFloat() = 0;
|
virtual float readFloat() = 0;
|
||||||
virtual bool readBool() = 0;
|
virtual bool readBool() = 0;
|
||||||
|
virtual atVec3f readVec3f() = 0;
|
||||||
|
virtual atVec4f readVec4f() = 0;
|
||||||
virtual std::string readUnicode(atInt32 = -1) = 0;
|
virtual std::string readUnicode(atInt32 = -1) = 0;
|
||||||
virtual std::string readString(atInt32 = -1) = 0;
|
virtual std::string readString(atInt32 = -1) = 0;
|
||||||
|
virtual std::wstring readWString(atInt32 = -1) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,10 @@ public:
|
||||||
virtual void writeDouble(double) = 0;
|
virtual void writeDouble(double) = 0;
|
||||||
virtual void writeFloat(float) = 0;
|
virtual void writeFloat(float) = 0;
|
||||||
virtual void writeBool(bool) = 0;
|
virtual void writeBool(bool) = 0;
|
||||||
|
virtual void writeVec3f(atVec3f vec) = 0;
|
||||||
|
virtual void writeVec4f(atVec4f vec) = 0;
|
||||||
virtual void writeString(const std::string&) = 0;
|
virtual void writeString(const std::string&) = 0;
|
||||||
|
virtual void writeWString(const std::wstring&) = 0;
|
||||||
virtual void writeUnicode(const std::string&) = 0;
|
virtual void writeUnicode(const std::string&) = 0;
|
||||||
virtual void fill(atUint8, atUint64) = 0;
|
virtual void fill(atUint8, atUint64) = 0;
|
||||||
virtual void fill(atInt8, atUint64) = 0;
|
virtual void fill(atInt8, atUint64) = 0;
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef INVALIDDATAEXCEPTION_HPP
|
#ifndef INVALIDDATAEXCEPTION_HPP
|
||||||
#define INVALIDDATAEXCEPTION_HPP
|
#define INVALIDDATAEXCEPTION_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef INVALID_OPERATION_EXCEPTION_HPP
|
#ifndef INVALID_OPERATION_EXCEPTION_HPP
|
||||||
#define INVALID_OPERATION_EXCEPTION_HPP
|
#define INVALID_OPERATION_EXCEPTION_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef MEMORYREADER_HPP
|
#ifndef MEMORYREADER_HPP
|
||||||
#define MEMORYREADER_HPP
|
#define MEMORYREADER_HPP
|
||||||
|
|
||||||
|
@ -268,6 +253,20 @@ public:
|
||||||
*/
|
*/
|
||||||
bool readBool();
|
bool readBool();
|
||||||
|
|
||||||
|
/*! \brief Reads an atVec3f (12 bytes) and advances the current position
|
||||||
|
*
|
||||||
|
* \return atVec3f The value at the current address
|
||||||
|
* \throw IOException when address is out of range
|
||||||
|
*/
|
||||||
|
atVec3f readVec3f();
|
||||||
|
|
||||||
|
/*! \brief Reads an atVec4f (16 bytes) and advances the current position
|
||||||
|
*
|
||||||
|
* \return atVec4f The value at the current address
|
||||||
|
* \throw IOException when address is out of range
|
||||||
|
*/
|
||||||
|
atVec4f readVec4f();
|
||||||
|
|
||||||
/*! \brief Reads a Unicode string and advances the position in the file
|
/*! \brief Reads a Unicode string and advances the position in the file
|
||||||
*
|
*
|
||||||
* \return std::string The value at the current address
|
* \return std::string The value at the current address
|
||||||
|
@ -282,6 +281,13 @@ public:
|
||||||
*/
|
*/
|
||||||
std::string readString(atInt32 maxlen = -1);
|
std::string readString(atInt32 maxlen = -1);
|
||||||
|
|
||||||
|
/*! \brief Reads a wstring and advances the position in the file
|
||||||
|
*
|
||||||
|
* \return std::wstring The value at the current address
|
||||||
|
* \throw IOException when address is out of range
|
||||||
|
*/
|
||||||
|
std::wstring readWString(atInt32 maxlen = -1);
|
||||||
|
|
||||||
void setProgressCallback(std::function<void(int)> cb);
|
void setProgressCallback(std::function<void(int)> cb);
|
||||||
protected:
|
protected:
|
||||||
void loadData();
|
void loadData();
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef MEMORYWRITER_HPP
|
#ifndef MEMORYWRITER_HPP
|
||||||
#define MEMORYWRITER_HPP
|
#define MEMORYWRITER_HPP
|
||||||
|
|
||||||
|
@ -261,6 +246,22 @@ public:
|
||||||
*/
|
*/
|
||||||
void writeBool(bool);
|
void writeBool(bool);
|
||||||
|
|
||||||
|
/*! \brief Writes an atVec3f (12 bytes) to the buffer and advances the buffer.
|
||||||
|
* It also swaps the bytes depending on the platform and Stream settings.
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
* \param vec The value to write to the buffer
|
||||||
|
*/
|
||||||
|
void writeVec3f(atVec3f vec);
|
||||||
|
|
||||||
|
/*! \brief Writes an atVec4f (16 bytes) to the buffer and advances the buffer.
|
||||||
|
* It also swaps the bytes depending on the platform and Stream settings.
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
* \param vec The value to write to the buffer
|
||||||
|
*/
|
||||||
|
void writeVec4f(atVec4f vec);
|
||||||
|
|
||||||
/*! \brief Writes an unicode string to the buffer and advances the buffer.
|
/*! \brief Writes an unicode string to the buffer and advances the buffer.
|
||||||
* It also swaps the bytes depending on the platform and Stream settings.
|
* It also swaps the bytes depending on the platform and Stream settings.
|
||||||
*
|
*
|
||||||
|
@ -276,6 +277,14 @@ public:
|
||||||
*/
|
*/
|
||||||
void writeString(const std::string& str);
|
void writeString(const std::string& str);
|
||||||
|
|
||||||
|
/*! \brief Writes an wstring to the buffer and advances the buffer.
|
||||||
|
*
|
||||||
|
* \sa Endian
|
||||||
|
* \param str The string to write to the buffer
|
||||||
|
*/
|
||||||
|
void writeWString(const std::wstring& str);
|
||||||
|
|
||||||
|
|
||||||
void fill(atUint8 val, atUint64 length);
|
void fill(atUint8 val, atUint64 length);
|
||||||
void fill(atInt8 val, atUint64 length);
|
void fill(atInt8 val, atUint64 length);
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef NOTIMPLEMENTEDEXCEPTION_HPP
|
#ifndef NOTIMPLEMENTEDEXCEPTION_HPP
|
||||||
#define NOTIMPLEMENTEDEXCEPTION_HPP
|
#define NOTIMPLEMENTEDEXCEPTION_HPP
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#ifndef TYPES_HPP
|
#ifndef TYPES_HPP
|
||||||
#define TYPES_HPP
|
#define TYPES_HPP
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
|
@ -1,20 +1,4 @@
|
||||||
// This file is part of libAthena.
|
#ifndef __UTILITY_H__
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UTILITY_H__
|
|
||||||
#define __UTILITY_H__
|
#define __UTILITY_H__
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/Checksums.hpp"
|
#include "Athena/Checksums.hpp"
|
||||||
#include "Athena/FileReader.hpp"
|
#include "Athena/FileReader.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/Compression.hpp"
|
#include "Athena/Compression.hpp"
|
||||||
#include "Athena/Exception.hpp"
|
#include "Athena/Exception.hpp"
|
||||||
#include <lzo/lzo1x.h>
|
#include <lzo/lzo1x.h>
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/FileReader.hpp"
|
#include "Athena/FileReader.hpp"
|
||||||
#include "Athena/FileNotFoundException.hpp"
|
#include "Athena/FileNotFoundException.hpp"
|
||||||
#include "Athena/InvalidDataException.hpp"
|
#include "Athena/InvalidDataException.hpp"
|
||||||
|
@ -316,9 +301,48 @@ bool FileReader::readBool()
|
||||||
return (readByte() != 0);
|
return (readByte() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atVec3f FileReader::readVec3f()
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
THROW_INVALID_OPERATION_EXCEPTION_RETURN({}, "File not open for reading");
|
||||||
|
|
||||||
|
m_bitValid = false;
|
||||||
|
atVec3f val = {};
|
||||||
|
fread(&val, 1, 12, m_fileHandle);
|
||||||
|
|
||||||
|
if ((!utility::isSystemBigEndian() && isBigEndian()) || (utility::isSystemBigEndian() && isLittleEndian()))
|
||||||
|
{
|
||||||
|
val.vec[0] = utility::swapFloat(val.vec[0]);
|
||||||
|
val.vec[1] = utility::swapFloat(val.vec[1]);
|
||||||
|
val.vec[2] = utility::swapFloat(val.vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
atVec4f FileReader::readVec4f()
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
THROW_INVALID_OPERATION_EXCEPTION_RETURN({}, "File not open for reading");
|
||||||
|
|
||||||
|
m_bitValid = false;
|
||||||
|
atVec4f val = {};
|
||||||
|
fread(&val, 1, 16, m_fileHandle);
|
||||||
|
|
||||||
|
if ((!utility::isSystemBigEndian() && isBigEndian()) || (utility::isSystemBigEndian() && isLittleEndian()))
|
||||||
|
{
|
||||||
|
val.vec[0] = utility::swapFloat(val.vec[0]);
|
||||||
|
val.vec[1] = utility::swapFloat(val.vec[1]);
|
||||||
|
val.vec[2] = utility::swapFloat(val.vec[2]);
|
||||||
|
val.vec[3] = utility::swapFloat(val.vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
std::string FileReader::readString(atInt32 maxlen)
|
std::string FileReader::readString(atInt32 maxlen)
|
||||||
{
|
{
|
||||||
std::string ret = "";
|
std::string ret;
|
||||||
atUint8 chr = readByte();
|
atUint8 chr = readByte();
|
||||||
|
|
||||||
atInt32 i = 0;
|
atInt32 i = 0;
|
||||||
|
@ -336,6 +360,26 @@ std::string FileReader::readString(atInt32 maxlen)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring FileReader::readWString(atInt32 maxlen)
|
||||||
|
{
|
||||||
|
std::wstring ret;
|
||||||
|
atUint16 chr = readUint16();
|
||||||
|
|
||||||
|
atInt32 i = 0;
|
||||||
|
|
||||||
|
while (chr != 0)
|
||||||
|
{
|
||||||
|
if (maxlen >= 0 && i >= maxlen - 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret += chr;
|
||||||
|
chr = readUint16();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
std::string FileReader::readUnicode(atInt32 maxlen)
|
std::string FileReader::readUnicode(atInt32 maxlen)
|
||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/FileWriter.hpp"
|
#include "Athena/FileWriter.hpp"
|
||||||
#include "Athena/FileNotFoundException.hpp"
|
#include "Athena/FileNotFoundException.hpp"
|
||||||
#include "Athena/InvalidDataException.hpp"
|
#include "Athena/InvalidDataException.hpp"
|
||||||
|
@ -276,6 +261,43 @@ void FileWriter::writeBool(bool val)
|
||||||
writeByte(val);
|
writeByte(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileWriter::writeVec3f(atVec3f vec)
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
|
||||||
|
|
||||||
|
m_bitValid = false;
|
||||||
|
|
||||||
|
if ((!utility::isSystemBigEndian() && isBigEndian()) || (utility::isSystemBigEndian() && isLittleEndian()))
|
||||||
|
{
|
||||||
|
vec.vec[0] = utility::swapFloat(vec.vec[0]);
|
||||||
|
vec.vec[1] = utility::swapFloat(vec.vec[1]);
|
||||||
|
vec.vec[2] = utility::swapFloat(vec.vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(&vec, 1, 12, m_fileHandle) != 12)
|
||||||
|
THROW_IO_EXCEPTION("Unable to write to stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileWriter::writeVec4f(atVec4f vec)
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
|
||||||
|
|
||||||
|
m_bitValid = false;
|
||||||
|
|
||||||
|
if ((!utility::isSystemBigEndian() && isBigEndian()) || (utility::isSystemBigEndian() && isLittleEndian()))
|
||||||
|
{
|
||||||
|
vec.vec[0] = utility::swapFloat(vec.vec[0]);
|
||||||
|
vec.vec[1] = utility::swapFloat(vec.vec[1]);
|
||||||
|
vec.vec[2] = utility::swapFloat(vec.vec[2]);
|
||||||
|
vec.vec[3] = utility::swapFloat(vec.vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fwrite(&vec, 1, 16, m_fileHandle) != 16)
|
||||||
|
THROW_IO_EXCEPTION("Unable to write to stream");
|
||||||
|
}
|
||||||
|
|
||||||
void FileWriter::writeString(const std::string& val)
|
void FileWriter::writeString(const std::string& val)
|
||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
|
@ -292,6 +314,22 @@ void FileWriter::writeString(const std::string& val)
|
||||||
THROW_IO_EXCEPTION("Unable to write to stream");
|
THROW_IO_EXCEPTION("Unable to write to stream");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileWriter::writeWString(const std::wstring& val)
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
|
||||||
|
|
||||||
|
m_bitValid = false;
|
||||||
|
|
||||||
|
wchar_t term = L'\0';
|
||||||
|
|
||||||
|
if (fwrite(val.c_str(), 2, val.length(), m_fileHandle) != val.length())
|
||||||
|
THROW_IO_EXCEPTION("Unable to write to stream");
|
||||||
|
|
||||||
|
if (fwrite(&term, 2, 1, m_fileHandle) != 1)
|
||||||
|
THROW_IO_EXCEPTION("Unable to write to stream");
|
||||||
|
}
|
||||||
|
|
||||||
void FileWriter::writeUnicode(const std::string& str)
|
void FileWriter::writeUnicode(const std::string& str)
|
||||||
{
|
{
|
||||||
if (!isOpen())
|
if (!isOpen())
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/Global.hpp"
|
#include "Athena/Global.hpp"
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin)
|
std::ostream& operator<<(std::ostream& os, const Athena::SeekOrigin& origin)
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/MemoryReader.hpp"
|
#include "Athena/MemoryReader.hpp"
|
||||||
#include "Athena/IOException.hpp"
|
#include "Athena/IOException.hpp"
|
||||||
#include "Athena/FileNotFoundException.hpp"
|
#include "Athena/FileNotFoundException.hpp"
|
||||||
|
@ -434,6 +419,74 @@ bool MemoryReader::readBool()
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
atVec3f MemoryReader::readVec3f()
|
||||||
|
{
|
||||||
|
if (!m_data)
|
||||||
|
loadData();
|
||||||
|
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(atUint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + 12 > m_length)
|
||||||
|
THROW_IO_EXCEPTION_RETURN({}, "Position %0.8X outside stream bounds ", m_position);
|
||||||
|
|
||||||
|
float* source = (float*)(m_data + m_position);
|
||||||
|
atVec3f result = {source[0], source[1], source[2]};
|
||||||
|
if (isBigEndian())
|
||||||
|
{
|
||||||
|
utility::BigFloat(result.vec[0]);
|
||||||
|
utility::BigFloat(result.vec[1]);
|
||||||
|
utility::BigFloat(result.vec[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
utility::LittleFloat(result.vec[0]);
|
||||||
|
utility::LittleFloat(result.vec[1]);
|
||||||
|
utility::LittleFloat(result.vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_position += 12;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
atVec4f MemoryReader::readVec4f()
|
||||||
|
{
|
||||||
|
if (!m_data)
|
||||||
|
loadData();
|
||||||
|
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(atUint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + 16 > m_length)
|
||||||
|
THROW_IO_EXCEPTION_RETURN({}, "Position %0.8X outside stream bounds ", m_position);
|
||||||
|
|
||||||
|
float* source = (float*)(m_data + m_position);
|
||||||
|
atVec4f result = {source[0], source[1], source[2], source[3]};
|
||||||
|
if (isBigEndian())
|
||||||
|
{
|
||||||
|
utility::BigFloat(result.vec[0]);
|
||||||
|
utility::BigFloat(result.vec[1]);
|
||||||
|
utility::BigFloat(result.vec[2]);
|
||||||
|
utility::BigFloat(result.vec[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
utility::LittleFloat(result.vec[0]);
|
||||||
|
utility::LittleFloat(result.vec[1]);
|
||||||
|
utility::LittleFloat(result.vec[2]);
|
||||||
|
utility::LittleFloat(result.vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_position += 16;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string MemoryReader::readUnicode(atInt32 maxlen)
|
std::string MemoryReader::readUnicode(atInt32 maxlen)
|
||||||
{
|
{
|
||||||
if (!m_data)
|
if (!m_data)
|
||||||
|
@ -464,7 +517,7 @@ std::string MemoryReader::readUnicode(atInt32 maxlen)
|
||||||
|
|
||||||
std::string MemoryReader::readString(atInt32 maxlen)
|
std::string MemoryReader::readString(atInt32 maxlen)
|
||||||
{
|
{
|
||||||
std::string ret = "";
|
std::string ret;
|
||||||
atUint8 chr = readByte();
|
atUint8 chr = readByte();
|
||||||
|
|
||||||
atInt32 i = 0;
|
atInt32 i = 0;
|
||||||
|
@ -482,6 +535,26 @@ std::string MemoryReader::readString(atInt32 maxlen)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring MemoryReader::readWString(atInt32 maxlen)
|
||||||
|
{
|
||||||
|
std::wstring ret;
|
||||||
|
atUint16 chr = readUint16();
|
||||||
|
|
||||||
|
atInt32 i = 0;
|
||||||
|
|
||||||
|
while (chr != 0)
|
||||||
|
{
|
||||||
|
if (maxlen >= 0 && i >= maxlen - 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret += chr;
|
||||||
|
chr = readUint16();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryReader::setProgressCallback(std::function<void (int)> cb)
|
void MemoryReader::setProgressCallback(std::function<void (int)> cb)
|
||||||
{
|
{
|
||||||
m_progressCallback = cb;
|
m_progressCallback = cb;
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
// This file is part of libAthena.
|
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/MemoryWriter.hpp"
|
#include "Athena/MemoryWriter.hpp"
|
||||||
#include "Athena/IOException.hpp"
|
#include "Athena/IOException.hpp"
|
||||||
#include "Athena/InvalidOperationException.hpp"
|
#include "Athena/InvalidOperationException.hpp"
|
||||||
|
@ -443,6 +428,75 @@ void MemoryWriter::writeBool(bool val)
|
||||||
m_position += sizeof(bool);
|
m_position += sizeof(bool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MemoryWriter::writeVec3f(atVec3f vec)
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
resize(12);
|
||||||
|
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(atUint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + 12 > m_length)
|
||||||
|
resize(m_position + 12);
|
||||||
|
|
||||||
|
if (isBigEndian())
|
||||||
|
{
|
||||||
|
utility::BigFloat(vec.vec[0]);
|
||||||
|
utility::BigFloat(vec.vec[1]);
|
||||||
|
utility::BigFloat(vec.vec[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
utility::LittleFloat(vec.vec[0]);
|
||||||
|
utility::LittleFloat(vec.vec[1]);
|
||||||
|
utility::LittleFloat(vec.vec[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
((float*)(m_data + m_position))[0] = vec.vec[0];
|
||||||
|
((float*)(m_data + m_position))[1] = vec.vec[1];
|
||||||
|
((float*)(m_data + m_position))[2] = vec.vec[2];
|
||||||
|
m_position += 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryWriter::writeVec4f(atVec4f vec)
|
||||||
|
{
|
||||||
|
if (!isOpen())
|
||||||
|
resize(16);
|
||||||
|
|
||||||
|
if (m_bitPosition > 0)
|
||||||
|
{
|
||||||
|
m_bitPosition = 0;
|
||||||
|
m_position += sizeof(atUint8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_position + 16 > m_length)
|
||||||
|
resize(m_position + 16);
|
||||||
|
|
||||||
|
if (isBigEndian())
|
||||||
|
{
|
||||||
|
utility::BigFloat(vec.vec[0]);
|
||||||
|
utility::BigFloat(vec.vec[1]);
|
||||||
|
utility::BigFloat(vec.vec[2]);
|
||||||
|
utility::BigFloat(vec.vec[3]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
utility::LittleFloat(vec.vec[0]);
|
||||||
|
utility::LittleFloat(vec.vec[1]);
|
||||||
|
utility::LittleFloat(vec.vec[2]);
|
||||||
|
utility::LittleFloat(vec.vec[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
((float*)(m_data + m_position))[0] = vec.vec[0];
|
||||||
|
((float*)(m_data + m_position))[1] = vec.vec[1];
|
||||||
|
((float*)(m_data + m_position))[2] = vec.vec[2];
|
||||||
|
((float*)(m_data + m_position))[3] = vec.vec[3];
|
||||||
|
m_position += 16;
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryWriter::writeUnicode(const std::string& str)
|
void MemoryWriter::writeUnicode(const std::string& str)
|
||||||
{
|
{
|
||||||
std::string tmpStr = "\xEF\xBB\xBF" + str;
|
std::string tmpStr = "\xEF\xBB\xBF" + str;
|
||||||
|
@ -473,6 +527,19 @@ void MemoryWriter::writeString(const std::string& str)
|
||||||
writeUByte(0);
|
writeUByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MemoryWriter::writeWString(const std::wstring& str)
|
||||||
|
{
|
||||||
|
for (atUint16 c : str)
|
||||||
|
{
|
||||||
|
writeUint16(c);
|
||||||
|
|
||||||
|
if (c == L'\0')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeUint16(0);
|
||||||
|
}
|
||||||
|
|
||||||
void MemoryWriter::fill(atUint8 val, atUint64 length)
|
void MemoryWriter::fill(atUint8 val, atUint64 length)
|
||||||
{
|
{
|
||||||
while ((length--) > 0)
|
while ((length--) > 0)
|
||||||
|
|
|
@ -1,19 +1,4 @@
|
||||||
// This file is part of libAthena.
|
#include "Athena/Utility.hpp"
|
||||||
//
|
|
||||||
// libAthena is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// libAthena is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with libAthena. If not, see <http://www.gnu.org/licenses/>
|
|
||||||
|
|
||||||
#include "Athena/Utility.hpp"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
Loading…
Reference in New Issue