header.cpp (2815B)
1 #include "header.hpp" 2 3 #include "collection_link.hpp" 4 #include "expansion.hpp" 5 #include "exports.hpp" 6 #include "../context.hpp" 7 #include "../../sink.hpp" 8 #include "../../utils.hpp" 9 10 #include <libshit/string_utils.hpp> 11 12 #include <stdexcept> 13 #include <iostream> 14 15 namespace Neptools::Stcm 16 { 17 18 void HeaderItem::Header::Validate(FilePosition file_size) const 19 { 20 #define VALIDATE(x) LIBSHIT_VALIDATE_FIELD("Stcm::HeaderItem::Header", x) 21 VALIDATE(memcmp(magic, "STCM2", 5) == 0); 22 VALIDATE(endian == 'L'); 23 VALIDATE(msg.is_valid()); 24 VALIDATE(export_offset < file_size - 0x28*export_count); 25 VALIDATE(collection_link_offset < file_size); 26 VALIDATE(field_30 == 0); 27 VALIDATE(expansion_count == 0 || expansion_offset != 0); 28 VALIDATE(expansion_offset < file_size - 0x50*expansion_count); 29 #undef VALIDATE 30 } 31 32 HeaderItem::HeaderItem(Key k, Context& ctx, const Header& hdr) 33 : Item{k, ctx}, export_sec{Libshit::EmptyNotNull{}}, 34 collection_link{Libshit::EmptyNotNull{}} 35 { 36 hdr.Validate(ctx.GetSize()); 37 38 msg = hdr.msg; 39 export_sec = ctx.CreateLabelFallback("exports", hdr.export_offset); 40 collection_link = ctx.CreateLabelFallback( 41 "collection_link_hdr", hdr.collection_link_offset);; 42 if (hdr.expansion_offset != 0) 43 expansion = ctx.CreateLabelFallback("expansion", hdr.expansion_offset); 44 field_28 = hdr.field_28; 45 } 46 47 HeaderItem& HeaderItem::CreateAndInsert(ItemPointer ptr) 48 { 49 auto x = RawItem::Get<Header>(ptr); 50 51 auto& ret = x.ritem.SplitCreate<HeaderItem>(ptr.offset, x.t); 52 CollectionLinkHeaderItem::CreateAndInsert(ret.collection_link->GetPtr()); 53 if (ret.expansion) 54 ExpansionsItem::CreateAndInsert(ret.expansion->GetPtr(), 55 x.t.expansion_count); 56 ExportsItem::CreateAndInsert(ret.export_sec->GetPtr(), x.t.export_count); 57 return ret; 58 } 59 60 void HeaderItem::Dump_(Sink& sink) const 61 { 62 Header hdr{}; 63 memcpy(hdr.magic, "STCM2", 5); 64 hdr.endian = 'L'; 65 hdr.msg = msg; 66 hdr.export_offset = ToFilePos(export_sec->GetPtr()); 67 hdr.export_count = export_sec->GetPtr().As0<ExportsItem>().entries.size(); 68 hdr.field_28 = field_28; 69 hdr.collection_link_offset = ToFilePos(collection_link->GetPtr()); 70 if (expansion) 71 { 72 hdr.expansion_offset = ToFilePos(expansion->GetPtr()); 73 hdr.expansion_count = expansion->GetPtr().As0<ExpansionsItem>(). 74 GetChildren().size(); 75 } 76 77 sink.WriteGen(hdr); 78 } 79 80 void HeaderItem::Inspect_(std::ostream& os, unsigned indent) const 81 { 82 Item::Inspect_(os, indent); 83 84 os << "header(" << Libshit::Quoted(msg.c_str()) << ", " 85 << PrintLabel(export_sec) << ", " << PrintLabel(collection_link) << ", " 86 << field_28 << ", " << PrintLabel(expansion) << ")"; 87 } 88 89 } 90 91 #include "header.binding.hpp"