diff --git a/src/nostalgia/tools/pack.cpp b/src/nostalgia/tools/pack.cpp index e0ef13ca..b3a98642 100644 --- a/src/nostalgia/tools/pack.cpp +++ b/src/nostalgia/tools/pack.cpp @@ -39,7 +39,7 @@ static ox::Error run(const ox::ClArgs &args) noexcept { oxReturnError(dst.resize()); oxRequire(dstSize, dst.size()); - oxOutf("new size: {}\n", dstSize); + oxOutf("new size: {} bytes\n", dstSize); buff.resize(dstSize); oxReturnError(writeFileBuff(argDst, buff)); diff --git a/src/nostalgia/tools/pack/CMakeLists.txt b/src/nostalgia/tools/pack/CMakeLists.txt index 8468788e..bd8382b9 100644 --- a/src/nostalgia/tools/pack/CMakeLists.txt +++ b/src/nostalgia/tools/pack/CMakeLists.txt @@ -15,3 +15,10 @@ install( ARCHIVE DESTINATION lib/nostalgia ) + +install( + FILES + pack.hpp + DESTINATION + include/nostalgia/tools/pack +) diff --git a/src/nostalgia/tools/pack/pack.cpp b/src/nostalgia/tools/pack/pack.cpp index 87ecb3df..2b0f46d1 100644 --- a/src/nostalgia/tools/pack/pack.cpp +++ b/src/nostalgia/tools/pack/pack.cpp @@ -4,52 +4,82 @@ #include #include +#include +#include +#include #include #include +#include #include "pack.hpp" namespace nostalgia { +static ox::Error pathToInode(ox::FileSystem *dest, ox::ModelObject *obj) noexcept { + auto &o = *obj; + auto type = static_cast(o["type"].get()); + auto &data = o["data"].get(); + ox::String path; + switch (type) { + case ox::FileAddressType::Path: + path = data["path"].get(); + break; + case ox::FileAddressType::ConstPath: + path = data["constPath"].get(); + break; + case ox::FileAddressType::Inode: + case ox::FileAddressType::None: + return OxError(0); + } + oxRequire(s, dest->stat(path.c_str())); + oxReturnError(o["type"].set(static_cast(ox::FileAddressType::Inode))); + return data.set(2, s.inode); +} + /** * Convert path references in Claw data to inodes to save space * @param buff buffer holding file * @return error * stub for now */ -static ox::Result pathToInode(const ox::Buffer &buff) noexcept { - return std::move(buff); -} - -// just strip header for now... -static ox::Result toMetalClaw(const ox::Buffer &buff) noexcept { - oxRequire(hdr, ox::readClawHeader(buff)); - if (hdr.fmt != ox::ClawFormat::Metal) { - return OxError(1, "Cannot convert from Claw to MetalClaw, data portion must already be MetalClaw"); +static ox::Error transformObj(ox::FileSystem *dest, ox::ModelObject *obj) noexcept { + for (auto &f : *obj) { + auto &v = f->value; + if (v.type() != ox::ModelValue::Type::Object) { + continue; + } + auto &o = v.get(); + if (o.typeName() == "net.drinkingtea.ox.FileAddress" && o.typeVersion() == 1) { + oxReturnError(pathToInode(dest, &o)); + } else { + oxReturnError(transformObj(dest, &o)); + } } - return ox::stripClawHeader(buff); + return OxError(0); } -static ox::Error doTransformations(ox::FileSystem *dest, const ox::String &filePath) noexcept { +static ox::Error doTransformations(core::TypeStore *ts, ox::FileSystem *dest, const ox::String &filePath) noexcept { if (filePath.endsWith(".ng") || filePath.endsWith(".npal")) { // load file - oxRequireM(buff, dest->read(filePath.c_str())); + oxRequire(s, dest->stat(filePath.c_str())); + oxRequireM(buff, dest->read(s.inode)); if (filePath.endsWith(".ng")) { oxReturnError(core::convertBuffToBuff(buff, ox::ClawFormat::Metal).moveTo(&buff)); } + oxRequireM(obj, ox::readClaw(ts, buff)); // do transformations - oxReturnError(pathToInode(buff).moveTo(&buff)); - oxReturnError(toMetalClaw(buff).moveTo(&buff)); + oxReturnError(transformObj(dest, &obj)); + oxReturnError(ox::writeMC(&obj).moveTo(&buff)); // write file to dest - oxReturnError(dest->write(filePath.c_str(), buff.data(), buff.size())); + oxReturnError(dest->write(s.inode, buff.data(), buff.size())); } return OxError(0); } // claw file transformations are broken out because path to inode // transformations need to be done after the copy to the new FS is complete -static ox::Error transformClaw(ox::FileSystem *dest, const ox::String &path) noexcept { +static ox::Error transformClaw(core::TypeStore *ts, ox::FileSystem *dest, const ox::String &path) noexcept { // copy oxTracef("pack::transformClaw", "path: {}", path); oxRequire(fileList, dest->ls(path)); @@ -58,9 +88,9 @@ static ox::Error transformClaw(ox::FileSystem *dest, const ox::String &path) noe oxRequire(stat, dest->stat(filePath.c_str())); if (stat.fileType == ox::FileType::Directory) { const auto dir = path + name + '/'; - oxReturnError(transformClaw(dest, dir)); + oxReturnError(transformClaw(ts, dest, dir)); } else { - oxReturnError(doTransformations(dest, filePath)); + oxReturnError(doTransformations(ts, dest, filePath)); } } return OxError(0); @@ -75,9 +105,9 @@ static ox::Error verifyFile(ox::FileSystem *fs, const ox::String &path, const ox struct VerificationPair { ox::String path; ox::Buffer buff; - VerificationPair(const ox::String &pPath, const ox::Buffer &pBuff) noexcept { - path = pPath; - buff = pBuff; + VerificationPair(const ox::String &pPath, ox::Buffer pBuff) noexcept: + path(pPath), + buff(std::move(pBuff)) { } }; @@ -115,7 +145,9 @@ static ox::Error copy(ox::FileSystem *src, ox::FileSystem *dest, const ox::Strin ox::Error pack(ox::FileSystem *src, ox::FileSystem *dest) noexcept { oxReturnError(copy(src, dest, "/")); - oxReturnError(transformClaw(dest, "/")); + core::TypeStore ts(src); + oxReturnError(ox::buildTypeDef(&ts)); + oxReturnError(transformClaw(&ts, dest, "/")); return OxError(0); }