From cdeada018b5973c92b0050dad44aa78670ff0f4b Mon Sep 17 00:00:00 2001 From: Jackkal Date: Wed, 25 Sep 2024 21:08:27 +0200 Subject: [PATCH] Graceful handling when dpfile parameter is missing in cid2xml --- src/awe/objectbinaryreadstream.cpp | 16 +++++++ src/awe/objectbinaryreadstream.h | 2 + tools/cid2xml.cpp | 68 ++++++++++++++++-------------- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/awe/objectbinaryreadstream.cpp b/src/awe/objectbinaryreadstream.cpp index 3db5237a..2c9ac987 100644 --- a/src/awe/objectbinaryreadstream.cpp +++ b/src/awe/objectbinaryreadstream.cpp @@ -21,6 +21,7 @@ #include #include "objectbinaryreadstream.h" +#include "src/common/exception.h" namespace AWE { @@ -30,6 +31,11 @@ ObjectBinaryReadStream::ObjectBinaryReadStream(Common::ReadStream &stream) : _st ObjectBinaryReadStream::ObjectBinaryReadStream(Common::ReadStream &stream, std::shared_ptr dp) : _stream(stream), _dp(dp) { } +void ObjectBinaryReadStream::assert_dp() { + if (!_dp) + throw CreateException("dp file expected but not defined"); +} + void ObjectBinaryReadStream::variable(const std::string &name, bool &value) { value = _stream.readByte() != 0; } @@ -51,6 +57,7 @@ void ObjectBinaryReadStream::variable(const std::string &name, float &value) { void ObjectBinaryReadStream::variable(const std::string &name, std::string &value, bool dp) { if (dp) { + assert_dp(); uint32_t offset = _stream.readUint32LE(); value = _dp->getString(offset); } else { @@ -87,6 +94,7 @@ void ObjectBinaryReadStream::variable(const std::string &name, ObjectID &value) } void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); uint32_t offset = _stream.readUint32LE(); std::vector values = _dp->getValues(offset, count); @@ -103,6 +111,7 @@ void ObjectBinaryReadStream::variable(const std::string &name, std::vector void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value, bool dp) { uint32_t count = _stream.readUint32LE(); if (dp) { + assert_dp(); uint32_t offset = _stream.readUint32LE(); std::vector values = _dp->getValues(offset, count); } else { @@ -121,6 +130,7 @@ void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); uint32_t offset = _stream.readUint32LE(); std::vector values = _dp->getValues(offset, count); @@ -128,18 +138,21 @@ void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); uint32_t offset = _stream.readUint32LE(); value = _dp->getPositions2D(offset, count); } void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); uint32_t offset = _stream.readUint32LE(); value = _dp->getFloats(offset, count); } void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); uint32_t offset = _stream.readUint32LE(); std::vector values = _dp->getValues(offset, count); @@ -147,12 +160,14 @@ void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); uint32_t offset = _stream.readUint32LE(); value = _dp->getGIDs(offset, count); } void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value) { + assert_dp(); uint32_t count = _stream.readUint32LE(); value.resize(count); for (unsigned int i = 0; i < count; ++i) { @@ -162,6 +177,7 @@ void ObjectBinaryReadStream::variable(const std::string &name, std::vector &value, size_t fixedSize) { + assert_dp(); value.resize(fixedSize); for (size_t i = 0; i < fixedSize; ++i) { uint32_t offset = _stream.readUint32LE(); diff --git a/src/awe/objectbinaryreadstream.h b/src/awe/objectbinaryreadstream.h index cb29dda4..b5247bde 100644 --- a/src/awe/objectbinaryreadstream.h +++ b/src/awe/objectbinaryreadstream.h @@ -36,6 +36,8 @@ class ObjectBinaryReadStream : public ObjectReadStream { void skip(size_t s) override; + void assert_dp(); + void variable(const std::string &name, bool &value) override; void variable(const std::string &name, int32_t &value) override; void variable(const std::string &name, uint32_t &value, bool bigEndian) override; diff --git a/tools/cid2xml.cpp b/tools/cid2xml.cpp index 58d7b345..b38b870e 100644 --- a/tools/cid2xml.cpp +++ b/tools/cid2xml.cpp @@ -22,6 +22,7 @@ #include +#include #include #include "src/common/writefile.h" @@ -51,45 +52,50 @@ int main(int argc, char **argv) { CLI11_PARSE(app, argc, argv); - // Open cid file as stream - Common::ReadFile cidFileStream(cidFile); + try { + // Open cid file as stream + Common::ReadFile cidFileStream(cidFile); - // Initialize xml object - Common::XML xml; - auto &rootNode = xml.getRootNode(); - rootNode.name = "cid"; + // Initialize xml object + Common::XML xml; + auto &rootNode = xml.getRootNode(); + rootNode.name = "cid"; - // Generate stem and deduce object type from it - const std::string stem = std::filesystem::path(cidFile).stem().string(); - ObjectType type = AWE::determineObjectTypeByFilename(stem); + // Generate stem and deduce object type from it + const std::string stem = std::filesystem::path(cidFile).stem().string(); + ObjectType type = AWE::determineObjectTypeByFilename(stem); - // Load dp file if given - std::shared_ptr dp; - if (!dpFile.empty()) - dp = std::make_shared(new Common::ReadFile(dpFile)); + // Load dp file if given + std::shared_ptr dp; + if (!dpFile.empty()) + dp = std::make_shared(new Common::ReadFile(dpFile)); - AWE::ObjectXMLWriteStream xmlWriteStream(xml.getRootNode()); + AWE::ObjectXMLWriteStream xmlWriteStream(xml.getRootNode()); - // If byte code and bytecode parameters are given, create a bytecode collection - if (!bytecodeFile.empty() && !bytecodeParametersFile.empty()) { - std::shared_ptr collection = std::make_shared( - new Common::ReadFile(bytecodeFile), - new Common::ReadFile(bytecodeParametersFile) - ); - xmlWriteStream.setBytecodeCollection(collection); - } + // If byte code and bytecode parameters are given, create a bytecode collection + if (!bytecodeFile.empty() && !bytecodeParametersFile.empty()) { + std::shared_ptr collection = std::make_shared( + new Common::ReadFile(bytecodeFile), + new Common::ReadFile(bytecodeParametersFile) + ); + xmlWriteStream.setBytecodeCollection(collection); + } - AWE::CIDFile cid(cidFileStream, type, dp); + AWE::CIDFile cid(cidFileStream, type, dp); - rootNode.properties["version"] = std::to_string(cid.getVersion()); + rootNode.properties["version"] = std::to_string(cid.getVersion()); - const auto &containers = cid.getContainers(); - for (const auto &item: containers) { - xmlWriteStream.writeObject(item, type, cid.getVersion()); - } + const auto &containers = cid.getContainers(); + for (const auto &item: containers) { + xmlWriteStream.writeObject(item, type, cid.getVersion()); + } - Common::WriteFile cidXmlStream(stem + ".xml"); - xml.write(cidXmlStream, false); + Common::WriteFile cidXmlStream(stem + ".xml"); + xml.write(cidXmlStream, false); - return EXIT_SUCCESS; + return EXIT_SUCCESS; + } catch (std::exception &e) { + fmt::print("Error: {}\n", e.what()); + return EXIT_FAILURE; + } } \ No newline at end of file