Merge pull request #27 from libAthena/explicit-endian

Added explicit Big/Little method suffix
This commit is contained in:
Jack Andersen 2015-08-13 17:10:56 -10:00
commit 776d52e4e5
4 changed files with 802 additions and 92 deletions

View File

@ -123,7 +123,7 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
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,
bool& isDNATypeOut) const std::string& funcPrefix, bool& isDNATypeOut)
{ {
isDNATypeOut = false; isDNATypeOut = false;
if (writerPass) if (writerPass)
@ -140,29 +140,29 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
if (width == 8) if (width == 8)
return ATHENA_DNA_WRITER ".writeUByte(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeUByte(" + fieldName + ");";
else if (width == 16) else if (width == 16)
return ATHENA_DNA_WRITER ".writeUint16(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeUint16" + funcPrefix + "(" + fieldName + ");";
else if (width == 32) else if (width == 32)
return ATHENA_DNA_WRITER ".writeUint32(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeUint32" + funcPrefix + "(" + fieldName + ");";
else if (width == 64) else if (width == 64)
return ATHENA_DNA_WRITER ".writeUint64(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeUint64" + funcPrefix + "(" + fieldName + ");";
} }
else if (bType->isSignedInteger()) else if (bType->isSignedInteger())
{ {
if (width == 8) if (width == 8)
return ATHENA_DNA_WRITER ".writeByte(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeByte(" + fieldName + ");";
else if (width == 16) else if (width == 16)
return ATHENA_DNA_WRITER ".writeInt16(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeInt16" + funcPrefix + "(" + fieldName + ");";
else if (width == 32) else if (width == 32)
return ATHENA_DNA_WRITER ".writeInt32(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeInt32" + funcPrefix + "(" + fieldName + ");";
else if (width == 64) else if (width == 64)
return ATHENA_DNA_WRITER ".writeInt64(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeInt64" + funcPrefix + "(" + fieldName + ");";
} }
else if (bType->isFloatingPoint()) else if (bType->isFloatingPoint())
{ {
if (width == 32) if (width == 32)
return ATHENA_DNA_WRITER ".writeFloat(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeFloat" + funcPrefix + "(" + fieldName + ");";
else if (width == 64) else if (width == 64)
return ATHENA_DNA_WRITER ".writeDouble(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeDouble" + funcPrefix + "(" + fieldName + ");";
} }
} }
else if (theType->isRecordType()) else if (theType->isRecordType())
@ -180,11 +180,11 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
context.getTypeInfo(eType).Width != 32) context.getTypeInfo(eType).Width != 32)
continue; continue;
if (vType->getNumElements() == 2) if (vType->getNumElements() == 2)
return ATHENA_DNA_WRITER ".writeVec2f(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeVec2f" + funcPrefix + "(" + fieldName + ");";
else if (vType->getNumElements() == 3) else if (vType->getNumElements() == 3)
return ATHENA_DNA_WRITER ".writeVec3f(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeVec3f" + funcPrefix + "(" + fieldName + ");";
else if (vType->getNumElements() == 4) else if (vType->getNumElements() == 4)
return ATHENA_DNA_WRITER ".writeVec4f(" + fieldName + ");"; return ATHENA_DNA_WRITER ".writeVec4f" + funcPrefix + "(" + fieldName + ");";
} }
} }
} }
@ -211,29 +211,29 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
if (width == 8) if (width == 8)
return ATHENA_DNA_READER ".readUByte()"; return ATHENA_DNA_READER ".readUByte()";
else if (width == 16) else if (width == 16)
return ATHENA_DNA_READER ".readUint16()"; return ATHENA_DNA_READER ".readUint16" + funcPrefix + "()";
else if (width == 32) else if (width == 32)
return ATHENA_DNA_READER ".readUint32()"; return ATHENA_DNA_READER ".readUint32" + funcPrefix + "()";
else if (width == 64) else if (width == 64)
return ATHENA_DNA_READER ".readUint64()"; return ATHENA_DNA_READER ".readUint64" + funcPrefix + "()";
} }
else if (bType->isSignedInteger()) else if (bType->isSignedInteger())
{ {
if (width == 8) if (width == 8)
return ATHENA_DNA_READER ".readByte()"; return ATHENA_DNA_READER ".readByte()";
else if (width == 16) else if (width == 16)
return ATHENA_DNA_READER ".readInt16()"; return ATHENA_DNA_READER ".readInt16" + funcPrefix + "()";
else if (width == 32) else if (width == 32)
return ATHENA_DNA_READER ".readInt32()"; return ATHENA_DNA_READER ".readInt32" + funcPrefix + "()";
else if (width == 64) else if (width == 64)
return ATHENA_DNA_READER ".readInt64()"; return ATHENA_DNA_READER ".readInt64" + funcPrefix + "()";
} }
else if (bType->isFloatingPoint()) else if (bType->isFloatingPoint())
{ {
if (width == 32) if (width == 32)
return ATHENA_DNA_READER ".readFloat()"; return ATHENA_DNA_READER ".readFloat" + funcPrefix + "()";
else if (width == 64) else if (width == 64)
return ATHENA_DNA_READER ".readDouble()"; return ATHENA_DNA_READER ".readDouble" + funcPrefix + "()";
} }
} }
else if (theType->isRecordType()) else if (theType->isRecordType())
@ -251,11 +251,11 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
context.getTypeInfo(eType).Width != 32) context.getTypeInfo(eType).Width != 32)
continue; continue;
if (vType->getNumElements() == 2) if (vType->getNumElements() == 2)
return ATHENA_DNA_READER ".readVec2f()"; return ATHENA_DNA_READER ".readVec2f" + funcPrefix + "()";
else if (vType->getNumElements() == 3) else if (vType->getNumElements() == 3)
return ATHENA_DNA_READER ".readVec3f()"; return ATHENA_DNA_READER ".readVec3f" + funcPrefix + "()";
else if (vType->getNumElements() == 4) else if (vType->getNumElements() == 4)
return ATHENA_DNA_READER ".readVec4f()"; return ATHENA_DNA_READER ".readVec4f" + funcPrefix + "()";
} }
} }
} }
@ -430,7 +430,6 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
fileOut << "void " << decl->getQualifiedNameAsString() << "::write(Athena::io::IStreamWriter& " ATHENA_DNA_WRITER ") const\n{\n"; fileOut << "void " << decl->getQualifiedNameAsString() << "::write(Athena::io::IStreamWriter& " ATHENA_DNA_WRITER ") const\n{\n";
else else
fileOut << "void " << decl->getQualifiedNameAsString() << "::read(Athena::io::IStreamReader& " ATHENA_DNA_READER ")\n{\n"; fileOut << "void " << decl->getQualifiedNameAsString() << "::read(Athena::io::IStreamReader& " ATHENA_DNA_READER ")\n{\n";
int currentEndian = -1;
if (baseDNA.size()) if (baseDNA.size())
{ {
@ -445,7 +444,8 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
clang::QualType qualType = field->getType(); clang::QualType qualType = field->getType();
clang::TypeInfo regTypeInfo = context.getTypeInfo(qualType); clang::TypeInfo regTypeInfo = context.getTypeInfo(qualType);
const clang::Type* regType = qualType.getTypePtrOrNull(); const clang::Type* regType = qualType.getTypePtrOrNull();
if (regType->getTypeClass() == clang::Type::Elaborated) while (regType->getTypeClass() == clang::Type::Elaborated ||
regType->getTypeClass() == clang::Type::Typedef)
regType = regType->getUnqualifiedDesugaredType(); regType = regType->getUnqualifiedDesugaredType();
/* Resolve constant array */ /* Resolve constant array */
@ -506,24 +506,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
} }
} }
clang::QualType templateType;
std::string ioOp;
bool isDNAType = false;
const clang::TemplateArgument* typeArg = nullptr;
for (const clang::TemplateArgument& arg : *tsType) for (const clang::TemplateArgument& arg : *tsType)
{ {
if (arg.getKind() == clang::TemplateArgument::Type) if (arg.getKind() == clang::TemplateArgument::Expression)
{
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(); const clang::Expr* expr = arg.getAsExpr();
endianExpr = expr; endianExpr = expr;
if (expr->isIntegerConstantExpr(endian, context)) if (!expr->isIntegerConstantExpr(endian, context))
{ {
if (!p) if (!p)
{ {
@ -557,6 +546,27 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
continue; continue;
} }
std::string funcPrefix;
if (endianVal == 0)
funcPrefix = "Little";
else if (endianVal == 1)
funcPrefix = "Big";
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, funcPrefix, isDNAType);
}
}
if (ioOp.empty()) if (ioOp.empty())
{ {
if (!p) if (!p)
@ -568,15 +578,6 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
continue; continue;
} }
if (currentEndian != endianVal)
{
if (endianVal == 0)
fileOut << (p ? " " ATHENA_DNA_WRITER ".setEndian(Athena::LittleEndian);\n" : " " ATHENA_DNA_READER ".setEndian(Athena::LittleEndian);\n");
else if (endianVal == 1)
fileOut << (p ? " " ATHENA_DNA_WRITER ".setEndian(Athena::BigEndian);\n" : " " ATHENA_DNA_READER ".setEndian(Athena::BigEndian);\n");
currentEndian = endianVal;
}
fileOut << " /* " << fieldName << " */\n"; fileOut << " /* " << fieldName << " */\n";
if (!p) if (!p)
fileOut << " " << fieldName << " = " << ioOp << ";\n"; fileOut << " " << fieldName << " = " << ioOp << ";\n";
@ -608,25 +609,13 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
} }
} }
clang::QualType templateType;
std::string ioOp;
bool isDNAType = false;
std::string sizeExpr; std::string sizeExpr;
const clang::TemplateArgument* typeArg = nullptr;
const clang::TemplateArgument* sizeArg = nullptr; const clang::TemplateArgument* sizeArg = nullptr;
size_t idx = 0; size_t idx = 0;
bool bad = false; bool bad = false;
for (const clang::TemplateArgument& arg : *tsType) for (const clang::TemplateArgument& arg : *tsType)
{ {
if (arg.getKind() == clang::TemplateArgument::Type) if (arg.getKind() == clang::TemplateArgument::Expression)
{
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()->IgnoreImpCasts(); const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
if (idx == 1) if (idx == 1)
@ -685,6 +674,28 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
continue; continue;
} }
std::string funcPrefix;
if (endianVal == 0)
funcPrefix = "Little";
else if (endianVal == 1)
funcPrefix = "Big";
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();
clang::TypeInfo typeInfo = context.getTypeInfo(templateType);
static const std::string elemStr = "elem";
ioOp = GetOpString(templateType.getTypePtr(), typeInfo.Width, elemStr, p, funcPrefix, isDNAType);
}
}
if (ioOp.empty()) if (ioOp.empty())
{ {
if (!p) if (!p)
@ -707,20 +718,14 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
continue; continue;
} }
if (currentEndian != endianVal) if (isDNAType)
{ funcPrefix.clear();
if (endianVal == 0)
fileOut << (p ? " " ATHENA_DNA_WRITER ".setEndian(Athena::LittleEndian);\n" : " " ATHENA_DNA_READER ".setEndian(Athena::LittleEndian);\n");
else if (endianVal == 1)
fileOut << (p ? " " ATHENA_DNA_WRITER ".setEndian(Athena::BigEndian);\n" : " " ATHENA_DNA_READER ".setEndian(Athena::BigEndian);\n");
currentEndian = endianVal;
}
fileOut << " /* " << fieldName << " */\n"; fileOut << " /* " << fieldName << " */\n";
if (!p) if (!p)
fileOut << " " ATHENA_DNA_READER ".enumerate(" << fieldName << ", " << sizeExpr << ");\n"; fileOut << " " ATHENA_DNA_READER ".enumerate" << funcPrefix << "(" << fieldName << ", " << sizeExpr << ");\n";
else else
fileOut << " " ATHENA_DNA_WRITER ".enumerate(" << fieldName << ");\n"; fileOut << " " ATHENA_DNA_WRITER ".enumerate" << funcPrefix << "(" << fieldName << ");\n";
} }
else if (!tsDecl->getName().compare("Buffer")) else if (!tsDecl->getName().compare("Buffer"))
@ -909,21 +914,18 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
continue; continue;
} }
if (currentEndian != endianVal) std::string funcPrefix;
{ if (endianVal == 0)
if (endianVal == 0) funcPrefix = "Little";
fileOut << (p ? " " ATHENA_DNA_WRITER ".setEndian(Athena::LittleEndian);\n" : " " ATHENA_DNA_READER ".setEndian(Athena::LittleEndian);\n"); else if (endianVal == 1)
else if (endianVal == 1) funcPrefix = "Big";
fileOut << (p ? " " ATHENA_DNA_WRITER ".setEndian(Athena::BigEndian);\n" : " " ATHENA_DNA_READER ".setEndian(Athena::BigEndian);\n");
currentEndian = endianVal;
}
fileOut << " /* " << fieldName << " */\n"; fileOut << " /* " << fieldName << " */\n";
if (!p) if (!p)
fileOut << " " << fieldName << " = " ATHENA_DNA_READER ".readWString(" << sizeExprStr << ");\n"; fileOut << " " << fieldName << " = " ATHENA_DNA_READER ".readWString" << funcPrefix << "(" << sizeExprStr << ");\n";
else else
{ {
fileOut << " " ATHENA_DNA_WRITER ".writeWString(" << fieldName; fileOut << " " ATHENA_DNA_WRITER ".writeWString" << funcPrefix << "(" << fieldName;
if (sizeExprStr.size()) if (sizeExprStr.size())
fileOut << ", " << sizeExprStr; fileOut << ", " << sizeExprStr;
fileOut << ");\n"; fileOut << ");\n";
@ -931,6 +933,29 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
} }
else if (!tsDecl->getName().compare("WStringAsString")) else if (!tsDecl->getName().compare("WStringAsString"))
{ {
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))
{
if (!p)
{
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; const clang::Expr* sizeExpr = nullptr;
std::string sizeExprStr; std::string sizeExprStr;
for (const clang::TemplateArgument& arg : *tsType) for (const clang::TemplateArgument& arg : *tsType)
@ -957,12 +982,40 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
} }
} }
int endianVal = endian.getSExtValue();
if (endianVal != 0 && endianVal != 1)
{
if (!p)
{
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;
}
std::string funcPrefix;
if (endianVal == 0)
funcPrefix = "Little";
else if (endianVal == 1)
funcPrefix = "Big";
fileOut << " /* " << fieldName << " */\n"; fileOut << " /* " << fieldName << " */\n";
if (!p) if (!p)
fileOut << " " << fieldName << " = " ATHENA_DNA_READER ".readWStringAsString(" << sizeExprStr << ");\n"; fileOut << " " << fieldName << " = " ATHENA_DNA_READER ".readWStringAsString" << funcPrefix << "(" << sizeExprStr << ");\n";
else else
{ {
fileOut << " " ATHENA_DNA_WRITER ".writeStringAsWString(" << fieldName; fileOut << " " ATHENA_DNA_WRITER ".writeStringAsWString" << funcPrefix << "(" << fieldName;
if (sizeExprStr.size()) if (sizeExprStr.size())
fileOut << ", " << sizeExprStr; fileOut << ", " << sizeExprStr;
fileOut << ");\n"; fileOut << ");\n";
@ -1131,7 +1184,6 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
{ {
fileOut << " /* " << fieldName << " */\n" fileOut << " /* " << fieldName << " */\n"
" " << fieldName << (p ? ".write(" ATHENA_DNA_WRITER ");\n" : ".read(" ATHENA_DNA_READER ");\n"); " " << fieldName << (p ? ".write(" ATHENA_DNA_WRITER ");\n" : ".read(" ATHENA_DNA_READER ");\n");
currentEndian = -1;
break; break;
} }
} }
@ -1167,7 +1219,8 @@ class ATDNAEmitVisitor : public clang::RecursiveASTVisitor<ATDNAEmitVisitor>
clang::QualType qualType = field->getType(); clang::QualType qualType = field->getType();
clang::TypeInfo regTypeInfo = context.getTypeInfo(qualType); clang::TypeInfo regTypeInfo = context.getTypeInfo(qualType);
const clang::Type* regType = qualType.getTypePtrOrNull(); const clang::Type* regType = qualType.getTypePtrOrNull();
if (regType->getTypeClass() == clang::Type::Elaborated) while (regType->getTypeClass() == clang::Type::Elaborated ||
regType->getTypeClass() == clang::Type::Typedef)
regType = regType->getUnqualifiedDesugaredType(); regType = regType->getUnqualifiedDesugaredType();
/* Resolve constant array */ /* Resolve constant array */

View File

@ -5,7 +5,6 @@ typedef io::DNAYaml<BigEndian> BigDNA;
struct TESTSubFile : public BigDNA struct TESTSubFile : public BigDNA
{ {
DECL_DNA
DECL_YAML DECL_YAML
Value<atUint32> sub1; Value<atUint32> sub1;
Value<atUint32> sub2; Value<atUint32> sub2;
@ -13,7 +12,6 @@ struct TESTSubFile : public BigDNA
struct TESTSubClassFile : public TESTSubFile struct TESTSubClassFile : public TESTSubFile
{ {
DECL_DNA
DECL_YAML DECL_YAML
Value<atUint32> sub3; Value<atUint32> sub3;
Value<atUint32> sub4; Value<atUint32> sub4;
@ -21,7 +19,6 @@ struct TESTSubClassFile : public TESTSubFile
struct TESTSubSubClassFile : public TESTSubClassFile struct TESTSubSubClassFile : public TESTSubClassFile
{ {
DECL_DNA
DECL_YAML DECL_YAML
Value<atUint32> sub5; Value<atUint32> sub5;
Value<atUint32> sub6; Value<atUint32> sub6;
@ -29,7 +26,6 @@ struct TESTSubSubClassFile : public TESTSubClassFile
struct TESTFile : public BigDNA struct TESTFile : public BigDNA
{ {
DECL_DNA
DECL_YAML DECL_YAML
Value<bool> varBool; Value<bool> varBool;
Value<atUint32> var32; Value<atUint32> var32;
@ -39,25 +35,24 @@ struct TESTFile : public BigDNA
struct TESTNestedSubFile : public BigDNA struct TESTNestedSubFile : public BigDNA
{ {
DECL_DNA
DECL_YAML DECL_YAML
Value<atUint32> nestSub1; Value<atUint32> nestSub1;
Value<atUint32> nestSub2; Value<atUint32> nestSub2;
} nestedSubFile; } nestedSubFile;
TESTSubFile subFile; using TESTSubFileUsing = TESTSubFile;
TESTSubFileUsing subFile;
Align<4> align; Align<4> align;
struct TESTExplicitSubFile : public BigDNA struct TESTExplicitSubFile : public BigDNA
{ {
DECL_EXPLICIT_DNA
DECL_YAML DECL_YAML
Value<atUint32> explSub1; Value<atUint32> explSub1;
Value<atUint32> explSub2; Value<atUint32> explSub2;
} explSubFile; } explSubFile;
Value<atUint32> arrCount[2]; Value<atUint32, LittleEndian> arrCount[2];
Vector<atUint32, DNA_COUNT(arrCount[0])> array; Vector<atUint32, DNA_COUNT(arrCount[0])> array;
Seek<21, Current> seek; Seek<21, Current> seek;

View File

@ -135,6 +135,26 @@ public:
inline atInt16 readVal(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0) inline atInt16 readVal(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
{return readInt16();} {return readInt16();}
inline atInt16 readInt16Little()
{
atInt16 val;
readUBytesToBuf(&val, 2);
return utility::LittleInt16(val);
}
template <class T>
inline atInt16 readValLittle(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
{return readInt16Little();}
inline atInt16 readInt16Big()
{
atInt16 val;
readUBytesToBuf(&val, 2);
return utility::BigInt16(val);
}
template <class T>
inline atInt16 readValBig(typename std::enable_if<std::is_same<T, atInt16>::value>::type* = 0)
{return readInt16Big();}
/*! \brief Reads a Uint16 and swaps to proper endianness depending on platform /*! \brief Reads a Uint16 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -149,6 +169,26 @@ public:
inline atUint16 readVal(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0) inline atUint16 readVal(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
{return readUint16();} {return readUint16();}
inline atUint16 readUint16Little()
{
atUint16 val;
readUBytesToBuf(&val, 2);
return utility::LittleUint16(val);
}
template <class T>
inline atUint16 readValLittle(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
{return readUint16Little();}
inline atUint16 readUint16Big()
{
atUint16 val;
readUBytesToBuf(&val, 2);
return utility::BigUint16(val);
}
template <class T>
inline atUint16 readValBig(typename std::enable_if<std::is_same<T, atUint16>::value>::type* = 0)
{return readUint16Big();}
/*! \brief Reads a Int32 and swaps to proper endianness depending on platform /*! \brief Reads a Int32 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -167,6 +207,26 @@ public:
inline atInt32 readVal(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0) inline atInt32 readVal(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
{return readInt32();} {return readInt32();}
inline atInt32 readInt32Little()
{
atInt32 val;
readUBytesToBuf(&val, 4);
return utility::LittleInt32(val);
}
template <class T>
inline atInt32 readValLittle(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
{return readInt32Little();}
inline atInt32 readInt32Big()
{
atInt32 val;
readUBytesToBuf(&val, 4);
return utility::BigInt32(val);
}
template <class T>
inline atInt32 readValBig(typename std::enable_if<std::is_same<T, atInt32>::value>::type* = 0)
{return readInt32Big();}
/*! \brief Reads a Uint32 and swaps to proper endianness depending on platform /*! \brief Reads a Uint32 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -181,6 +241,26 @@ public:
inline atUint32 readVal(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0) inline atUint32 readVal(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
{return readUint32();} {return readUint32();}
inline atUint32 readUint32Little()
{
atUint32 val;
readUBytesToBuf(&val, 4);
return utility::LittleUint32(val);
}
template <class T>
inline atInt32 readValLittle(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
{return readUint32Little();}
inline atUint32 readUint32Big()
{
atUint32 val;
readUBytesToBuf(&val, 4);
return utility::BigUint32(val);
}
template <class T>
inline atUint32 readValBig(typename std::enable_if<std::is_same<T, atUint32>::value>::type* = 0)
{return readUint32Big();}
/*! \brief Reads a Int64 and swaps to proper endianness depending on platform /*! \brief Reads a Int64 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -199,6 +279,26 @@ public:
inline atInt64 readVal(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0) inline atInt64 readVal(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
{return readInt64();} {return readInt64();}
inline atInt64 readInt64Little()
{
atInt64 val;
readUBytesToBuf(&val, 8);
return utility::LittleInt64(val);
}
template <class T>
inline atInt64 readValLittle(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
{return readInt64Little();}
inline atInt64 readInt64Big()
{
atInt64 val;
readUBytesToBuf(&val, 8);
return utility::BigInt64(val);
}
template <class T>
inline atInt64 readValBig(typename std::enable_if<std::is_same<T, atInt64>::value>::type* = 0)
{return readInt64Big();}
/*! \brief Reads a Uint64 and swaps to proper endianness depending on platform /*! \brief Reads a Uint64 and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -213,6 +313,26 @@ public:
inline atUint64 readVal(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0) inline atUint64 readVal(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
{return readUint64();} {return readUint64();}
inline atUint64 readUint64Little()
{
atUint64 val;
readUBytesToBuf(&val, 8);
return utility::LittleUint64(val);
}
template <class T>
inline atUint64 readValLittle(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
{return readUint64Little();}
inline atUint64 readUint64Big()
{
atUint64 val;
readUBytesToBuf(&val, 8);
return utility::BigUint64(val);
}
template <class T>
inline atUint64 readValBig(typename std::enable_if<std::is_same<T, atUint64>::value>::type* = 0)
{return readUint64Big();}
/*! \brief Reads a float and swaps to proper endianness depending on platform /*! \brief Reads a float and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -231,6 +351,26 @@ public:
inline float readVal(typename std::enable_if<std::is_same<T, float>::value>::type* = 0) inline float readVal(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
{return readFloat();} {return readFloat();}
inline float readFloatLittle()
{
float val;
readUBytesToBuf(&val, 4);
return utility::LittleFloat(val);
}
template <class T>
inline float readValLittle(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
{return readFloatLittle();}
inline float readFloatBig()
{
float val;
readUBytesToBuf(&val, 4);
return utility::BigFloat(val);
}
template <class T>
inline float readValBig(typename std::enable_if<std::is_same<T, float>::value>::type* = 0)
{return readFloatBig();}
/*! \brief Reads a double and swaps to proper endianness depending on platform /*! \brief Reads a double and swaps to proper endianness depending on platform
* and Stream settings, and advances the current position * and Stream settings, and advances the current position
* *
@ -249,6 +389,26 @@ public:
inline double readVal(typename std::enable_if<std::is_same<T, double>::value>::type* = 0) inline double readVal(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
{return readDouble();} {return readDouble();}
inline double readDoubleLittle()
{
double val;
readUBytesToBuf(&val, 8);
return utility::LittleDouble(val);
}
template <class T>
inline double readValLittle(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
{return readDoubleLittle();}
inline double readDoubleBig()
{
double val;
readUBytesToBuf(&val, 8);
return utility::BigDouble(val);
}
template <class T>
inline double readValBig(typename std::enable_if<std::is_same<T, double>::value>::type* = 0)
{return readDoubleBig();}
/*! \brief Reads a bool and advances the current position /*! \brief Reads a bool and advances the current position
* *
* \return bool The value at the current address * \return bool The value at the current address
@ -289,6 +449,30 @@ public:
inline atVec2f readVal(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0) inline atVec2f readVal(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
{return readVec2f();} {return readVec2f();}
inline atVec2f readVec2fLittle()
{
atVec2f val;
readUBytesToBuf(&val, 8);
utility::LittleFloat(val.vec[0]);
utility::LittleFloat(val.vec[1]);
return val;
}
template <class T>
inline atVec2f readValLittle(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
{return readVec2fLittle();}
inline atVec2f readVec2fBig()
{
atVec2f val;
readUBytesToBuf(&val, 8);
utility::BigFloat(val.vec[0]);
utility::BigFloat(val.vec[1]);
return val;
}
template <class T>
inline atVec2f readValBig(typename std::enable_if<std::is_same<T, atVec2f>::value>::type* = 0)
{return readVec2fBig();}
/*! \brief Reads an atVec3f (12 bytes) and advances the current position /*! \brief Reads an atVec3f (12 bytes) and advances the current position
* *
* \return atVec3f The value at the current address * \return atVec3f The value at the current address
@ -316,6 +500,32 @@ public:
inline atVec3f readVal(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0) inline atVec3f readVal(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
{return readVec3f();} {return readVec3f();}
inline atVec3f readVec3fLittle()
{
atVec3f val;
readUBytesToBuf(&val, 12);
utility::LittleFloat(val.vec[0]);
utility::LittleFloat(val.vec[1]);
utility::LittleFloat(val.vec[2]);
return val;
}
template <class T>
inline atVec3f readValLittle(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
{return readVec3fLittle();}
inline atVec3f readVec3fBig()
{
atVec3f val;
readUBytesToBuf(&val, 12);
utility::BigFloat(val.vec[0]);
utility::BigFloat(val.vec[1]);
utility::BigFloat(val.vec[2]);
return val;
}
template <class T>
inline atVec3f readValBig(typename std::enable_if<std::is_same<T, atVec3f>::value>::type* = 0)
{return readVec3fBig();}
/*! \brief Reads an atVec4f (16 bytes) and advances the current position /*! \brief Reads an atVec4f (16 bytes) and advances the current position
* *
* \return atVec4f The value at the current address * \return atVec4f The value at the current address
@ -345,6 +555,34 @@ public:
inline atVec4f readVal(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0) inline atVec4f readVal(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
{return readVec4f();} {return readVec4f();}
inline atVec4f readVec4fLittle()
{
atVec4f val;
readUBytesToBuf(&val, 16);
utility::LittleFloat(val.vec[0]);
utility::LittleFloat(val.vec[1]);
utility::LittleFloat(val.vec[2]);
utility::LittleFloat(val.vec[3]);
return val;
}
template <class T>
inline atVec4f readValLittle(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
{return readVec4fLittle();}
inline atVec4f readVec4fBig()
{
atVec4f val;
readUBytesToBuf(&val, 16);
utility::BigFloat(val.vec[0]);
utility::BigFloat(val.vec[1]);
utility::BigFloat(val.vec[2]);
utility::BigFloat(val.vec[3]);
return val;
}
template <class T>
inline atVec4f readValBig(typename std::enable_if<std::is_same<T, atVec4f>::value>::type* = 0)
{return readVec4fBig();}
/*! \brief Reads a wide-char string, converts to UTF8 and advances the position in the file /*! \brief Reads a wide-char string, converts to UTF8 and advances the position in the file
* *
* \param fixedLen If non-negative, this is a fixed-length string read * \param fixedLen If non-negative, this is a fixed-length string read
@ -376,6 +614,56 @@ public:
return conv.to_bytes(tmp); return conv.to_bytes(tmp);
} }
inline std::string readWStringAsStringLittle(atInt32 fixedLen = -1)
{
std::wstring tmp;
atUint16 chr = readUint16Little();
atInt32 i;
for (i = 0 ;; ++i)
{
if (fixedLen >= 0 && i >= fixedLen - 1)
break;
if (!chr)
break;
tmp.push_back(chr);
chr = readUint16Little();
}
if (fixedLen >= 0 && i < fixedLen)
seek(fixedLen - i);
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.to_bytes(tmp);
}
inline std::string readWStringAsStringBig(atInt32 fixedLen = -1)
{
std::wstring tmp;
atUint16 chr = readUint16Big();
atInt32 i;
for (i = 0 ;; ++i)
{
if (fixedLen >= 0 && i >= fixedLen - 1)
break;
if (!chr)
break;
tmp.push_back(chr);
chr = readUint16Big();
}
if (fixedLen >= 0 && i < fixedLen)
seek(fixedLen - i);
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
return conv.to_bytes(tmp);
}
/*! \brief Reads a string and advances the position in the file /*! \brief Reads a string and advances the position in the file
* *
* \param fixedLen If non-negative, this is a fixed-length string read * \param fixedLen If non-negative, this is a fixed-length string read
@ -438,6 +726,56 @@ public:
inline std::wstring readVal(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0) inline std::wstring readVal(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWString();} {return readWString();}
inline std::wstring readWStringLittle(atInt32 fixedLen = -1)
{
std::wstring ret;
atUint16 chr = readUint16Little();
atInt32 i;
for (i = 1 ; chr != 0 ; ++i)
{
ret += chr;
if (fixedLen >= 0 && i >= fixedLen)
break;
chr = readUint16Little();
}
if (fixedLen >= 0 && i < fixedLen)
seek(fixedLen - i);
return ret;
}
template <class T>
inline std::wstring readValLittle(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWStringLittle();}
inline std::wstring readWStringBig(atInt32 fixedLen = -1)
{
std::wstring ret;
atUint16 chr = readUint16Big();
atInt32 i;
for (i = 1 ; chr != 0 ; ++i)
{
ret += chr;
if (fixedLen >= 0 && i >= fixedLen)
break;
chr = readUint16Big();
}
if (fixedLen >= 0 && i < fixedLen)
seek(fixedLen - i);
return ret;
}
template <class T>
inline std::wstring readValBig(typename std::enable_if<std::is_same<T, std::wstring>::value>::type* = 0)
{return readWStringBig();}
template<class T> template<class T>
void enumerate(std::vector<T>& vector, size_t count, void enumerate(std::vector<T>& vector, size_t count,
typename std::enable_if<std::is_arithmetic<T>::value || typename std::enable_if<std::is_arithmetic<T>::value ||
@ -451,6 +789,32 @@ public:
vector.emplace_back(readVal<T>()); vector.emplace_back(readVal<T>());
} }
template<class T>
void enumerateLittle(std::vector<T>& vector, size_t count,
typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0)
{
vector.clear();
vector.reserve(count);
for (size_t i=0 ; i<count ; ++i)
vector.emplace_back(readValLittle<T>());
}
template<class T>
void enumerateBig(std::vector<T>& vector, size_t count,
typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0)
{
vector.clear();
vector.reserve(count);
for (size_t i=0 ; i<count ; ++i)
vector.emplace_back(readValBig<T>());
}
template<class T> template<class T>
void enumerate(std::vector<T>& vector, size_t count, void enumerate(std::vector<T>& vector, size_t count,
typename std::enable_if<!std::is_arithmetic<T>::value && typename std::enable_if<!std::is_arithmetic<T>::value &&

View File

@ -115,6 +115,20 @@ public:
} }
inline void writeVal(atInt16 val) {return writeInt16(val);} inline void writeVal(atInt16 val) {return writeInt16(val);}
inline void writeInt16Little(atInt16 val)
{
utility::LittleInt16(val);
writeUBytes((atUint8*)&val, 2);
}
inline void writeValLittle(atInt16 val) {return writeInt16Little(val);}
inline void writeInt16Big(atInt16 val)
{
utility::BigInt16(val);
writeUBytes((atUint8*)&val, 2);
}
inline void writeValBig(atInt16 val) {return writeInt16Big(val);}
/*! \brief Writes an Uint16 to the buffer and advances the buffer. /*! \brief Writes an Uint16 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
* *
@ -124,6 +138,12 @@ public:
inline void writeUint16(atUint16 val) {writeInt16(val);} inline void writeUint16(atUint16 val) {writeInt16(val);}
inline void writeVal(atUint16 val) {return writeUint16(val);} inline void writeVal(atUint16 val) {return writeUint16(val);}
inline void writeUint16Little(atUint16 val) {writeInt16Little(val);}
inline void writeValLittle(atUint16 val) {return writeUint16Little(val);}
inline void writeUint16Big(atUint16 val) {writeInt16Big(val);}
inline void writeValBig(atUint16 val) {return writeUint16Big(val);}
/*! \brief Writes an Int32 to the buffer and advances the buffer. /*! \brief Writes an Int32 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.
* *
@ -140,6 +160,20 @@ public:
} }
inline void writeVal(atInt32 val) {return writeInt32(val);} inline void writeVal(atInt32 val) {return writeInt32(val);}
inline void writeInt32Little(atInt32 val)
{
utility::LittleInt32(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValLittle(atInt32 val) {return writeInt32Little(val);}
inline void writeInt32Big(atInt32 val)
{
utility::BigInt32(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValBig(atInt32 val) {return writeInt32Big(val);}
/*! \brief Writes an Uint32 to the buffer and advances the buffer. /*! \brief Writes an Uint32 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.
* *
@ -149,6 +183,12 @@ public:
inline void writeUint32(atUint32 val) {writeInt32(val);} inline void writeUint32(atUint32 val) {writeInt32(val);}
inline void writeVal(atUint32 val) {return writeUint32(val);} inline void writeVal(atUint32 val) {return writeUint32(val);}
inline void writeUint32Little(atUint32 val) {writeInt32Little(val);}
inline void writeValLittle(atUint32 val) {return writeUint32Little(val);}
inline void writeUint32Big(atUint32 val) {writeInt32Big(val);}
inline void writeValBig(atUint32 val) {return writeUint32Big(val);}
/*! \brief Writes an Int64 to the buffer and advances the buffer. /*! \brief Writes an Int64 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.
* *
@ -165,6 +205,20 @@ public:
} }
inline void writeVal(atInt64 val) {return writeInt64(val);} inline void writeVal(atInt64 val) {return writeInt64(val);}
inline void writeInt64Little(atInt64 val)
{
utility::LittleInt64(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValLittle(atInt64 val) {return writeInt64Little(val);}
inline void writeInt64Big(atInt64 val)
{
utility::BigInt64(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValBig(atInt64 val) {return writeInt64Big(val);}
/*! \brief Writes an Uint64 to the buffer and advances the buffer. /*! \brief Writes an Uint64 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.
* *
@ -174,6 +228,12 @@ public:
inline void writeUint64(atUint64 val) {writeInt64(val);} inline void writeUint64(atUint64 val) {writeInt64(val);}
inline void writeVal(atUint64 val) {return writeUint64(val);} inline void writeVal(atUint64 val) {return writeUint64(val);}
inline void writeUint64Little(atUint64 val) {writeInt64Little(val);}
inline void writeValLittle(atUint64 val) {return writeUint64Little(val);}
inline void writeUint64Big(atUint64 val) {writeInt64Big(val);}
inline void writeValBig(atUint64 val) {return writeUint64Big(val);}
/*! \brief Writes an float to the buffer and advances the buffer. /*! \brief Writes an float 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.
* *
@ -190,6 +250,20 @@ public:
} }
inline void writeVal(float val) {return writeFloat(val);} inline void writeVal(float val) {return writeFloat(val);}
inline void writeFloatLittle(float val)
{
utility::LittleFloat(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValLittle(float val) {return writeFloatLittle(val);}
inline void writeFloatBig(float val)
{
utility::BigFloat(val);
writeUBytes((atUint8*)&val, 4);
}
inline void writeValBig(float val) {return writeFloatBig(val);}
/*! \brief Writes an double to the buffer and advances the buffer. /*! \brief Writes an double 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.
* *
@ -206,6 +280,20 @@ public:
} }
inline void writeVal(double val) {return writeDouble(val);} inline void writeVal(double val) {return writeDouble(val);}
inline void writeDoubleLittle(double val)
{
utility::LittleDouble(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValLittle(double val) {return writeDoubleLittle(val);}
inline void writeDoubleBig(double val)
{
utility::BigDouble(val);
writeUBytes((atUint8*)&val, 8);
}
inline void writeValBig(double val) {return writeDoubleBig(val);}
/*! \brief Writes an bool to the buffer and advances the buffer. /*! \brief Writes an bool 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.
* *
@ -237,6 +325,22 @@ public:
} }
inline void writeVal(atVec2f val) {return writeVec2f(val);} inline void writeVal(atVec2f val) {return writeVec2f(val);}
inline void writeVec2fLittle(atVec2f vec)
{
utility::LittleFloat(vec.vec[0]);
utility::LittleFloat(vec.vec[1]);
writeUBytes((atUint8*)&vec, 8);
}
inline void writeValLittle(atVec2f val) {return writeVec2fLittle(val);}
inline void writeVec2fBig(atVec2f vec)
{
utility::BigFloat(vec.vec[0]);
utility::BigFloat(vec.vec[1]);
writeUBytes((atUint8*)&vec, 8);
}
inline void writeValBig(atVec2f val) {return writeVec2fBig(val);}
/*! \brief Writes an atVec3f (12 bytes) to the buffer and advances the buffer. /*! \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. * It also swaps the bytes depending on the platform and Stream settings.
* *
@ -261,6 +365,24 @@ public:
} }
inline void writeVal(atVec3f val) {return writeVec3f(val);} inline void writeVal(atVec3f val) {return writeVec3f(val);}
inline void writeVec3fLittle(atVec3f vec)
{
utility::LittleFloat(vec.vec[0]);
utility::LittleFloat(vec.vec[1]);
utility::LittleFloat(vec.vec[2]);
writeUBytes((atUint8*)&vec, 12);
}
inline void writeValLittle(atVec3f val) {return writeVec3fLittle(val);}
inline void writeVec3fBig(atVec3f vec)
{
utility::BigFloat(vec.vec[0]);
utility::BigFloat(vec.vec[1]);
utility::BigFloat(vec.vec[2]);
writeUBytes((atUint8*)&vec, 12);
}
inline void writeValBig(atVec3f val) {return writeVec3fBig(val);}
/*! \brief Writes an atVec4f (16 bytes) to the buffer and advances the buffer. /*! \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. * It also swaps the bytes depending on the platform and Stream settings.
* *
@ -287,6 +409,26 @@ public:
} }
inline void writeVal(atVec4f val) {return writeVec4f(val);} inline void writeVal(atVec4f val) {return writeVec4f(val);}
inline void writeVec4fLittle(atVec4f vec)
{
utility::LittleFloat(vec.vec[0]);
utility::LittleFloat(vec.vec[1]);
utility::LittleFloat(vec.vec[2]);
utility::LittleFloat(vec.vec[3]);
writeUBytes((atUint8*)&vec, 16);
}
inline void writeValLittle(atVec4f val) {return writeVec4fLittle(val);}
inline void writeVec4fBig(atVec4f vec)
{
utility::BigFloat(vec.vec[0]);
utility::BigFloat(vec.vec[1]);
utility::BigFloat(vec.vec[2]);
utility::BigFloat(vec.vec[3]);
writeUBytes((atUint8*)&vec, 16);
}
inline void writeValBig(atVec4f val) {return writeVec4fBig(val);}
/*! \brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer. /*! \brief Converts a UTF8 string to a wide-char string in the buffer and advances the buffer.
* It also swaps the bytes depending on the platform and Stream settings. * It also swaps the bytes depending on the platform and Stream settings.
* *
@ -332,6 +474,82 @@ public:
} }
} }
inline void writeStringAsWStringLittle(const std::string& str, atInt32 fixedLen = -1)
{
std::string tmpStr = "\xEF\xBB\xBF" + str;
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring tmp = conv.from_bytes(tmpStr);
if (fixedLen < 0)
{
for (atUint16 chr : tmp)
{
if (chr != 0xFEFF)
writeUint16Little(chr);
}
writeUint16Little(0);
}
else
{
auto it = tmp.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
atUint16 chr;
if (it == tmp.end())
chr = 0;
else
chr = *it++;
if (chr == 0xFEFF)
{
--i;
continue;
}
writeUint16Little(chr);
}
}
}
inline void writeStringAsWStringBig(const std::string& str, atInt32 fixedLen = -1)
{
std::string tmpStr = "\xEF\xBB\xBF" + str;
std::wstring_convert<std::codecvt_utf8<wchar_t>> conv;
std::wstring tmp = conv.from_bytes(tmpStr);
if (fixedLen < 0)
{
for (atUint16 chr : tmp)
{
if (chr != 0xFEFF)
writeUint16Big(chr);
}
writeUint16Big(0);
}
else
{
auto it = tmp.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
atUint16 chr;
if (it == tmp.end())
chr = 0;
else
chr = *it++;
if (chr == 0xFEFF)
{
--i;
continue;
}
writeUint16Big(chr);
}
}
}
/*! \brief Writes an string to the buffer and advances the buffer. /*! \brief Writes an string to the buffer and advances the buffer.
* *
* \sa Endian * \sa Endian
@ -402,6 +620,64 @@ public:
} }
inline void writeVal(const std::wstring& val) {return writeWString(val);} inline void writeVal(const std::wstring& val) {return writeWString(val);}
inline void writeWStringLittle(const std::wstring& str, atInt32 fixedLen = -1)
{
if (fixedLen < 0)
{
for (atUint16 c : str)
{
writeUint16Little(c);
if (c == L'\0')
break;
}
writeUint16Little(0);
}
else
{
auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
atUint16 chr;
if (it == str.end())
chr = 0;
else
chr = *it++;
writeUint16Little(chr);
}
}
}
inline void writeValLittle(const std::wstring& val) {return writeWStringLittle(val);}
inline void writeWStringBig(const std::wstring& str, atInt32 fixedLen = -1)
{
if (fixedLen < 0)
{
for (atUint16 c : str)
{
writeUint16Big(c);
if (c == L'\0')
break;
}
writeUint16Big(0);
}
else
{
auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
atUint16 chr;
if (it == str.end())
chr = 0;
else
chr = *it++;
writeUint16Big(chr);
}
}
}
inline void writeValBig(const std::wstring& val) {return writeWStringBig(val);}
inline void fill(atUint8 val, atUint64 length) inline void fill(atUint8 val, atUint64 length)
{for (atUint64 l=0 ; l<length ; ++l) writeUBytes(&val, 1);} {for (atUint64 l=0 ; l<length ; ++l) writeUBytes(&val, 1);}
inline void fill(atInt8 val, atUint64 length) inline void fill(atInt8 val, atUint64 length)
@ -418,6 +694,28 @@ public:
writeVal(item); writeVal(item);
} }
template <class T>
void enumerateLittle(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0)
{
for (const T& item : vector)
writeValLittle(item);
}
template <class T>
void enumerateBig(const std::vector<T>& vector,
typename std::enable_if<std::is_arithmetic<T>::value ||
std::is_same<T, atVec2f>::value ||
std::is_same<T, atVec3f>::value ||
std::is_same<T, atVec4f>::value>::type* = 0)
{
for (const T& item : vector)
writeValBig(item);
}
template <class T> template <class T>
void enumerate(const std::vector<T>& vector, void enumerate(const std::vector<T>& vector,
typename std::enable_if<!std::is_arithmetic<T>::value && typename std::enable_if<!std::is_arithmetic<T>::value &&