collection_link.cpp (4712B)
1 #include "collection_link.hpp" 2 #include "../context.hpp" 3 #include "../cstring_item.hpp" 4 #include "../eof_item.hpp" 5 #include "../raw_item.hpp" 6 #include "../../sink.hpp" 7 8 #include <libshit/container/vector.lua.hpp> 9 10 namespace Neptools::Stcm 11 { 12 13 void CollectionLinkHeaderItem::Header::Validate(FilePosition file_size) const 14 { 15 #define VALIDATE(x) \ 16 LIBSHIT_VALIDATE_FIELD("Stcm::CollectionLinkHeaderItem::Header", x) 17 18 VALIDATE(field_00 == 0); 19 VALIDATE(offset <= file_size); 20 VALIDATE(offset + sizeof(CollectionLinkItem::Entry)*count <= file_size); 21 VALIDATE(field_0c == 0); 22 VALIDATE(field_10 == 0 && field_14 == 0 && field_18 == 0 && field_1c == 0); 23 VALIDATE(field_20 == 0 && field_24 == 0 && field_28 == 0 && field_2c == 0); 24 VALIDATE(field_30 == 0 && field_34 == 0 && field_38 == 0 && field_3c == 0); 25 #undef VALIDATE 26 } 27 28 void CollectionLinkItem::Entry::Validate(FilePosition file_size) const 29 { 30 #define VALIDATE(x) LIBSHIT_VALIDATE_FIELD("Stcm::CollectionLinkItem::Entry", x) 31 VALIDATE(name_0 <= file_size); 32 VALIDATE(name_1 <= file_size); 33 VALIDATE(ptr == 0); 34 VALIDATE(field_0c == 0); 35 VALIDATE(field_10 == 0 && field_14 == 0 && field_18 == 0 && field_1c == 0); 36 #undef VALIDATE 37 } 38 39 CollectionLinkHeaderItem::CollectionLinkHeaderItem( 40 Key k, Context& ctx, const Header& s) 41 : Item{k, ctx}, 42 data{(s.Validate(ctx.GetSize()), 43 ctx.CreateLabelFallback("collection_link", s.offset))} 44 {} 45 46 CollectionLinkHeaderItem& CollectionLinkHeaderItem::CreateAndInsert( 47 ItemPointer ptr) 48 { 49 auto x = RawItem::Get<Header>(ptr); 50 auto& ret = x.ritem.SplitCreate<CollectionLinkHeaderItem>(ptr.offset, x.t); 51 52 auto ptr2 = ret.data->GetPtr(); 53 auto* ritem2 = ptr2.Maybe<RawItem>(); 54 if (!ritem2) 55 { 56 // HACK! 57 LIBSHIT_VALIDATE_FIELD( 58 "Stcm::CollectionLinkHeaderItem", 59 ptr2.offset == 0 && x.t.count == 0); 60 auto& eof = ptr2.AsChecked0<EofItem>(); 61 auto ctx = eof.GetContext(); 62 eof.Replace(ctx->Create<CollectionLinkItem>()); 63 return ret; 64 } 65 66 auto e = RawItem::GetSource( 67 ptr2, x.t.count*sizeof(CollectionLinkItem::Entry)); 68 69 e.ritem.SplitCreate<CollectionLinkItem>(ptr2.offset, e.src, x.t.count); 70 71 return ret; 72 } 73 74 void CollectionLinkHeaderItem::Dump_(Sink& sink) const 75 { 76 Header hdr{}; 77 hdr.offset = ToFilePos(data->GetPtr()); 78 hdr.count = data->GetPtr().AsChecked0<CollectionLinkItem>().entries.size(); 79 sink.WriteGen(hdr); 80 } 81 82 void CollectionLinkHeaderItem::Inspect_( 83 std::ostream& os, unsigned indent) const 84 { 85 Item::Inspect_(os, indent); 86 os << "collection_link_header(" << PrintLabel(data) << ")"; 87 } 88 89 CollectionLinkItem::CollectionLinkItem( 90 Key k, Context& ctx, Source src, uint32_t count) 91 : Item{k, ctx} 92 { 93 ADD_SOURCE(Parse_(ctx, src, count), src); 94 } 95 96 void CollectionLinkItem::Dispose() noexcept 97 { 98 entries.clear(); 99 Item::Dispose(); 100 } 101 102 void CollectionLinkItem::Parse_(Context& ctx, Source& src, uint32_t count) 103 { 104 entries.reserve(count); 105 for (uint32_t i = 0; i < count; ++i) 106 { 107 auto e = src.ReadGen<Entry>(); 108 e.Validate(ctx.GetSize()); 109 110 LabelPtr label0, label1; 111 if (e.name_0) 112 { 113 auto& str0 = MaybeCreate<CStringItem>(ctx.GetPointer(e.name_0)); 114 label0 = ctx.GetLabelTo(e.name_0, str0.GetLabelName()); 115 } 116 117 if (e.name_1) 118 { 119 auto& str1 = MaybeCreate<CStringItem>(ctx.GetPointer(e.name_1)); 120 label1 = ctx.GetLabelTo(e.name_1, str1.GetLabelName()); 121 } 122 123 entries.emplace_back(label0, label1); 124 } 125 } 126 127 void CollectionLinkItem::Dump_(Sink& sink) const 128 { 129 Entry ee{}; 130 for (const auto& e : entries) 131 { 132 ee.name_0 = e.name_0 ? ToFilePos(e.name_0->GetPtr()) : 0; 133 ee.name_1 = e.name_1 ? ToFilePos(e.name_1->GetPtr()) : 0; 134 sink.WriteGen(ee); 135 } 136 } 137 138 void CollectionLinkItem::Inspect_(std::ostream& os, unsigned indent) const 139 { 140 Item::Inspect_(os, indent); 141 142 os << "collection_link{\n"; 143 for (const auto& e : entries) 144 { 145 if (!e.name_0 || ! e.name_1) 146 Indent(os, indent+1) << "neptools.stcm.collection_link_item.link_entry(" 147 << PrintLabel(e.name_0) << ", " 148 << PrintLabel(e.name_1) << "),\n"; 149 else 150 Indent(os, indent+1) << '{' << PrintLabel(e.name_0) << ", " 151 << PrintLabel(e.name_1) << "},\n"; 152 } 153 Indent(os, indent) << "}"; 154 } 155 156 } 157 158 LIBSHIT_STD_VECTOR_LUAGEN( 159 stcm_collection_link_item_link_entry, 160 Neptools::Stcm::CollectionLinkItem::LinkEntry); 161 #include "collection_link.binding.hpp"