mirror of https://github.com/libAthena/athena.git
added fixed-length string writing
This commit is contained in:
parent
242a06915b
commit
3dfb001f3d
|
@ -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')
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue