// Copyright Epic Games, Inc. All Rights Reserved. #include "print.h" #include #include #include #include #include #include #include using namespace std::literals; namespace zen { static void PrintCbObject(CbObject Object) { zen::StringBuilder<1024> ObjStr; zen::CompactBinaryToJson(Object, ObjStr); zen::ConsoleLog().info("{}", ObjStr); } static void PrintCbObject(IoBuffer Data) { zen::CbObject Object{SharedBuffer(Data)}; PrintCbObject(Object); } PrintCommand::PrintCommand() { m_Options.add_options()("h,help", "Print help"); m_Options.add_option("", "s", "source", "Object payload file", cxxopts::value(m_Filename), ""); } PrintCommand::~PrintCommand() = default; int PrintCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions, argc, argv); m_Options.parse_positional({"source"}); auto result = m_Options.parse(argc, argv); if (result.count("help")) { std::cout << m_Options.help({"", "Group"}) << std::endl; return 0; } // Validate arguments if (m_Filename.empty()) throw std::runtime_error("No file specified"); zen::FileContents Fc; if (m_Filename == "-") { Fc = zen::ReadStdIn(); } else { Fc = zen::ReadFile(m_Filename); } if (Fc.ErrorCode) { zen::ConsoleLog().error("Failed to read file '{}': {}", m_Filename, Fc.ErrorCode.message()); return 1; } IoBuffer Data = Fc.Flatten(); if (CompressedBuffer Compressed{CompressedBuffer::FromCompressed(SharedBuffer(Data))}) { zen::ConsoleLog().info("Compressed binary: size {}, raw size {}, hash: {}", Compressed.GetCompressedSize(), Compressed.GetRawSize(), IoHash::FromBLAKE3(Compressed.GetRawHash())); } else if (IsPackageMessage(Data)) { CbPackage Package = ParsePackageMessage(Data); CbObject Object = Package.GetObject(); std::span Attachments = Package.GetAttachments(); zen::ConsoleLog().info("Package - {} attachments, object hash {}", Package.GetAttachments().size(), Package.GetObjectHash()); zen::ConsoleLog().info(""); int AttachmentIndex = 1; for (const CbAttachment& Attachment : Attachments) { std::string AttachmentSize = "n/a"; const char* AttachmentType = "unknown"; if (Attachment.IsCompressedBinary()) { AttachmentType = "Compressed"; AttachmentSize = fmt::format("{} ({} uncompressed)", Attachment.AsCompressedBinary().GetCompressedSize(), Attachment.AsCompressedBinary().GetRawSize()); } else if (Attachment.IsBinary()) { AttachmentType = "Binary"; AttachmentSize = fmt::format("{}", Attachment.AsBinary().GetSize()); } else if (Attachment.IsObject()) { AttachmentType = "Object"; AttachmentSize = fmt::format("{}", Attachment.AsObject().GetSize()); } else if (Attachment.IsNull()) { AttachmentType = "null"; } zen::ConsoleLog().info("Attachment #{} : {}, {}, size {}", AttachmentIndex, Attachment.GetHash(), AttachmentType, AttachmentSize); ++AttachmentIndex; } zen::ConsoleLog().info("---8<---"); PrintCbObject(Object); } else if (CbValidateError Result = ValidateCompactBinary(Data, CbValidateMode::All); Result == CbValidateError::None) { PrintCbObject(Data); } else { zen::ConsoleLog().error("Data in file '{}' does not appear to be compact binary (validation error {:#x})", m_Filename, uint32_t(Result)); return 1; } return 0; } ////////////////////////////////////////////////////////////////////////// PrintPackageCommand::PrintPackageCommand() { m_Options.add_options()("h,help", "Print help"); m_Options.add_option("", "s", "source", "Package payload file", cxxopts::value(m_Filename), ""); } PrintPackageCommand::~PrintPackageCommand() { } int PrintPackageCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions, argc, argv); m_Options.parse_positional({"source"}); auto result = m_Options.parse(argc, argv); if (result.count("help")) { std::cout << m_Options.help({"", "Group"}) << std::endl; return 0; } // Validate arguments if (m_Filename.empty()) throw std::runtime_error("No file specified"); zen::FileContents Fc = zen::ReadFile(m_Filename); IoBuffer Data = Fc.Flatten(); zen::CbPackage Package; bool Ok = Package.TryLoad(Data) || zen::legacy::TryLoadCbPackage(Package, Data, &UniqueBuffer::Alloc); if (Ok) { zen::StringBuilder<1024> ObjStr; zen::CompactBinaryToJson(Package.GetObject(), ObjStr); zen::ConsoleLog().info("{}", ObjStr); } else { zen::ConsoleLog().error("error: malformed package?"); } return 0; } } // namespace zen