mkxp-freebird/xxd+/main.cpp

165 lines
3.2 KiB
C++

#include <QFile>
#include <QTextStream>
#include <QDataStream>
#include <QString>
#include <QBuffer>
#include <QFileInfo>
#include <QStringList>
#include <QDebug>
static const char intro[] =
"extern const %1 %2[] = {\n";
static const char outro[] =
"\n};\nextern const %1 %2 = %3;";
int writeDump(const QString &srcFilename,
const QString &dstFilename,
const QString &dataType,
const QString &lenType,
const QString &dataSymbol,
bool addNullTerm)
{
QFile srcFile(srcFilename);
if (!srcFile.open(QFile::ReadOnly))
return 1;
QFile dstFile(dstFilename);
if (!dstFile.open(QFile::WriteOnly))
return 1;
QByteArray srcData = srcFile.readAll();
if (addNullTerm)
srcData.append('\0');
QBuffer srcBuffer(&srcData);
srcBuffer.open(QBuffer::ReadOnly);
QDataStream in(&srcBuffer);
QTextStream out(&dstFile);
QString introStr = QString(intro).arg(dataType, dataSymbol);
out << introStr;
const int byteColumns = 0x10;
int columnInd = 0;
int byteCount = 0;
while (!in.atEnd())
{
uchar byte;
in >> byte;
out << " ";
if (columnInd == 0)
out << " ";
out << "0x";
if (byte < 0x10)
out << "0";
out << QString::number(byte, 0x10);
if (!in.atEnd())
out << ",";
if (++columnInd == byteColumns)
{
out << "\n";
columnInd = 0;
}
++byteCount;
}
if (addNullTerm)
--byteCount;
QString outroStr = QString(outro).arg(lenType, dataSymbol+"_len", QString::number(byteCount));
out << outroStr;
return 0;
}
QString getNamedOption(const QStringList &args,
const QString &optName,
const QString &defValue)
{
QString value = defValue;
if (args.contains(optName))
{
int argInd = args.indexOf(optName);
if (argInd < args.count())
value = args.at(argInd+1);
}
return value;
}
static const char usageStr[] =
"Usage: %1 file [options]\n"
"Options:\n"
" -o [filename] Override default output filename.\n"
" --symbol [sym] Override default data C symbol.\n"
" --null-terminated Add null byte to data (not reflected in \"len\").\n"
" --string Use char for data array. Implies \"--null-terminated\".\n"
" --help Yo dawg.\n";
void usage(const QString &argv0)
{
QTextStream out(stdout);
out << QString(usageStr).arg(argv0);
}
int main(int argc, char *argv[])
{
(void) argc; (void) argv;
if (argc < 2)
{
usage(*argv);
return 0;
}
QString inFile(argv[1]);
QFileInfo finfo(inFile);
QStringList restArg;
for (int i = 2; i < argc; ++i)
restArg << argv[i];
if (restArg.contains("--help"))
{
usage(*argv);
return 0;
}
bool nullTerm = false;
bool stringData = false;
if (restArg.contains("--null-terminated"))
nullTerm = true;
if (restArg.contains("--string"))
{
stringData = true;
nullTerm = true;
}
QString outSymbol = finfo.baseName();
outSymbol.replace(".", "_");
QString outFile;
outFile = getNamedOption(restArg, "-o", finfo.fileName() + ".xxd");
outSymbol = getNamedOption(restArg, "--symbol", outSymbol);
QString dataType = stringData ? "char" : "unsigned char";
return writeDump(inFile, outFile,
dataType, "unsigned int",
outSymbol, nullTerm);
}