finish cmd

This commit is contained in:
yyc12345 2023-03-04 00:13:03 +08:00
parent 2bdeee9007
commit e166b8ec5b
5 changed files with 186 additions and 61 deletions

View File

@ -13,6 +13,9 @@
/* TODO:
do not re-allocated ctx and file for each loading in future.
this will be implemented by free all objects within doc.
split encoding and temp folder setting
and load command only have file name arg.
*/
namespace Unvirt::CmdHelper {
@ -39,6 +42,7 @@ namespace Unvirt::CmdHelper {
// split
for (auto it = u8cmd.begin(); it != u8cmd.end(); ++it) {
mCmdChar = (*it);
if (!std::isprint(mCmdChar)) continue; // skip all invalid characters
switch (mState) {
case StateType::SPACE:
@ -169,14 +173,14 @@ namespace Unvirt::CmdHelper {
else if (subcmd == "unload") this->ProcUnLoad(cmds);
else if (subcmd == "info") this->ProcInfo(cmds);
else if (subcmd == "ls") this->ProcLs(cmds);
else if (subcmd == "page") this->ProcPage(cmds);
else if (subcmd == "items") this->ProcItems(cmds);
else if (subcmd == "help") this->PrintHelp();
else if (subcmd == "exit") break;
else {
this->PrintCommonError("No such command \"\".", subcmd.c_str());
this->PrintCommonError("No such command \"%s\".", subcmd.c_str());
this->PrintHelp();
}
}
}
@ -192,7 +196,7 @@ namespace Unvirt::CmdHelper {
}
bool InteractiveCmd::HasOpenedFile(void) {
return (m_Ctx != nullptr || m_File == nullptr || m_Doc != nullptr);
return (m_Ctx != nullptr || m_File != nullptr || m_Doc != nullptr);
}
void InteractiveCmd::PrintHelp(void) {
@ -215,9 +219,9 @@ namespace Unvirt::CmdHelper {
fputs("\tDescription: List something about loaded Virtools composition.\n", f);
fputs("\tSyntax: ls <obj | mgr> [page]\n", f);
fputs("page\n", f);
fputs("items\n", f);
fputs("\tDescription: Set up how many items should be listed in one page when using \"ls\" command.\n", f);
fputs("\tSyntax: page <num>\n", f);
fputs("\tSyntax: items <num>\n", f);
fputs("exit\n", f);
fputs("\tDescription: Exit program\n", f);
@ -243,6 +247,7 @@ namespace Unvirt::CmdHelper {
std::vfprintf(stdout, u8_fmt, argptr);
std::fputs(UNVIRT_TERMCOLTAIL, stdout);
va_end(argptr);
std::fputc('\n', stdout);
}
@ -288,13 +293,17 @@ namespace Unvirt::CmdHelper {
if (err != LibCmo::CK2::CKERROR::CKERR_OK) {
// fail to load. release all.
this->PrintCommonError("Fail to open file. Function return: %s\n%s",
Unvirt::AccessibleValue::GetCkErrorName(err),
Unvirt::AccessibleValue::GetCkErrorDescription(err)
Unvirt::AccessibleValue::GetCkErrorName(err).c_str(),
Unvirt::AccessibleValue::GetCkErrorDescription(err).c_str()
);
if (m_Doc != nullptr) delete m_Doc;
if (m_File != nullptr) delete m_File;
if (m_Ctx != nullptr) delete m_Ctx;
m_Doc = nullptr;
m_File = nullptr;
m_Ctx = nullptr;
}
}
@ -309,6 +318,10 @@ namespace Unvirt::CmdHelper {
if (m_Doc != nullptr) delete m_Doc;
if (m_File != nullptr) delete m_File;
if (m_Ctx != nullptr) delete m_Ctx;
m_Doc = nullptr;
m_File = nullptr;
m_Ctx = nullptr;
}
void InteractiveCmd::ProcInfo(const std::deque<std::string>& cmd) {
@ -323,14 +336,54 @@ namespace Unvirt::CmdHelper {
}
void InteractiveCmd::ProcLs(const std::deque<std::string>& cmd) {
// static values of switches
static const std::vector<std::string> c_AllowedSwitches{
"obj", "mgr"
};
// check pre-requirement
if (!HasOpenedFile()) {
this->PrintCommonError("No loaded file.");
return;
}
// check requirement
size_t pos = 0u;
std::string sw;
if (!ArgParser::ParseSwitch(cmd, pos, c_AllowedSwitches, sw)) {
this->PrintArgParseError(cmd, pos);
return;
}
++pos;
int32_t gotten_page;
if (!ArgParser::ParseInt(cmd, pos, gotten_page) || gotten_page <= 0) {
gotten_page = 0; // asssume as zero
}
size_t page = static_cast<size_t>(gotten_page);
// show list
if (sw == c_AllowedSwitches[0]) {
// obj list
if (page * this->m_PageLen >= m_Doc->m_FileObjects.size()) {
this->PrintCommonError("Page out of range.");
return;
}
Unvirt::StructFormatter::PrintObjectList(this->m_Doc->m_FileObjects, page, this->m_PageLen);
} else {
// mgr list
if (page * this->m_PageLen >= m_Doc->m_FileManagersData.size()) {
this->PrintCommonError("Page out of range.");
return;
}
Unvirt::StructFormatter::PrintManagerList(this->m_Doc->m_FileManagersData, page, this->m_PageLen);
}
}
void InteractiveCmd::ProcPage(const std::deque<std::string>& cmd) {
void InteractiveCmd::ProcItems(const std::deque<std::string>& cmd) {
// check requirement
size_t pos = 0u;
int32_t count;

View File

@ -1,6 +1,6 @@
#pragma once
#include <VTUtils.h>
#include <VTUtils.hpp>
#include <CKDefines.hpp>
#include <string>
#include <vector>
@ -152,7 +152,7 @@ namespace Unvirt::CmdHelper {
void ProcUnLoad(const std::deque<std::string>& cmd);
void ProcInfo(const std::deque<std::string>& cmd);
void ProcLs(const std::deque<std::string>& cmd);
void ProcPage(const std::deque<std::string>& cmd);
void ProcItems(const std::deque<std::string>& cmd);
CmdSplitter m_CmdSplitter;
size_t m_PageLen;

View File

@ -2,56 +2,124 @@
#include "AccessibleValue.hpp"
#include "TerminalHelper.hpp"
namespace Unvirt {
namespace StructFormatter {
namespace Unvirt::StructFormatter {
static FILE* fout = stdout;
static FILE* fout = stdout;
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo) {
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo) {
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileInfo\n")), fout);
fprintf(fout, "FileVersion: %" PRIu32 "\n", fileinfo.FileVersion);
fprintf(fout, "CKVersion: %02" PRIX32 "/%02" PRIX32 "/%04" PRIX32 "\n",
(fileinfo.CKVersion >> 24) & 0xFF,
(fileinfo.CKVersion >> 16) & 0xFF,
(fileinfo.CKVersion >> 0) & 0xFFFF
);
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileInfo\n")), fout);
fprintf(fout, "FileVersion: %" PRIu32 "\n", fileinfo.FileVersion);
fprintf(fout, "CKVersion: %02" PRIX32 "/%02" PRIX32 "/%04" PRIX32 "\n",
(fileinfo.CKVersion >> 24) & 0xFF,
(fileinfo.CKVersion >> 16) & 0xFF,
(fileinfo.CKVersion >> 0) & 0xFFFF
);
LibCmo::CK2::CKDWORD product_series[4]{
(fileinfo.ProductBuild >> 24) & 0xFF,
(fileinfo.ProductBuild >> 16) & 0xFF,
(fileinfo.ProductBuild >> 8) & 0xFF,
(fileinfo.ProductBuild >> 0) & 0xFF,
};
fprintf(fout, "Product (Version / Build): %" PRIu32 " / %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "\n",
fileinfo.ProductVersion, product_series[0], product_series[1], product_series[2], product_series[3]
);
LibCmo::CK2::CKDWORD product_series[4]{
(fileinfo.ProductBuild >> 24) & 0xFF,
(fileinfo.ProductBuild >> 16) & 0xFF,
(fileinfo.ProductBuild >> 8) & 0xFF,
(fileinfo.ProductBuild >> 0) & 0xFF,
};
fprintf(fout, "Product (Version / Build): %" PRIu32 " / %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "\n",
fileinfo.ProductVersion, product_series[0], product_series[1], product_series[2], product_series[3]
);
fprintf(fout, "Save Flags: %s\n", Unvirt::AccessibleValue::GetFlagEnumName<LibCmo::CK2::CK_FILE_WRITEMODE>(
Unvirt::AccessibleValue::EnumDesc::CK_FILE_WRITEMODE, fileinfo.FileWriteMode
).c_str());
fprintf(fout, "Save Flags: %s\n", Unvirt::AccessibleValue::GetFlagEnumName<LibCmo::CK2::CK_FILE_WRITEMODE>(
Unvirt::AccessibleValue::EnumDesc::CK_FILE_WRITEMODE, fileinfo.FileWriteMode
).c_str());
fprintf(fout, "File Size: %s\n", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.FileSize).c_str());
fprintf(fout, "File Size: %s\n", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.FileSize).c_str());
fprintf(fout, "Crc: 0x%" PRIX32 "\n", fileinfo.Crc);
fputc('\n', fout);
fprintf(fout, "Crc: 0x%" PRIX32 "\n", fileinfo.Crc);
fputc('\n', fout);
fputs("Hdr1 (Pack / UnPack): ", fout);
fprintf(fout, "%s / ", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.Hdr1PackSize).c_str());
fprintf(fout, "%s\n", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.Hdr1UnPackSize).c_str());
fputs("Hdr1 (Pack / UnPack): ", fout);
fprintf(fout, "%s / ", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.Hdr1PackSize).c_str());
fprintf(fout, "%s\n", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.Hdr1UnPackSize).c_str());
fputs("Data (Pack / UnPack): ", fout);
fprintf(fout, "%s / ", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.DataPackSize).c_str());
fprintf(fout, "%s\n", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.DataUnPackSize).c_str());
fputc('\n', fout);
fputs("Data (Pack / UnPack): ", fout);
fprintf(fout, "%s / ", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.DataPackSize).c_str());
fprintf(fout, "%s\n", Unvirt::AccessibleValue::GetAccessibleFileSize(fileinfo.DataUnPackSize).c_str());
fputc('\n', fout);
fprintf(fout, "Manager Count: %" PRIu32 "\nObject Count: %" PRIu32 "\nMax ID Saved: %" PRIu32 "\n",
fileinfo.ManagerCount, fileinfo.ObjectCount, fileinfo.MaxIDSaved
);
}
fprintf(fout, "Manager Count: %" PRIu32 "\nObject Count: %" PRIu32 "\nMax ID Saved: %" PRIu32 "\n",
fileinfo.ManagerCount, fileinfo.ObjectCount, fileinfo.MaxIDSaved
);
}
static void PrintCKSTRING(const std::string& name) {
if (name.empty()) {
fputs(UNVIRT_TERMCOL_LIGHT_MAGENTA(("<anonymous>")), fout);
} else {
fputs(name.c_str(), fout);
}
}
static void PrintPointer(const void* ptr) {
if (ptr == nullptr) {
fputs(UNVIRT_TERMCOL_LIGHT_CYAN(("<null>")), fout);
} else {
fprintf(fout, "<0x%08zX>", reinterpret_cast<size_t>(ptr));
}
}
static void PrintCKGUID(const LibCmo::CK2::CKGUID& guid) {
fprintf(stdout, "<0x%08" PRIx32 ", 0x%08" PRIx32 ">", guid.d1, guid.d2);
}
void PrintObjectList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileObject>& ls, size_t page, size_t pageitems) {
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileObject\n")), fout);
size_t fulllen = ls.size(),
startpos = page * pageitems,
fullpage = fulllen / pageitems;
// print header
fputs("Index\tCK ID\tCKObject\tCKStateChunk\tName\n", fout);
// print body
for (size_t counter = startpos; counter < fulllen && (counter - startpos) < pageitems; ++counter) {
const auto& obj = ls[counter];
fprintf(stdout, "%zu\t%" PRIu32 "\t", counter, obj.ObjectId);
PrintPointer(obj.ObjPtr);
fputc('\t', fout);
PrintPointer(obj.Data);
fputc('\t', fout);
PrintCKSTRING(obj.Name);
fputc('\n', fout);
}
fprintf(fout, "Page %zu of %zu\n", page, fullpage);
}
void PrintManagerList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileManagerData>& ls, size_t page, size_t pageitems) {
fputs(UNVIRT_TERMCOL_LIGHT_YELLOW(("CKFileManager\n")), fout);
size_t fulllen = ls.size(),
startpos = page * pageitems,
fullpage = fulllen / pageitems;
// print header
fputs("Index\tCKGUID\tCKBaseManager\tCKStateChunk\n", fout);
// print body
for (size_t counter = startpos; counter < fulllen && (counter - startpos) < pageitems; ++counter) {
const auto& mgr = ls[counter];
fprintf(stdout, "%zu\t", counter);
PrintCKGUID(mgr.Manager);
fputc('\t', fout);
PrintPointer(mgr.MgrPtr);
fputc('\t', fout);
PrintPointer(mgr.Data);
fputc('\n', fout);
}
fprintf(fout, "Page %zu of %zu\n", page, fullpage);
}
}

View File

@ -2,10 +2,10 @@
#include <CKFile.hpp>
namespace Unvirt {
namespace StructFormatter {
namespace Unvirt::StructFormatter {
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo);
void PrintCKFileInfo(const LibCmo::CK2::CKFileInfo& fileinfo);
void PrintObjectList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileObject>& ls, size_t page, size_t pageitems);
void PrintManagerList(const LibCmo::CK2::XArray<LibCmo::CK2::CKFileManagerData>& ls, size_t page, size_t pageitems);
}
}

View File

@ -1,6 +1,7 @@
#include "AccessibleValue.hpp"
#include "TerminalHelper.hpp"
#include "StructFormatter.hpp"
#include "CmdHelper.hpp"
#include "CKMinContext.hpp"
#include "CKFile.hpp"
@ -12,16 +13,19 @@ int main(int argc, char* argv[]) {
Unvirt::TerminalHelper::EnsureTerminalColor();
Unvirt::TerminalHelper::EnsureTerminalEncoding();
LibCmo::CK2::CKMinContext vtctx;
vtctx.SetTempPath("Temp");
vtctx.SetEncoding("850");
//LibCmo::CK2::CKMinContext vtctx;
//vtctx.SetTempPath("Temp");
//vtctx.SetEncoding("850");
LibCmo::CK2::CKFile vtfile(&vtctx);
LibCmo::CK2::CKFileDocument* doc;
LibCmo::CK2::CKERROR err = vtfile.DeepLoad("Level_02.NMO", &doc);
//LibCmo::CK2::CKFile vtfile(&vtctx);
//LibCmo::CK2::CKFileDocument* doc;
//LibCmo::CK2::CKERROR err = vtfile.DeepLoad("Level_02.NMO", &doc);
if (doc)
Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);
//if (doc)
// Unvirt::StructFormatter::PrintCKFileInfo(doc->m_FileInfo);
auto cmd = new Unvirt::CmdHelper::InteractiveCmd();
cmd->Run();
delete cmd;
return 0;
}