mirror of https://github.com/libAthena/athena.git
Merge pull request #38 from libAthena/binary-size
Added binarySize method for DNA
This commit is contained in:
commit
e861691480
416
atdna/main.cpp
416
atdna/main.cpp
|
@ -21,6 +21,7 @@ static unsigned AthenaError = 0;
|
||||||
#define ATHENA_DNA_WRITER "__dna_writer"
|
#define ATHENA_DNA_WRITER "__dna_writer"
|
||||||
#define ATHENA_YAML_READER "__dna_docin"
|
#define ATHENA_YAML_READER "__dna_docin"
|
||||||
#define ATHENA_YAML_WRITER "__dna_docout"
|
#define ATHENA_YAML_WRITER "__dna_docout"
|
||||||
|
#define ATHENA_SZ_ENUMERATE "__EnumerateSize"
|
||||||
|
|
||||||
#ifndef INSTALL_PREFIX
|
#ifndef INSTALL_PREFIX
|
||||||
#define INSTALL_PREFIX /usr/local
|
#define INSTALL_PREFIX /usr/local
|
||||||
|
@ -130,6 +131,70 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int64_t GetSizeValue(const clang::Type* theType, unsigned width)
|
||||||
|
{
|
||||||
|
if (theType->isEnumeralType())
|
||||||
|
{
|
||||||
|
clang::EnumType* eType = (clang::EnumType*)theType;
|
||||||
|
clang::EnumDecl* eDecl = eType->getDecl();
|
||||||
|
theType = eDecl->getIntegerType().getCanonicalType().getTypePtr();
|
||||||
|
|
||||||
|
const clang::BuiltinType* bType = (clang::BuiltinType*)theType;
|
||||||
|
if (bType->isBooleanType())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (bType->isUnsignedInteger() || bType->isSignedInteger())
|
||||||
|
{
|
||||||
|
return width / 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (theType->isBuiltinType())
|
||||||
|
{
|
||||||
|
const clang::BuiltinType* bType = (clang::BuiltinType*)theType;
|
||||||
|
if (bType->isBooleanType())
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (bType->isUnsignedInteger() || bType->isSignedInteger() || bType->isFloatingPoint())
|
||||||
|
{
|
||||||
|
return width / 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (theType->isRecordType())
|
||||||
|
{
|
||||||
|
const clang::CXXRecordDecl* rDecl = theType->getAsCXXRecordDecl();
|
||||||
|
for (const clang::FieldDecl* field : rDecl->fields())
|
||||||
|
{
|
||||||
|
if (!field->getName().compare("clangVec"))
|
||||||
|
{
|
||||||
|
const clang::VectorType* vType = (clang::VectorType*)field->getType().getTypePtr();
|
||||||
|
if (vType->isVectorType())
|
||||||
|
{
|
||||||
|
const clang::BuiltinType* eType = (clang::BuiltinType*)vType->getElementType().getTypePtr();
|
||||||
|
const uint64_t width = context.getTypeInfo(eType).Width;
|
||||||
|
if (!eType->isBuiltinType() || !eType->isFloatingPoint() ||
|
||||||
|
(width != 32 && width != 64))
|
||||||
|
continue;
|
||||||
|
if (vType->getNumElements() == 2)
|
||||||
|
{
|
||||||
|
return width / 8 * 2;
|
||||||
|
}
|
||||||
|
else if (vType->getNumElements() == 3)
|
||||||
|
{
|
||||||
|
return width / 8 * 3;
|
||||||
|
}
|
||||||
|
else if (vType->getNumElements() == 4)
|
||||||
|
{
|
||||||
|
return width / 8 * 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetOpString(const clang::Type* theType, unsigned width,
|
std::string GetOpString(const clang::Type* theType, unsigned width,
|
||||||
const std::string& fieldName, bool writerPass,
|
const std::string& fieldName, bool writerPass,
|
||||||
const std::string& funcPrefix, bool& isDNATypeOut)
|
const std::string& funcPrefix, bool& isDNATypeOut)
|
||||||
|
@ -630,6 +695,356 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emitSizeFuncs(clang::CXXRecordDecl* decl, const std::string& baseDNA)
|
||||||
|
{
|
||||||
|
int64_t podTotal = 0;
|
||||||
|
fileOut << "size_t " << decl->getQualifiedNameAsString() << "::binarySize(size_t __isz) const\n{\n";
|
||||||
|
|
||||||
|
if (baseDNA.size())
|
||||||
|
{
|
||||||
|
fileOut << " __isz = " << baseDNA << "::binarySize(__isz);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const clang::FieldDecl* field : decl->fields())
|
||||||
|
{
|
||||||
|
clang::QualType qualType = field->getType();
|
||||||
|
clang::TypeInfo regTypeInfo = context.getTypeInfo(qualType);
|
||||||
|
const clang::Type* regType = qualType.getTypePtrOrNull();
|
||||||
|
while (regType->getTypeClass() == clang::Type::Elaborated ||
|
||||||
|
regType->getTypeClass() == clang::Type::Typedef)
|
||||||
|
regType = regType->getUnqualifiedDesugaredType();
|
||||||
|
|
||||||
|
/* Resolve constant array */
|
||||||
|
size_t arraySize = 1;
|
||||||
|
bool isArray = false;
|
||||||
|
if (regType->getTypeClass() == clang::Type::ConstantArray)
|
||||||
|
{
|
||||||
|
isArray = true;
|
||||||
|
const clang::ConstantArrayType* caType = (clang::ConstantArrayType*)regType;
|
||||||
|
arraySize = caType->getSize().getZExtValue();
|
||||||
|
qualType = caType->getElementType();
|
||||||
|
regTypeInfo = context.getTypeInfo(qualType);
|
||||||
|
regType = qualType.getTypePtrOrNull();
|
||||||
|
if (regType->getTypeClass() == clang::Type::Elaborated)
|
||||||
|
regType = regType->getUnqualifiedDesugaredType();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int e=0 ; e<arraySize ; ++e)
|
||||||
|
{
|
||||||
|
std::string fieldName;
|
||||||
|
if (isArray)
|
||||||
|
{
|
||||||
|
char subscript[16];
|
||||||
|
snprintf(subscript, 16, "[%d]", e);
|
||||||
|
fieldName = field->getName().str() + subscript;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fieldName = field->getName();
|
||||||
|
|
||||||
|
if (regType->getTypeClass() == clang::Type::TemplateSpecialization)
|
||||||
|
{
|
||||||
|
const clang::TemplateSpecializationType* tsType = (const clang::TemplateSpecializationType*)regType;
|
||||||
|
const clang::TemplateDecl* tsDecl = tsType->getTemplateName().getAsTemplateDecl();
|
||||||
|
|
||||||
|
if (!tsDecl->getName().compare("Value"))
|
||||||
|
{
|
||||||
|
clang::QualType templateType;
|
||||||
|
const clang::TemplateArgument* typeArg = nullptr;
|
||||||
|
size_t typeSize = 0;
|
||||||
|
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();
|
||||||
|
typeSize = GetSizeValue(type, regTypeInfo.Width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeSize)
|
||||||
|
podTotal += typeSize;
|
||||||
|
else
|
||||||
|
fileOut << " __isz = " << fieldName << ".binarySize(__isz);\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().compare("Vector"))
|
||||||
|
{
|
||||||
|
clang::QualType templateType;
|
||||||
|
const clang::TemplateArgument* typeArg = nullptr;
|
||||||
|
size_t typeSize = 0;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Type)
|
||||||
|
{
|
||||||
|
typeArg = &arg;
|
||||||
|
templateType = arg.getAsType().getCanonicalType();
|
||||||
|
clang::TypeInfo typeInfo = context.getTypeInfo(templateType);
|
||||||
|
typeSize = GetSizeValue(templateType.getTypePtr(), typeInfo.Width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeSize)
|
||||||
|
fileOut << " __isz += " << fieldName << ".size() * " << typeSize << ";\n";
|
||||||
|
else
|
||||||
|
fileOut << " __isz = " ATHENA_SZ_ENUMERATE "(__isz, " << fieldName << ");\n";
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().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()->IgnoreImpCasts();
|
||||||
|
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();
|
||||||
|
sizeExpr = argExpr;
|
||||||
|
llvm::raw_string_ostream strStream(sizeExprStr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fileOut << " __isz += (" << sizeExprStr << ");\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().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()->IgnoreImpCasts();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeExprStr.size())
|
||||||
|
fileOut << " __isz += (" << sizeExprStr << ");\n";
|
||||||
|
else
|
||||||
|
fileOut << " __isz += " << fieldName << ".size() + 1;\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().compare("WString"))
|
||||||
|
{
|
||||||
|
const clang::Expr* sizeExpr = nullptr;
|
||||||
|
std::string sizeExprStr;
|
||||||
|
size_t idx = 0;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
llvm::APSInt sizeLiteral;
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
||||||
|
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 (sizeExprStr.size())
|
||||||
|
fileOut << " __isz += (" << sizeExprStr << ") * 2;\n";
|
||||||
|
else
|
||||||
|
fileOut << " __isz += (" << fieldName << ".size() + 1) * 2;\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().compare("WStringAsString"))
|
||||||
|
{
|
||||||
|
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()->IgnoreImpCasts();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sizeExprStr.size())
|
||||||
|
fileOut << " __isz += (" << sizeExprStr << ") * 2;\n";
|
||||||
|
else
|
||||||
|
fileOut << " __isz += (" << fieldName << ".size() + 1) * 2;\n";
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().compare("Seek"))
|
||||||
|
{
|
||||||
|
size_t idx = 0;
|
||||||
|
const clang::Expr* offsetExpr = nullptr;
|
||||||
|
std::string offsetExprStr;
|
||||||
|
llvm::APSInt direction(64, 0);
|
||||||
|
const clang::Expr* directionExpr = nullptr;
|
||||||
|
bool bad = false;
|
||||||
|
int64_t literal = 0;
|
||||||
|
for (const clang::TemplateArgument& arg : *tsType)
|
||||||
|
{
|
||||||
|
if (arg.getKind() == clang::TemplateArgument::Expression)
|
||||||
|
{
|
||||||
|
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
|
||||||
|
if (!idx)
|
||||||
|
{
|
||||||
|
offsetExpr = expr;
|
||||||
|
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
|
||||||
|
llvm::APSInt offsetLiteral;
|
||||||
|
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();
|
||||||
|
offsetExpr = argExpr;
|
||||||
|
llvm::raw_string_ostream strStream(offsetExprStr);
|
||||||
|
argExpr->printPretty(strStream, nullptr, context.getPrintingPolicy());
|
||||||
|
}
|
||||||
|
else if (expr->isIntegerConstantExpr(offsetLiteral, context))
|
||||||
|
{
|
||||||
|
literal = offsetLiteral.getSExtValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
directionExpr = expr;
|
||||||
|
if (!expr->isIntegerConstantExpr(direction, context))
|
||||||
|
{
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
if (bad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int64_t directionVal = direction.getSExtValue();
|
||||||
|
|
||||||
|
if (literal)
|
||||||
|
{
|
||||||
|
if (directionVal == 0)
|
||||||
|
{
|
||||||
|
podTotal = 0;
|
||||||
|
fileOut << " __isz = " << literal << ";\n";
|
||||||
|
}
|
||||||
|
else if (directionVal == 1)
|
||||||
|
podTotal += literal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (directionVal == 0)
|
||||||
|
{
|
||||||
|
podTotal = 0;
|
||||||
|
fileOut << " __isz = (" << offsetExprStr << ");\n";
|
||||||
|
}
|
||||||
|
else if (directionVal == 1)
|
||||||
|
fileOut << " __isz += (" << offsetExprStr << ");\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (!tsDecl->getName().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))
|
||||||
|
{
|
||||||
|
bad = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bad)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int64_t alignVal = align.getSExtValue();
|
||||||
|
if (alignVal)
|
||||||
|
{
|
||||||
|
fileOut << " __isz += " << podTotal << ";\n";
|
||||||
|
podTotal = 0;
|
||||||
|
if (align.isPowerOf2())
|
||||||
|
fileOut << " __isz = (__isz + " << alignVal-1 << ") & ~" << alignVal-1 << ";\n";
|
||||||
|
else
|
||||||
|
fileOut << " __isz = (__isz + " << alignVal-1 << ") / " << alignVal << " * " << alignVal << ";\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (regType->getTypeClass() == clang::Type::Record)
|
||||||
|
{
|
||||||
|
const clang::CXXRecordDecl* cxxRDecl = regType->getAsCXXRecordDecl();
|
||||||
|
std::string baseDNA;
|
||||||
|
bool isYAML = false;
|
||||||
|
if (cxxRDecl && isDNARecord(cxxRDecl, baseDNA, isYAML))
|
||||||
|
{
|
||||||
|
fileOut << " __isz = " << fieldName << ".binarySize(__isz);\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (podTotal)
|
||||||
|
fileOut << " return __isz + " << podTotal << ";\n}\n\n";
|
||||||
|
else
|
||||||
|
fileOut << " return __isz;\n}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
void emitIOFuncs(clang::CXXRecordDecl* decl, const std::string& baseDNA)
|
void emitIOFuncs(clang::CXXRecordDecl* decl, const std::string& baseDNA)
|
||||||
{
|
{
|
||||||
/* Two passes - read then write */
|
/* Two passes - read then write */
|
||||||
|
@ -1789,6 +2204,7 @@ public:
|
||||||
emitIOFuncs(decl, baseDNA);
|
emitIOFuncs(decl, baseDNA);
|
||||||
if (isYAML)
|
if (isYAML)
|
||||||
emitYAMLFuncs(decl, baseDNA);
|
emitYAMLFuncs(decl, baseDNA);
|
||||||
|
emitSizeFuncs(decl, baseDNA);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,8 @@ struct WStringAsString;
|
||||||
template <Endian DNAE>
|
template <Endian DNAE>
|
||||||
struct DNA
|
struct DNA
|
||||||
{
|
{
|
||||||
|
virtual ~DNA() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Common virtual read function for all DNA types
|
* @brief Common virtual read function for all DNA types
|
||||||
*/
|
*/
|
||||||
|
@ -52,6 +54,12 @@ struct DNA
|
||||||
* @brief Common virtual write function for all DNA types
|
* @brief Common virtual write function for all DNA types
|
||||||
*/
|
*/
|
||||||
virtual void write(IStreamWriter&) const=0;
|
virtual void write(IStreamWriter&) const=0;
|
||||||
|
/**
|
||||||
|
* @brief Common virtual binary size computation for all DNA types
|
||||||
|
* @param __isz initial cumulative value to add result to
|
||||||
|
* @return Cumulative size
|
||||||
|
*/
|
||||||
|
virtual size_t binarySize(size_t __isz) const=0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Template type signaling atdna to capture the value where it's used
|
* @brief Template type signaling atdna to capture the value where it's used
|
||||||
|
@ -121,6 +129,20 @@ struct DNA
|
||||||
* @brief Meta Template preventing atdna from emitting read/write implementations
|
* @brief Meta Template preventing atdna from emitting read/write implementations
|
||||||
*/
|
*/
|
||||||
struct Delete {};
|
struct Delete {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Internal DNA helper for accumulating binarySize
|
||||||
|
* @param __isz initial size value
|
||||||
|
* @param v Vector to enumerate
|
||||||
|
* @return Cumulative total
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
static size_t __EnumerateSize(size_t __isz, const T& v)
|
||||||
|
{
|
||||||
|
for (const auto& val : v)
|
||||||
|
__isz = val.binarySize(__isz);
|
||||||
|
return __isz;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,15 +152,19 @@ template <size_t sizeVar, Endian VE>
|
||||||
struct Buffer : public DNA<VE>, public std::unique_ptr<atUint8[]>
|
struct Buffer : public DNA<VE>, public std::unique_ptr<atUint8[]>
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reset(new atUint8[sizeVar]);
|
reset(new atUint8[sizeVar]);
|
||||||
reader.readUBytesToBuf(get(), sizeVar);
|
reader.readUBytesToBuf(get(), sizeVar);
|
||||||
}
|
}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUBytes(get(), sizeVar);
|
writer.writeUBytes(get(), sizeVar);
|
||||||
}
|
}
|
||||||
|
size_t binarySize(size_t __isz) const
|
||||||
|
{
|
||||||
|
return __isz + sizeVar;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,13 +174,15 @@ template <atInt32 sizeVar, Endian VE>
|
||||||
struct String : public DNA<VE>, public std::string
|
struct String : public DNA<VE>, public std::string
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{this->assign(std::move(reader.readString(sizeVar)));}
|
{this->assign(std::move(reader.readString(sizeVar)));}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{writer.writeString(*this, sizeVar);}
|
{writer.writeString(*this, sizeVar);}
|
||||||
inline std::string& operator=(const std::string& __str)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{return __isz + ((sizeVar<0)?(this->size()+1):sizeVar);}
|
||||||
|
std::string& operator=(const std::string& __str)
|
||||||
{return this->assign(__str);}
|
{return this->assign(__str);}
|
||||||
inline std::string& operator=(std::string&& __str)
|
std::string& operator=(std::string&& __str)
|
||||||
{this->swap(__str); return *this;}
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -165,19 +193,21 @@ template <atInt32 sizeVar, Endian VE>
|
||||||
struct WString : public DNA<VE>, public std::wstring
|
struct WString : public DNA<VE>, public std::wstring
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(VE);
|
reader.setEndian(VE);
|
||||||
this->assign(std::move(reader.readWString(sizeVar)));
|
this->assign(std::move(reader.readWString(sizeVar)));
|
||||||
}
|
}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(VE);
|
writer.setEndian(VE);
|
||||||
writer.writeWString(*this, sizeVar);
|
writer.writeWString(*this, sizeVar);
|
||||||
}
|
}
|
||||||
inline std::wstring& operator=(const std::wstring& __str)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{return __isz + (((sizeVar<0)?(this->size()+1):sizeVar)*2);}
|
||||||
|
std::wstring& operator=(const std::wstring& __str)
|
||||||
{return this->assign(__str);}
|
{return this->assign(__str);}
|
||||||
inline std::wstring& operator=(std::wstring&& __str)
|
std::wstring& operator=(std::wstring&& __str)
|
||||||
{this->swap(__str); return *this;}
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,13 +218,15 @@ template <atInt32 sizeVar, Endian VE>
|
||||||
struct WStringAsString : public DNA<VE>, public std::string
|
struct WStringAsString : public DNA<VE>, public std::string
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{*this = reader.readWStringAsString(sizeVar);}
|
{*this = reader.readWStringAsString(sizeVar);}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{writer.writeStringAsWString(*this, sizeVar);}
|
{writer.writeStringAsWString(*this, sizeVar);}
|
||||||
inline std::string& operator=(const std::string& __str)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{return __isz + (((sizeVar<0)?(this->size()+1):sizeVar)*2);}
|
||||||
|
std::string& operator=(const std::string& __str)
|
||||||
{return this->assign(__str);}
|
{return this->assign(__str);}
|
||||||
inline std::string& operator=(std::string&& __str)
|
std::string& operator=(std::string&& __str)
|
||||||
{this->swap(__str); return *this;}
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -202,11 +234,13 @@ struct WStringAsString : public DNA<VE>, public std::string
|
||||||
#define DECL_DNA \
|
#define DECL_DNA \
|
||||||
void read(Athena::io::IStreamReader&); \
|
void read(Athena::io::IStreamReader&); \
|
||||||
void write(Athena::io::IStreamWriter&) const; \
|
void write(Athena::io::IStreamWriter&) const; \
|
||||||
|
size_t binarySize(size_t __isz) const;
|
||||||
|
|
||||||
/** Macro to automatically declare read/write methods and prevent outputting implementation */
|
/** Macro to automatically declare read/write methods and prevent outputting implementation */
|
||||||
#define DECL_EXPLICIT_DNA \
|
#define DECL_EXPLICIT_DNA \
|
||||||
void read(Athena::io::IStreamReader&); \
|
void read(Athena::io::IStreamReader&); \
|
||||||
void write(Athena::io::IStreamWriter&) const; \
|
void write(Athena::io::IStreamWriter&) const; \
|
||||||
|
size_t binarySize(size_t __isz) const; \
|
||||||
Delete __dna_delete;
|
Delete __dna_delete;
|
||||||
|
|
||||||
/** Macro to supply count variable to atdna and mute it for other compilers */
|
/** Macro to supply count variable to atdna and mute it for other compilers */
|
||||||
|
|
|
@ -1049,6 +1049,8 @@ struct WStringAsStringYaml;
|
||||||
template <Endian DNAE>
|
template <Endian DNAE>
|
||||||
struct DNAYaml : DNA<DNAE>
|
struct DNAYaml : DNA<DNAE>
|
||||||
{
|
{
|
||||||
|
virtual ~DNAYaml() {}
|
||||||
|
|
||||||
virtual void toYAML(YAMLDocWriter& out) const=0;
|
virtual void toYAML(YAMLDocWriter& out) const=0;
|
||||||
virtual void fromYAML(YAMLDocReader& in)=0;
|
virtual void fromYAML(YAMLDocReader& in)=0;
|
||||||
static const char* DNAType() {return nullptr;}
|
static const char* DNAType() {return nullptr;}
|
||||||
|
@ -1230,18 +1232,22 @@ template <size_t sizeVar, Endian VE>
|
||||||
struct BufferYaml : public DNAYaml<VE>, public std::unique_ptr<atUint8[]>
|
struct BufferYaml : public DNAYaml<VE>, public std::unique_ptr<atUint8[]>
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reset(new atUint8[sizeVar]);
|
reset(new atUint8[sizeVar]);
|
||||||
reader.readUBytesToBuf(get(), sizeVar);
|
reader.readUBytesToBuf(get(), sizeVar);
|
||||||
}
|
}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.writeUBytes(get(), sizeVar);
|
writer.writeUBytes(get(), sizeVar);
|
||||||
}
|
}
|
||||||
inline void fromYAML(Athena::io::YAMLDocReader& reader)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{
|
||||||
|
return __isz + sizeVar;
|
||||||
|
}
|
||||||
|
void fromYAML(Athena::io::YAMLDocReader& reader)
|
||||||
{*this = reader.readUBytes(nullptr);}
|
{*this = reader.readUBytes(nullptr);}
|
||||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||||
{writer.writeUBytes(nullptr, *this, sizeVar);}
|
{writer.writeUBytes(nullptr, *this, sizeVar);}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1249,17 +1255,19 @@ template <atInt32 sizeVar, Endian VE>
|
||||||
struct StringYaml : public DNAYaml<VE>, public std::string
|
struct StringYaml : public DNAYaml<VE>, public std::string
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{this->assign(std::move(reader.readString(sizeVar)));}
|
{this->assign(std::move(reader.readString(sizeVar)));}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{writer.writeString(*this, sizeVar);}
|
{writer.writeString(*this, sizeVar);}
|
||||||
inline void fromYAML(Athena::io::YAMLDocReader& reader)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{return __isz + ((sizeVar<0)?(this->size()+1):sizeVar);}
|
||||||
|
void fromYAML(Athena::io::YAMLDocReader& reader)
|
||||||
{this->assign(std::move(reader.readString(nullptr)));}
|
{this->assign(std::move(reader.readString(nullptr)));}
|
||||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||||
{writer.writeString(nullptr, *this);}
|
{writer.writeString(nullptr, *this);}
|
||||||
inline std::string& operator=(const std::string& __str)
|
std::string& operator=(const std::string& __str)
|
||||||
{return this->assign(__str);}
|
{return this->assign(__str);}
|
||||||
inline std::string& operator=(std::string&& __str)
|
std::string& operator=(std::string&& __str)
|
||||||
{this->swap(__str); return *this;}
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1267,23 +1275,25 @@ template <atInt32 sizeVar, Endian VE>
|
||||||
struct WStringYaml : public DNAYaml<VE>, public std::wstring
|
struct WStringYaml : public DNAYaml<VE>, public std::wstring
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{
|
{
|
||||||
reader.setEndian(VE);
|
reader.setEndian(VE);
|
||||||
this->assign(std::move(reader.readWString(sizeVar)));
|
this->assign(std::move(reader.readWString(sizeVar)));
|
||||||
}
|
}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
writer.setEndian(VE);
|
writer.setEndian(VE);
|
||||||
writer.writeWString(*this, sizeVar);
|
writer.writeWString(*this, sizeVar);
|
||||||
}
|
}
|
||||||
inline void fromYAML(Athena::io::YAMLDocReader& reader)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{return __isz + (((sizeVar<0)?(this->size()+1):sizeVar)*2);}
|
||||||
|
void fromYAML(Athena::io::YAMLDocReader& reader)
|
||||||
{this->assign(std::move(reader.readWString(nullptr)));}
|
{this->assign(std::move(reader.readWString(nullptr)));}
|
||||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||||
{writer.writeWString(nullptr, *this);}
|
{writer.writeWString(nullptr, *this);}
|
||||||
inline std::wstring& operator=(const std::wstring& __str)
|
std::wstring& operator=(const std::wstring& __str)
|
||||||
{return this->assign(__str);}
|
{return this->assign(__str);}
|
||||||
inline std::wstring& operator=(std::wstring&& __str)
|
std::wstring& operator=(std::wstring&& __str)
|
||||||
{this->swap(__str); return *this;}
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1291,17 +1301,19 @@ template <atInt32 sizeVar, Endian VE>
|
||||||
struct WStringAsStringYaml : public DNAYaml<VE>, public std::string
|
struct WStringAsStringYaml : public DNAYaml<VE>, public std::string
|
||||||
{
|
{
|
||||||
typename DNA<VE>::Delete expl;
|
typename DNA<VE>::Delete expl;
|
||||||
inline void read(IStreamReader& reader)
|
void read(IStreamReader& reader)
|
||||||
{*this = reader.readWStringAsString(sizeVar);}
|
{*this = reader.readWStringAsString(sizeVar);}
|
||||||
inline void write(IStreamWriter& writer) const
|
void write(IStreamWriter& writer) const
|
||||||
{writer.writeStringAsWString(*this, sizeVar);}
|
{writer.writeStringAsWString(*this, sizeVar);}
|
||||||
inline void fromYAML(Athena::io::YAMLDocReader& reader)
|
size_t binarySize(size_t __isz) const
|
||||||
|
{return __isz + (((sizeVar<0)?(this->size()+1):sizeVar)*2);}
|
||||||
|
void fromYAML(Athena::io::YAMLDocReader& reader)
|
||||||
{this->assign(std::move(reader.readString(nullptr)));}
|
{this->assign(std::move(reader.readString(nullptr)));}
|
||||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||||
{writer.writeString(nullptr, *this);}
|
{writer.writeString(nullptr, *this);}
|
||||||
inline std::string& operator=(const std::string& __str)
|
std::string& operator=(const std::string& __str)
|
||||||
{return this->assign(__str);}
|
{return this->assign(__str);}
|
||||||
inline std::string& operator=(std::string&& __str)
|
std::string& operator=(std::string&& __str)
|
||||||
{this->swap(__str); return *this;}
|
{this->swap(__str); return *this;}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue