5#include "absl/strings/str_format.h"
16 return absl::FailedPreconditionError(
"ROM must be loaded");
20 formatter.
AddField(
"size", absl::StrFormat(
"0x%X", rom->
size()));
21 formatter.
AddField(
"size_bytes",
static_cast<int>(rom->
size()));
23 return absl::OkStatus();
30 return absl::FailedPreconditionError(
"ROM must be loaded");
34 std::vector<std::string> validation_results;
38 validation_results.push_back(
"checksum: PASSED");
40 validation_results.push_back(
"checksum: FAILED");
45 if (rom->
title() ==
"THE LEGEND OF ZELDA") {
46 validation_results.push_back(
"header: PASSED");
48 validation_results.push_back(
49 "header: FAILED (Invalid title: " + rom->
title() +
")");
53 formatter.
AddField(
"validation_passed", all_ok);
54 std::string results_str;
55 for (
const auto& result : validation_results) {
56 if (!results_str.empty())
58 results_str += result;
60 formatter.
AddField(
"results", results_str);
62 return absl::OkStatus();
68 auto rom_a_opt = parser.
GetString(
"rom_a");
69 auto rom_b_opt = parser.
GetString(
"rom_b");
71 if (!rom_a_opt.has_value()) {
72 return absl::InvalidArgumentError(
"Missing required argument: rom_a");
74 if (!rom_b_opt.has_value()) {
75 return absl::InvalidArgumentError(
"Missing required argument: rom_b");
78 std::string rom_a_path = rom_a_opt.value();
79 std::string rom_b_path = rom_b_opt.value();
94 formatter.
AddField(
"size_match",
false);
95 formatter.
AddField(
"size_a",
static_cast<int>(rom_a.
size()));
96 formatter.
AddField(
"size_b",
static_cast<int>(rom_b.
size()));
97 return absl::OkStatus();
101 std::vector<std::string> diff_details;
103 for (
size_t i = 0; i < rom_a.
size(); ++i) {
106 if (differences <= 10) {
107 diff_details.push_back(absl::StrFormat(
"0x%08X: 0x%02X vs 0x%02X", i,
114 formatter.
AddField(
"identical", differences == 0);
115 formatter.
AddField(
"differences_count", differences);
116 if (!diff_details.empty()) {
117 std::string diff_str;
118 for (
const auto& diff : diff_details) {
119 if (!diff_str.empty())
123 formatter.
AddField(
"differences", diff_str);
126 return absl::OkStatus();
132 auto rom_opt = parser.
GetString(
"rom_file");
133 auto golden_opt = parser.
GetString(
"golden_file");
135 if (!rom_opt.has_value()) {
136 return absl::InvalidArgumentError(
"Missing required argument: rom_file");
138 if (!golden_opt.has_value()) {
139 return absl::InvalidArgumentError(
"Missing required argument: golden_file");
142 std::string rom_path = rom_opt.value();
143 std::string golden_path = golden_opt.value();
151 std::ofstream file(golden_path, std::ios::binary);
152 if (!file.is_open()) {
153 return absl::NotFoundError(
"Could not open file for writing: " +
157 file.write(
reinterpret_cast<const char*
>(source_rom.
vector().data()),
160 formatter.
AddField(
"status",
"success");
161 formatter.
AddField(
"golden_file", golden_path);
162 formatter.
AddField(
"source_file", rom_path);
163 formatter.
AddField(
"size",
static_cast<int>(source_rom.
size()));
165 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status LoadFromFile(const std::string &filename, const LoadOptions &options=LoadOptions::Defaults())
const auto & vector() const
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)