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_YAML_READER "__dna_docin"
|
||||
#define ATHENA_YAML_WRITER "__dna_docout"
|
||||
#define ATHENA_SZ_ENUMERATE "__EnumerateSize"
|
||||
|
||||
#ifndef INSTALL_PREFIX
|
||||
#define INSTALL_PREFIX /usr/local
|
||||
|
@ -130,6 +131,70 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
|||
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,
|
||||
const std::string& fieldName, bool writerPass,
|
||||
const std::string& funcPrefix, bool& isDNATypeOut)
|
||||
|
@ -630,6 +695,356 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
|
|||
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)
|
||||
{
|
||||
/* Two passes - read then write */
|
||||
|
@ -1789,6 +2204,7 @@ public:
|
|||
emitIOFuncs(decl, baseDNA);
|
||||
if (isYAML)
|
||||
emitYAMLFuncs(decl, baseDNA);
|
||||
emitSizeFuncs(decl, baseDNA);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ struct WStringAsString;
|
|||
template <Endian DNAE>
|
||||
struct DNA
|
||||
{
|
||||
virtual ~DNA() {}
|
||||
|
||||
/**
|
||||
* @brief Common virtual read function for all DNA types
|
||||
*/
|
||||
|
@ -52,6 +54,12 @@ struct DNA
|
|||
* @brief Common virtual write function for all DNA types
|
||||
*/
|
||||
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
|
||||
|
@ -121,6 +129,20 @@ struct DNA
|
|||
* @brief Meta Template preventing atdna from emitting read/write implementations
|
||||
*/
|
||||
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[]>
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{
|
||||
reset(new atUint8[sizeVar]);
|
||||
reader.readUBytesToBuf(get(), sizeVar);
|
||||
}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{
|
||||
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
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{this->assign(std::move(reader.readString(sizeVar)));}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{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);}
|
||||
inline std::string& operator=(std::string&& __str)
|
||||
std::string& operator=(std::string&& __str)
|
||||
{this->swap(__str); return *this;}
|
||||
};
|
||||
|
||||
|
@ -165,19 +193,21 @@ template <atInt32 sizeVar, Endian VE>
|
|||
struct WString : public DNA<VE>, public std::wstring
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{
|
||||
reader.setEndian(VE);
|
||||
this->assign(std::move(reader.readWString(sizeVar)));
|
||||
}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{
|
||||
writer.setEndian(VE);
|
||||
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);}
|
||||
inline std::wstring& operator=(std::wstring&& __str)
|
||||
std::wstring& operator=(std::wstring&& __str)
|
||||
{this->swap(__str); return *this;}
|
||||
};
|
||||
|
||||
|
@ -188,13 +218,15 @@ template <atInt32 sizeVar, Endian VE>
|
|||
struct WStringAsString : public DNA<VE>, public std::string
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{*this = reader.readWStringAsString(sizeVar);}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{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);}
|
||||
inline std::string& operator=(std::string&& __str)
|
||||
std::string& operator=(std::string&& __str)
|
||||
{this->swap(__str); return *this;}
|
||||
};
|
||||
|
||||
|
@ -202,11 +234,13 @@ struct WStringAsString : public DNA<VE>, public std::string
|
|||
#define DECL_DNA \
|
||||
void read(Athena::io::IStreamReader&); \
|
||||
void write(Athena::io::IStreamWriter&) const; \
|
||||
size_t binarySize(size_t __isz) const;
|
||||
|
||||
/** Macro to automatically declare read/write methods and prevent outputting implementation */
|
||||
#define DECL_EXPLICIT_DNA \
|
||||
void read(Athena::io::IStreamReader&); \
|
||||
void write(Athena::io::IStreamWriter&) const; \
|
||||
size_t binarySize(size_t __isz) const; \
|
||||
Delete __dna_delete;
|
||||
|
||||
/** Macro to supply count variable to atdna and mute it for other compilers */
|
||||
|
|
|
@ -1049,6 +1049,8 @@ struct WStringAsStringYaml;
|
|||
template <Endian DNAE>
|
||||
struct DNAYaml : DNA<DNAE>
|
||||
{
|
||||
virtual ~DNAYaml() {}
|
||||
|
||||
virtual void toYAML(YAMLDocWriter& out) const=0;
|
||||
virtual void fromYAML(YAMLDocReader& in)=0;
|
||||
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[]>
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{
|
||||
reset(new atUint8[sizeVar]);
|
||||
reader.readUBytesToBuf(get(), sizeVar);
|
||||
}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{
|
||||
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);}
|
||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
{writer.writeUBytes(nullptr, *this, sizeVar);}
|
||||
};
|
||||
|
||||
|
@ -1249,17 +1255,19 @@ template <atInt32 sizeVar, Endian VE>
|
|||
struct StringYaml : public DNAYaml<VE>, public std::string
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{this->assign(std::move(reader.readString(sizeVar)));}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{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)));}
|
||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
{writer.writeString(nullptr, *this);}
|
||||
inline std::string& operator=(const std::string& __str)
|
||||
std::string& operator=(const std::string& __str)
|
||||
{return this->assign(__str);}
|
||||
inline std::string& operator=(std::string&& __str)
|
||||
std::string& operator=(std::string&& __str)
|
||||
{this->swap(__str); return *this;}
|
||||
};
|
||||
|
||||
|
@ -1267,23 +1275,25 @@ template <atInt32 sizeVar, Endian VE>
|
|||
struct WStringYaml : public DNAYaml<VE>, public std::wstring
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{
|
||||
reader.setEndian(VE);
|
||||
this->assign(std::move(reader.readWString(sizeVar)));
|
||||
}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{
|
||||
writer.setEndian(VE);
|
||||
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)));}
|
||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
{writer.writeWString(nullptr, *this);}
|
||||
inline std::wstring& operator=(const std::wstring& __str)
|
||||
std::wstring& operator=(const std::wstring& __str)
|
||||
{return this->assign(__str);}
|
||||
inline std::wstring& operator=(std::wstring&& __str)
|
||||
std::wstring& operator=(std::wstring&& __str)
|
||||
{this->swap(__str); return *this;}
|
||||
};
|
||||
|
||||
|
@ -1291,17 +1301,19 @@ template <atInt32 sizeVar, Endian VE>
|
|||
struct WStringAsStringYaml : public DNAYaml<VE>, public std::string
|
||||
{
|
||||
typename DNA<VE>::Delete expl;
|
||||
inline void read(IStreamReader& reader)
|
||||
void read(IStreamReader& reader)
|
||||
{*this = reader.readWStringAsString(sizeVar);}
|
||||
inline void write(IStreamWriter& writer) const
|
||||
void write(IStreamWriter& writer) const
|
||||
{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)));}
|
||||
inline void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
void toYAML(Athena::io::YAMLDocWriter& writer) const
|
||||
{writer.writeString(nullptr, *this);}
|
||||
inline std::string& operator=(const std::string& __str)
|
||||
std::string& operator=(const std::string& __str)
|
||||
{return this->assign(__str);}
|
||||
inline std::string& operator=(std::string&& __str)
|
||||
std::string& operator=(std::string&& __str)
|
||||
{this->swap(__str); return *this;}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue