18std::string lower_extension(
const std::string& destination) {
19 std::string extension = std::filesystem::path(destination).extension().string();
20 std::transform(extension.begin(), extension.end(), extension.begin(),
21 [](
unsigned char c) { return static_cast<char>(std::tolower(c)); });
25void ensure_parent_directory(
const std::string& destination) {
26 const auto parent = std::filesystem::path(destination).parent_path();
27 if (!parent.empty()) {
28 std::error_code error;
29 std::filesystem::create_directories(parent, error);
31 throw std::runtime_error(
32 "FileWriter: cannot create output directory '" + parent.string() +
33 "': " + error.message()
39std::shared_ptr<BlockAccessor> source_for_parameter(
41 const std::shared_ptr<BlockAccessor>& fallback
43 if (!parameter_id.
type.has_value()) {
48 if (!parameters || !parameters->get_block_accessor()) {
49 throw std::invalid_argument(
50 "FileWriter: no parameter repository is available for the requested ParamId"
53 return parameters->get_block_accessor();
58std::shared_ptr<BlockAccessor> FileWriter::resolve_source(std::shared_ptr<BlockAccessor> src) {
64 if (!memory_manager || !memory_manager->is_ready()) {
65 throw std::logic_error(
66 "FileWriter: HyperIso must be initialized before exporting the current database"
69 return memory_manager->extract_block_accessor();
72void FileWriter::write_accessor(
73 const std::string& dest,
74 const std::shared_ptr<BlockAccessor>& src
77 throw std::invalid_argument(
"FileWriter: source BlockAccessor is null");
80 ensure_parent_directory(dest);
82 std::error_code remove_error;
83 std::filesystem::remove(dest, remove_error);
85 throw std::runtime_error(
86 "FileWriter: cannot replace output file '" + dest +
"': " +
87 remove_error.message()
91 auto node = std::make_shared<DBNode>();
94 const std::string extension = lower_extension(dest);
95 if (extension ==
".json") {
97 }
else if (extension ==
".yaml" || extension ==
".yml") {
99 }
else if (extension ==
".lha" || extension ==
".slha" || extension ==
".flha") {
102 throw std::invalid_argument(
103 "FileWriter: unsupported output extension '" + extension +
104 "'; expected .json, .yaml, .yml, .lha, .slha or .flha"
108 std::error_code error;
109 const bool exists = std::filesystem::is_regular_file(dest, error);
110 if (error || !exists) {
111 throw std::runtime_error(
"FileWriter: output file was not created: " + dest);
116 write_accessor(dest, resolve_source(std::move(src)));
120 const std::string& dest,
121 const std::vector<BlockName>& block_names,
122 std::shared_ptr<BlockAccessor> src
124 if (block_names.empty()) {
125 throw std::invalid_argument(
"FileWriter: block_names must not be empty");
128 const auto source = resolve_source(std::move(src));
129 auto selected = std::make_shared<BlockAccessor>();
131 for (
const auto& block_name : block_names) {
132 if (!source->contains(block_name)) {
133 throw std::invalid_argument(
134 "FileWriter: requested block '" + block_name.canonical() +
"' does not exist"
137 selected->emplace(block_name, source->at(block_name)->deep_clone_plain());
140 write_accessor(dest, selected);
144 const std::string& dest,
145 const std::vector<ParamId>& parameter_ids,
146 std::shared_ptr<BlockAccessor> src
148 if (parameter_ids.empty()) {
149 throw std::invalid_argument(
"FileWriter: parameter_ids must not be empty");
152 const auto fallback = resolve_source(std::move(src));
153 auto selected = std::make_shared<BlockAccessor>();
155 for (
const auto& parameter_id : parameter_ids) {
156 const auto source = source_for_parameter(parameter_id, fallback);
157 if (!source->has_param(parameter_id.
block, parameter_id.
code)) {
158 throw std::invalid_argument(
159 "FileWriter: requested parameter '" + parameter_id.
block.
canonical() +
164 if (!selected->contains(parameter_id.
block)) {
165 auto block = std::make_shared<Block>();
166 block->blockname = parameter_id.
block;
168 const auto source_block = source->at(parameter_id.
block);
169 if (source_block->has_scale()) {
170 block->set_scale(source_block->get_scale());
172 selected->emplace(parameter_id.
block, block);
175 auto destination_block = selected->at(parameter_id.
block);
176 if (!destination_block->contains(parameter_id.
code)) {
177 const auto source_parameter = source->getParameter(
181 destination_block->store(
183 std::make_shared<Parameter>(*source_parameter)
188 write_accessor(dest, selected);
Export the current HyperIso parameter database to JSON, YAML or LHA.
Lightweight JSON parser/serializer for DBNode trees.
Parser for LHA / FLHA-style files into LhaBlock structures and DBNode trees.
Manages memory caching, parameter blocks, and LHA reader instances.
Write parameter blocks from a BlockAccessor into a DBNode.
Model-dependent parameter repository and initialization strategies.
Lightweight YAML parser/serializer for DBNode trees.
const std::string & canonical() const
void write_blocks(const std::string &dest, const std::vector< BlockName > &block_names, std::shared_ptr< BlockAccessor > src=nullptr)
Export only the requested blocks.
void write_parameters(const std::string &dest, const std::vector< ParamId > ¶meter_ids, std::shared_ptr< BlockAccessor > src=nullptr)
Export only the requested block/id parameters.
void write(const std::string &dest, std::shared_ptr< BlockAccessor > src=nullptr) override
Export all blocks from an accessor or from the current database.
JSON implementation of the IParser interface.
void writeToFile(const std::string &filename, const std::shared_ptr< DBNode > &root) const override
Serializes a DBNode tree to a JSON file.
Parser for LHA/FLHA files, producing blocks and a DBNode representation.
void writeToFile(const std::string &filename, const std::shared_ptr< DBNode > &root) const
Serializes a DBNode structure back to an LHA-like file.
static MemoryManager * GetInstance()
Retrieves the singleton instance of MemoryManager.
Writer class to populate a DbNode from a BlockAccessor.
void write(std::shared_ptr< DBNode > dest, std::shared_ptr< BlockAccessor > src) override
Write node parameters from a BlockAccessor into the given destination node.
static std::shared_ptr< Parameters > GetInstance(ParameterType id=ParameterType::SM)
Returns the singleton-like repository for a given parameter type.
YAML implementation of the IParser interface.
void writeToFile(const std::string &filename, const std::shared_ptr< DBNode > &root) const override
Writes a DBNode hierarchy to a YAML file.
std::string to_string() const
Returns the canonical string representation of this LhaID.
Composite identifier for a single parameter.
std::optional< ParameterType > type
Optional high-level parameter category.
BlockName block
Name of the block where the parameter is stored.
LhaID code
Index or multi-index of the parameter inside the block.