gbnl.hpp (4047B)
1 #ifndef UUID_9037C300_D4EF_473C_8387_A1A9797069A7 2 #define UUID_9037C300_D4EF_473C_8387_A1A9797069A7 3 #pragma once 4 5 #include "../dumpable.hpp" 6 #include "../endian.hpp" 7 #include "../source.hpp" 8 #include "../dynamic_struct.hpp" 9 #include "../txt_serializable.hpp" 10 11 #include <libshit/lua/auto_table.hpp> 12 13 #include <boost/endian/arithmetic.hpp> 14 15 #include <optional> 16 #include <vector> 17 18 namespace Neptools 19 { 20 21 class Gbnl : public Dumpable, public TxtSerializable 22 { 23 LIBSHIT_DYNAMIC_OBJECT; 24 public: 25 struct Header // or Footer 26 { 27 char magic[3]; 28 char endian; 29 30 std::uint16_t field_04; 31 std::uint16_t field_06; 32 std::uint32_t field_08; 33 std::uint32_t field_0c; 34 std::uint32_t flags; // 1 if there's a string, 0 otherwise? 35 std::uint32_t descr_offset; 36 std::uint32_t count_msgs; 37 std::uint32_t msg_descr_size; 38 std::uint32_t count_types; 39 std::uint32_t offset_types; 40 std::uint32_t field_28; 41 std::uint32_t offset_msgs; 42 std::uint32_t field_30; 43 std::uint32_t field_34; 44 std::uint32_t field_38; 45 std::uint32_t field_3c; 46 47 void Validate(std::size_t chunk_size) const; 48 }; 49 static_assert(sizeof(Header) == 0x40); 50 51 struct TypeDescriptor 52 { 53 enum Type 54 { 55 INT32 = 0, 56 INT8 = 1, 57 INT16 = 2, 58 FLOAT = 3, 59 STRING = 5, 60 INT64 = 6, 61 }; 62 std::uint16_t type; 63 std::uint16_t offset; 64 }; 65 static_assert(sizeof(TypeDescriptor) == 0x04); 66 67 struct OffsetString 68 { 69 std::string str; 70 uint32_t offset; 71 }; 72 73 struct FixStringTag { char str[1]; }; 74 struct PaddingTag { char pad[1]; }; 75 76 using Struct = DynamicStruct< 77 int8_t, int16_t, int32_t, int64_t, float, OffsetString, 78 FixStringTag, PaddingTag>; 79 using StructPtr = Libshit::NotNull<boost::intrusive_ptr<Struct>>; 80 using Messages = std::vector<StructPtr>; 81 82 Gbnl(Source src); 83 Gbnl(Endian endian, bool is_gstl, uint32_t flags, uint32_t field_28, 84 uint32_t field_30, Libshit::AT<Struct::TypePtr> type) 85 : endian{endian}, is_gstl{is_gstl}, flags{flags}, field_28{field_28}, 86 field_30{field_30}, type{std::move(type.Get())} {} 87 #if LIBSHIT_WITH_LUA 88 Gbnl(Libshit::Lua::StateRef vm, Endian endian, bool is_gstl, uint32_t flags, 89 uint32_t field_28, uint32_t field_30, Libshit::AT<Struct::TypePtr> type, 90 Libshit::Lua::RawTable messages); 91 #endif 92 93 void Fixup() override { RecalcSize(); } 94 95 Endian endian; 96 bool is_gstl; 97 uint32_t flags, field_28, field_30; 98 99 // no setter - it doesn't work how you expect in lua 100 LIBSHIT_LUAGEN(get: "::Libshit::Lua::GetSmartOwnedMember") 101 Messages messages; 102 103 Struct::TypePtr type; 104 105 void RecalcSize(); 106 FilePosition GetSize() const noexcept override; 107 108 Libshit::NotNullSharedPtr<TxtSerializable> GetDefaultTxtSerializable( 109 const Libshit::NotNullSharedPtr<Dumpable>& thiz) override 110 { return Libshit::NotNullSharedPtr<TxtSerializable>{thiz.Get(), this}; } 111 112 protected: 113 // todo: private after removing GbnlItem 114 void Dump_(Sink& sink) const override; 115 void InspectGbnl(std::ostream& os, unsigned indent) const; 116 void Inspect_(std::ostream& os, unsigned indent) const override; 117 118 private: 119 void WriteTxt_(std::ostream& os) const override; 120 void ReadTxt_(std::istream& is) override; 121 122 void Parse_(Source& src); 123 void DumpHeader(Sink& sink) const; 124 void Pad(uint16_t diff, Struct::TypeBuilder& bld, bool& int8_in_progress); 125 FilePosition Align(FilePosition x) const noexcept; 126 127 std::optional<std::int32_t> GetId( 128 bool simple, const Gbnl::Struct& m, size_t i, size_t j, size_t& k) const; 129 size_t FindDst(bool simple, int32_t id, std::vector<StructPtr>& messages, 130 size_t& index) const; 131 132 size_t msg_descr_size, msgs_size; 133 size_t real_item_count; // excluding dummy pad items 134 }; 135 136 void endian_reverse_inplace(Gbnl::Header& hdr); 137 void endian_reverse_inplace(Gbnl::TypeDescriptor& desc); 138 } 139 #endif