Skip to content

Commit

Permalink
[TagDumper] Re-write code to use the new helper class.
Browse files Browse the repository at this point in the history
  • Loading branch information
num0005 committed Jul 26, 2021
1 parent 18562d4 commit 6423a7f
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 47 deletions.
140 changes: 93 additions & 47 deletions H2Codez/Common/TagDumper.cpp
Expand Up @@ -5,6 +5,8 @@
#include <boost/property_tree/ptree.hpp>
#include "util/string_util.h"
#include "util/numerical.h"
#include "util/XMLWriter.h"
#include <fstream>

using boost::property_tree::ptree;
using boost::property_tree::write_xml;
Expand Down Expand Up @@ -98,12 +100,12 @@ static size_t get_static_element_size(tag_field::field_type type)
}
}

static void dump_tag_block(tag_block_ref *block, ptree &tree);
static size_t dump_tag_element(tag_field *fields, char *data, ptree &tree);
static size_t dump_tag_field(tag_field **fields_pointer, char *data, ptree &tree);
static size_t dump_tag_array(tag_field *fields, char *data, ptree &tree);
static void dump_tag_block(XMLWriter& writer, tag_block_ref *block);
static size_t dump_tag_element(XMLWriter& writer, tag_field *fields, char *data);
static size_t dump_tag_field(XMLWriter& writer, tag_field **fields_pointer, char *data);
static size_t dump_tag_array(XMLWriter& writer, tag_field **fields, char *data);

static size_t dump_tag_field(tag_field **fields_pointer, char *data, ptree &tree)
static size_t dump_tag_field(XMLWriter& writer, tag_field **fields_pointer, char *data)
{
ASSERT_CHECK(data != nullptr);
ASSERT_CHECK(fields_pointer != nullptr);
Expand All @@ -116,40 +118,67 @@ static size_t dump_tag_field(tag_field **fields_pointer, char *data, ptree &tree
name = name.substr(0, name.find_first_of('#'));

if (fields->type == tag_field::block) {
ptree &block_tree = tree.add("block", "");
block_tree.add("<xmlattr>.name", name);
tag_block_ref *block = reinterpret_cast<tag_block_ref*>(data);
dump_tag_block(block, block_tree);
tag_block_ref* block = reinterpret_cast<tag_block_ref*>(data);
std::map<FastString, FastString> attributes = { {"name", name} };

writer.write(
"block",
[block](XMLWriter& writer) -> bool {
dump_tag_block(writer, block);
return false;
},
attributes
);
}
else if (fields->type == tag_field::struct_) {
ptree &struct_tree = tree.add("struct", "");
struct_tree.add("<xmlattr>.name", name);
std::map<FastString, FastString> attributes = { {"name", name} };
auto def = reinterpret_cast<tag_struct_defintion*>(fields->defintion);
size_change = dump_tag_element(def->block->latest->fields, data, struct_tree);

writer.write(
"struct",
[def, data, &size_change](XMLWriter& writer) -> bool {
size_change = dump_tag_element(writer, def->block->latest->fields, data);
return false;
},
attributes
);
}
else if (fields->type == tag_field::array_start) {
ptree &array_tree = tree.add("array", "");
array_tree.add("<xmlattr>.name", name);
std::map<FastString, FastString> attributes = { {"name", name} };

size_t count = reinterpret_cast<size_t>(fields->defintion);
tag_field* array_fields;
for (size_t i = 0; i < count; i++)
{
size_change += dump_tag_array(fields, &data[size_change], array_tree);
array_fields = fields;

writer.write(
"struct",
[&array_fields, data, &size_change](XMLWriter& writer) -> bool {
size_change += dump_tag_array(writer, &array_fields, &data[size_change]);
return false;
},
attributes
);


}
while (fields->type != tag_field::array_end && fields->type != tag_field::terminator)
fields++;
LOG_CHECK(fields->type == tag_field::array_end);
*fields_pointer = fields;
LOG_CHECK(array_fields->type == tag_field::array_end);
*fields_pointer = array_fields;
}
else if (fields->type == tag_field::tag_reference) {


tag_reference *tag_ref = reinterpret_cast<tag_reference *>(data);
std::string tag_path = tag_ref->tag_name ? tag_ref->tag_name : "NONE";
ptree &ref_tree = tree.add("tag_reference", tag_path);
ref_tree.add("<xmlattr>.name", name);
ref_tree.add("<xmlattr>.type", tag_ref->tag_type.as_string());

std::map<FastString, FastString> attributes = { {"name", name}, {"type", tag_ref->tag_type.as_string()} };

writer.write_self_closing("tag_reference", tag_path, attributes);
}
else {
std::string value;
std::map<std::string, std::string> attributes;
std::map<FastString, FastString> attributes;
attributes["type"] = tag_field_type_names[fields->type];
attributes["name"] = name;

Expand Down Expand Up @@ -378,58 +407,75 @@ static size_t dump_tag_field(tag_field **fields_pointer, char *data, ptree &tree
LOG_FUNC("handling for %s is missing", tag_field_type_names[fields->type]);
break;
}
ptree &field_tree = tree.add("field", value);

for (auto attribute : attributes)
field_tree.add("<xmlattr>." + attribute.first, attribute.second);
writer.write_self_closing("field", value, attributes);
}
return size_change;
}

static size_t dump_tag_array(tag_field *fields, char *data, ptree &tree)
static size_t dump_tag_array(XMLWriter& writer, tag_field **fields, char *data)
{
ASSERT_CHECK(fields->type == tag_field::array_start);
ASSERT_CHECK((*fields)->type == tag_field::array_start);
size_t offset = 0;
for (fields++; fields->type != tag_field::array_end; fields++)
offset += dump_tag_field(&fields, &data[offset], tree);
for (*fields = ++(*fields); (*fields)->type != tag_field::array_end; *fields = ++(*fields))
offset += dump_tag_field(writer, fields, &data[offset]);
return offset;
}

static size_t dump_tag_element(tag_field *fields, char *data, ptree &tree)
static size_t dump_tag_element(XMLWriter& writer, tag_field *fields, char *data)
{
size_t offset = 0;
for (;fields->type != tag_field::terminator; fields++)
offset += dump_tag_field(&fields, &data[offset], tree);
offset += dump_tag_field(writer, &fields, &data[offset]);
return offset;
}

static void dump_tag_block(tag_block_ref *block, ptree &tree)
static void dump_tag_block(XMLWriter &writer, tag_block_ref *block)
{
tag_field *fields = block->defination->latest->fields;
for (int32_t idx = 0; idx < block->size; idx++)
{
ptree &element_tree = tree.add("element", "");
element_tree.add("<xmlattr>.index", idx);
char *element = reinterpret_cast<char*>(block->get_element(idx));
dump_tag_element(fields, element, element_tree);
char* element = reinterpret_cast<char*>(block->get_element(idx));

writer.write(
"element",
[idx](std::map<FastString, FastString>& attributes) {
attributes["index"] = std::to_string(idx);
},
[element, fields](XMLWriter& writer) -> bool {
dump_tag_element(writer, fields, element);
return false;
}
);
}
}

class TagDumperImpl : XMLWriter {
public:
TagDumperImpl(const std::string& name) : filestream(name), XMLWriter(filestream) {};

void dump(datum tag) {
tag_block_ref *root = tags::get_root_block(tag);
this->write(
"tag",
[root](XMLWriter& writer) -> bool {
dump_tag_block(writer, root);
return false;
}
);
}

std::ofstream filestream;
};

bool TagDumper::dump_as_xml(datum tag, std::string xml_dump_name)
{
ptree tree;
ptree &tag_tree = tree.add("tag", "");
dump_tag_block(tags::get_root_block(tag), tag_tree);

xml_dump_name += ".xml";

printf("Saving to %s\n", xml_dump_name.c_str());

write_xml(
xml_dump_name,
tree,
std::locale(),
xml_writer_settings<std::string>('\t', 1)
);
TagDumperImpl output(xml_dump_name);
output.dump(tag);

return true;
}
2 changes: 2 additions & 0 deletions H2Codez/H2Codez.vcxproj
Expand Up @@ -205,6 +205,7 @@
<ClInclude Include="HaloScript\hs_global_variable.h" />
<ClInclude Include="HaloScript\hs_opcodes.h" />
<ClInclude Include="HaloScript\hs_types.h" />
<ClInclude Include="util\FastString.h" />
<ClInclude Include="util\FileSystem.h" />
<ClInclude Include="util\FileWatcher.h" />
<ClInclude Include="util\Logs.h" />
Expand All @@ -223,6 +224,7 @@
<ClInclude Include="util\StringEndianess.h" />
<ClInclude Include="util\string_util.h" />
<ClInclude Include="util\Time.h" />
<ClInclude Include="util\XMLWriter.h" />
<ClInclude Include="Version.h" />
</ItemGroup>
<ItemGroup>
Expand Down

0 comments on commit 6423a7f

Please sign in to comment.