added fixed-length string writing

This commit is contained in:
Jack Andersen 2015-06-19 10:12:25 -10:00
parent 242a06915b
commit 3dfb001f3d
7 changed files with 216 additions and 75 deletions

View File

@ -1,7 +1,7 @@
# PKGBUILD for atdna
_pkgname=atdna
pkgname=$_pkgname-git
pkgver=1.1.0.35.gfd3db3e
pkgver=1.1.0.36.g242a069
pkgrel=1
pkgdesc="Companion DNA utility for libAthena"
arch=('i686' 'x86_64')

View File

@ -412,7 +412,7 @@ public:
}
else if (arg.getKind() == clang::TemplateArgument::Expression)
{
const clang::Expr* expr = arg.getAsExpr();
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
if (idx == 1)
{
sizeArg = &arg;
@ -506,13 +506,13 @@ public:
fileOut << " " << fieldName << ".clear();\n";
fileOut << " " << fieldName << ".reserve(" << sizeExpr << ");\n";
if (isDNAType)
fileOut << " for (int i=0 ; i<(" << sizeExpr << ") ; ++i)\n"
fileOut << " for (size_t i=0 ; i<(" << sizeExpr << ") ; ++i)\n"
" {\n"
" " << fieldName << ".emplace_back();\n"
" " << fieldName << ".back()." << ioOp << "\n"
" }\n";
else
fileOut << " for (int i=0 ; i<(" << sizeExpr << ") ; ++i)\n"
fileOut << " for (size_t i=0 ; i<(" << sizeExpr << ") ; ++i)\n"
" " << fieldName << ".push_back(" << ioOp << ");\n";
}
else
@ -533,7 +533,7 @@ public:
{
if (arg.getKind() == clang::TemplateArgument::Expression)
{
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)arg.getAsExpr();
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)arg.getAsExpr()->IgnoreImpCasts();
if (uExpr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
uExpr->getKind() == clang::UETT_SizeOf)
{
@ -585,7 +585,7 @@ public:
{
if (arg.getKind() == clang::TemplateArgument::Expression)
{
const clang::Expr* expr = arg.getAsExpr();
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
llvm::APSInt sizeLiteral;
if (expr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
@ -609,7 +609,12 @@ public:
if (!p)
fileOut << " " << fieldName << " = reader.readString(" << sizeExprStr << ");\n";
else
fileOut << " writer.writeString(" << fieldName << ");\n";
{
fileOut << " writer.writeString(" << fieldName;
if (sizeExprStr.size())
fileOut << ", " << sizeExprStr;
fileOut << ");\n";
}
}
else if (!tsDecl->getNameAsString().compare("WString"))
{
@ -644,7 +649,7 @@ public:
{
if (arg.getKind() == clang::TemplateArgument::Expression)
{
const clang::Expr* expr = arg.getAsExpr();
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
if (idx == 0)
{
llvm::APSInt sizeLiteral;
@ -719,7 +724,12 @@ public:
if (!p)
fileOut << " " << fieldName << " = reader.readWString(" << sizeExprStr << ");\n";
else
fileOut << " writer.writeWString(" << fieldName << ");\n";
{
fileOut << " writer.writeWString(" << fieldName;
if (sizeExprStr.size())
fileOut << ", " << sizeExprStr;
fileOut << ");\n";
}
}
else if (!tsDecl->getNameAsString().compare("UTF8"))
{
@ -729,7 +739,7 @@ public:
{
if (arg.getKind() == clang::TemplateArgument::Expression)
{
const clang::Expr* expr = arg.getAsExpr();
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
llvm::APSInt sizeLiteral;
if (expr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
@ -753,12 +763,18 @@ public:
if (!p)
fileOut << " " << fieldName << " = reader.readUnicode(" << sizeExprStr << ");\n";
else
fileOut << " writer.writeUnicode(" << fieldName << ");\n";
{
fileOut << " writer.writeUnicode(" << fieldName;
if (sizeExprStr.size())
fileOut << ", " << sizeExprStr;
fileOut << ");\n";
}
}
else if (!tsDecl->getNameAsString().compare("Seek"))
{
size_t idx = 0;
llvm::APSInt offset(64, 0);
const clang::Expr* offsetExpr = nullptr;
std::string offsetExprStr;
llvm::APSInt direction(64, 0);
const clang::Expr* directionExpr = nullptr;
bool bad = false;
@ -766,19 +782,25 @@ public:
{
if (arg.getKind() == clang::TemplateArgument::Expression)
{
const clang::Expr* expr = arg.getAsExpr();
const clang::Expr* expr = arg.getAsExpr()->IgnoreImpCasts();
if (!idx)
{
if (!expr->isIntegerConstantExpr(offset, context))
offsetExpr = expr;
const clang::UnaryExprOrTypeTraitExpr* uExpr = (clang::UnaryExprOrTypeTraitExpr*)expr;
llvm::APSInt offsetLiteral;
if (expr->getStmtClass() == clang::Stmt::UnaryExprOrTypeTraitExprClass &&
uExpr->getKind() == clang::UETT_SizeOf)
{
if (!p)
{
clang::DiagnosticBuilder diag = context.getDiagnostics().Report(expr->getLocStart(), AthenaError);
diag.AddString("Unable to use non-constant offset expression in Athena");
diag.AddSourceRange(clang::CharSourceRange(expr->getSourceRange(), true));
}
bad = true;
break;
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))
{
offsetExprStr = offsetLiteral.toString(10);
}
}
else
@ -802,7 +824,6 @@ public:
if (bad)
continue;
int64_t offsetVal = offset.getSExtValue();
int64_t directionVal = direction.getSExtValue();
if (directionVal < 0 || directionVal > 2)
{
@ -828,23 +849,23 @@ public:
if (directionVal == 0)
{
if (!p)
fileOut << " reader.seek(" << offsetVal << ", Athena::Begin);\n";
fileOut << " reader.seek(" << offsetExprStr << ", Athena::Begin);\n";
else
fileOut << " writer.seek(" << offsetVal << ", Athena::Begin);\n";
fileOut << " writer.seek(" << offsetExprStr << ", Athena::Begin);\n";
}
else if (directionVal == 1)
{
if (!p)
fileOut << " reader.seek(" << offsetVal << ", Athena::Current);\n";
fileOut << " reader.seek(" << offsetExprStr << ", Athena::Current);\n";
else
fileOut << " writer.seek(" << offsetVal << ", Athena::Current);\n";
fileOut << " writer.seek(" << offsetExprStr << ", Athena::Current);\n";
}
else if (directionVal == 2)
{
if (!p)
fileOut << " reader.seek(" << offsetVal << ", Athena::End);\n";
fileOut << " reader.seek(" << offsetExprStr << ", Athena::End);\n";
else
fileOut << " writer.seek(" << offsetVal << ", Athena::End);\n";
fileOut << " writer.seek(" << offsetExprStr << ", Athena::End);\n";
}
}

View File

@ -44,9 +44,9 @@ public:
void writeBool(bool val);
void writeVec3f(atVec3f vec);
void writeVec4f(atVec4f vec);
void writeString(const std::string& val);
void writeWString(const std::wstring& str);
void writeUnicode(const std::string& str);
void writeString(const std::string& val, atInt32 fixedLen = -1);
void writeWString(const std::wstring& str, atInt32 fixedLen = -1);
void writeUnicode(const std::string& str, atInt32 fixedLen = -1);
void fill(atInt8 byte, atUint64 len);
void fill(atUint8 byte, atUint64 len);
private:

View File

@ -38,9 +38,9 @@ public:
virtual void writeBool(bool) = 0;
virtual void writeVec3f(atVec3f vec) = 0;
virtual void writeVec4f(atVec4f vec) = 0;
virtual void writeString(const std::string&) = 0;
virtual void writeWString(const std::wstring&) = 0;
virtual void writeUnicode(const std::string&) = 0;
virtual void writeString(const std::string&, atInt32 = -1) = 0;
virtual void writeWString(const std::wstring&, atInt32 = -1) = 0;
virtual void writeUnicode(const std::string&, atInt32 = -1) = 0;
virtual void fill(atUint8, atUint64) = 0;
virtual void fill(atInt8, atUint64) = 0;
};

View File

@ -267,22 +267,25 @@ public:
*
* \sa Endian
* \param str The string to write to the buffer
* \param fixedLen If not -1, the number of characters to zero-fill string to
*/
void writeUnicode(const std::string& str);
void writeUnicode(const std::string& str, atInt32 fixedLen = -1);
/*! \brief Writes an string to the buffer and advances the buffer.
*
* \sa Endian
* \param str The string to write to the buffer
* \param fixedLen If not -1, the number of characters to zero-fill string to
*/
void writeString(const std::string& str);
void writeString(const std::string& str, atInt32 fixedLen = -1);
/*! \brief Writes an wstring to the buffer and advances the buffer.
*
* \sa Endian
* \param str The string to write to the buffer
* \param fixedLen If not -1, the number of characters to zero-fill string to
*/
void writeWString(const std::wstring& str);
void writeWString(const std::wstring& str, atInt32 fixedLen = -1);
void fill(atUint8 val, atUint64 length);

View File

@ -298,53 +298,117 @@ void FileWriter::writeVec4f(atVec4f vec)
THROW_IO_EXCEPTION("Unable to write to stream");
}
void FileWriter::writeString(const std::string& val)
void FileWriter::writeString(const std::string& val, atInt32 fixedLen)
{
if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
m_bitValid = false;
char term = '\0';
if (fwrite(val.c_str(), 1, val.length(), m_fileHandle) != val.length())
THROW_IO_EXCEPTION("Unable to write to stream");
if (fixedLen < 0)
{
if (fwrite(val.c_str(), 1, val.length(), m_fileHandle) != val.length())
THROW_IO_EXCEPTION("Unable to write to stream");
if (fwrite(&term, 1, 1, m_fileHandle) != 1)
THROW_IO_EXCEPTION("Unable to write to stream");
if (fwrite(&term, 1, 1, m_fileHandle) != 1)
THROW_IO_EXCEPTION("Unable to write to stream");
}
else
{
if (val.length() >= fixedLen)
{
if (fwrite(val.c_str(), 1, fixedLen, m_fileHandle) != fixedLen)
THROW_IO_EXCEPTION("Unable to write to stream");
}
else
{
if (fwrite(val.c_str(), 1, val.length(), m_fileHandle) != val.length())
THROW_IO_EXCEPTION("Unable to write to stream");
for (atUint32 i=val.length() ; i<fixedLen ; ++i)
{
if (fwrite(&term, 1, 1, m_fileHandle) != 1)
THROW_IO_EXCEPTION("Unable to write to stream");
}
}
}
}
void FileWriter::writeWString(const std::wstring& val)
void FileWriter::writeWString(const std::wstring& val, atInt32 fixedLen)
{
if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
m_bitValid = false;
wchar_t term = L'\0';
if (fwrite(val.c_str(), 2, val.length(), m_fileHandle) != val.length())
THROW_IO_EXCEPTION("Unable to write to stream");
if (fixedLen < 0)
{
if (fwrite(val.c_str(), 2, val.length(), m_fileHandle) != val.length())
THROW_IO_EXCEPTION("Unable to write to stream");
if (fwrite(&term, 2, 1, m_fileHandle) != 1)
THROW_IO_EXCEPTION("Unable to write to stream");
if (fwrite(&term, 2, 1, m_fileHandle) != 1)
THROW_IO_EXCEPTION("Unable to write to stream");
}
else
{
if (val.length() >= fixedLen)
{
if (fwrite(val.c_str(), 2, fixedLen, m_fileHandle) != fixedLen)
THROW_IO_EXCEPTION("Unable to write to stream");
}
else
{
if (fwrite(val.c_str(), 2, val.length(), m_fileHandle) != val.length())
THROW_IO_EXCEPTION("Unable to write to stream");
for (atUint32 i=val.length() ; i<fixedLen ; ++i)
{
if (fwrite(&term, 2, 1, m_fileHandle) != 1)
THROW_IO_EXCEPTION("Unable to write to stream");
}
}
}
}
void FileWriter::writeUnicode(const std::string& str)
void FileWriter::writeUnicode(const std::string& str, atInt32 fixedLen)
{
if (!isOpen())
THROW_INVALID_OPERATION_EXCEPTION("File not open for writing");
std::string tmpStr = "\xEF\xBB\xBF" + str;
std::vector<short> tmp;
std::vector<atUint16> tmp;
utf8::utf8to16(tmpStr.begin(), tmpStr.end(), back_inserter(tmp));
for (atUint16 chr : tmp)
if (fixedLen < 0)
{
if (chr != 0xFEFF)
writeInt16(chr);
for (atUint16 chr : tmp)
{
if (chr != 0xFEFF)
writeUint16(chr);
}
writeUint16(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;
}
writeUint16(chr);
}
}
}

View File

@ -497,47 +497,100 @@ void MemoryWriter::writeVec4f(atVec4f vec)
m_position += 16;
}
void MemoryWriter::writeUnicode(const std::string& str)
void MemoryWriter::writeUnicode(const std::string& str, atInt32 fixedLen)
{
std::string tmpStr = "\xEF\xBB\xBF" + str;
std::vector<short> tmp;
std::vector<atUint16> tmp;
utf8::utf8to16(tmpStr.begin(), tmpStr.end(), back_inserter(tmp));
for (atUint16 chr : tmp)
if (fixedLen < 0)
{
if (chr != 0xFEFF)
writeInt16(chr);
for (atUint16 chr : tmp)
{
if (chr != 0xFEFF)
writeUint16(chr);
}
writeUint16(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;
}
writeUint16(chr);
}
}
writeInt16(0);
}
void MemoryWriter::writeString(const std::string& str)
void MemoryWriter::writeString(const std::string& str, atInt32 fixedLen)
{
for (atUint8 c : str)
if (fixedLen < 0)
{
writeUByte(c);
for (atUint8 c : str)
{
writeUByte(c);
if (c == '\0')
break;
if (c == '\0')
break;
}
writeUByte(0);
}
else
{
auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
atUint8 chr;
if (it == str.end())
chr = 0;
else
chr = *it++;
writeUByte(chr);
}
}
writeUByte(0);
}
void MemoryWriter::writeWString(const std::wstring& str)
void MemoryWriter::writeWString(const std::wstring& str, atInt32 fixedLen)
{
for (atUint16 c : str)
if (fixedLen < 0)
{
writeUint16(c);
for (atUint16 c : str)
{
writeUint16(c);
if (c == L'\0')
break;
if (c == L'\0')
break;
}
writeUint16(0);
}
else
{
auto it = str.begin();
for (atInt32 i=0 ; i<fixedLen ; ++i)
{
atUint16 chr;
if (it == str.end())
chr = 0;
else
chr = *it++;
writeUint16(chr);
}
}
writeUint16(0);
}
void MemoryWriter::fill(atUint8 val, atUint64 length)