raw_item.hpp (3475B)
1 #ifndef UUID_49BE292D_0E45_47B1_8901_97A22C0190F6 2 #define UUID_49BE292D_0E45_47B1_8901_97A22C0190F6 3 #pragma once 4 5 #include "context.hpp" 6 #include "../source.hpp" 7 8 #include <libshit/except.hpp> 9 10 namespace Neptools 11 { 12 13 class RawItem final : public Item 14 { 15 LIBSHIT_DYNAMIC_OBJECT; 16 public: 17 RawItem(Key k, Context& ctx, Source src) noexcept 18 : Item{k, ctx}, src{std::move(src)} {} 19 RawItem(Key k, Context& ctx, std::string src) 20 : Item{k, ctx}, src{Source::FromMemory(std::move(src))} {} 21 LIBSHIT_NOLUA 22 RawItem(Key k, Context& ctx, Source src, FilePosition pos) noexcept 23 : Item{k, ctx, pos}, src{std::move(src)} {} 24 25 const Source& GetSource() const noexcept { return src; } 26 FilePosition GetSize() const noexcept override { return src.GetSize(); } 27 28 template <typename T> 29 LIBSHIT_LUAGEN(template_params: %w(::Neptools::Item)) 30 T& Split(FilePosition pos, Libshit::NotNull<Libshit::RefCountedPtr<T>> nitem) 31 { 32 T& ret = *nitem; 33 Split2(pos, std::move(nitem)); 34 return ret; 35 } 36 37 template <typename T, typename... Args> 38 LIBSHIT_NOLUA T& SplitCreate(FilePosition pos, Args&&... args) 39 { 40 auto ctx = GetContext(); 41 return Split(pos, ctx->Create<T>(std::forward<Args>(args)...)); 42 } 43 44 RawItem& Split(FilePosition offset, FilePosition size); 45 46 template <typename T> 47 LIBSHIT_NOLUA static auto Get(ItemPointer ptr) 48 { 49 auto& ritem = ptr.AsChecked<RawItem>(); 50 LIBSHIT_ASSERT_MSG(ptr.offset <= ritem.GetSize(), "invalid offset"); 51 if (ptr.offset + sizeof(T) > ritem.GetSize()) 52 LIBSHIT_THROW(Libshit::DecodeError, "Premature end of data"); 53 54 struct Ret { RawItem& ritem; T t; }; 55 return Ret{ 56 std::ref(ritem), 57 ritem.src.PreadGen<T>(ptr.offset)}; 58 } 59 60 struct GetSourceRet { RawItem& ritem; Source src; }; 61 static GetSourceRet GetSource(ItemPointer ptr, FilePosition len) 62 { 63 auto& ritem = ptr.AsChecked<RawItem>(); 64 LIBSHIT_ASSERT_MSG(ptr.offset <= ritem.GetSize(), "invalid offset"); 65 if (len == FilePosition(-1)) len = ritem.GetSize() - ptr.offset; 66 67 if (ptr.offset + len > ritem.GetSize()) 68 LIBSHIT_THROW(Libshit::DecodeError, "Premature end of data"); 69 return {std::ref(ritem), {ritem.src, ptr.offset, len}}; 70 } 71 72 private: 73 Libshit::NotNull<Libshit::RefCountedPtr<RawItem>> InternalSlice( 74 FilePosition offset, FilePosition size); 75 void Split2( 76 FilePosition pos, Libshit::NotNull<Libshit::SmartPtr<Item>> nitem); 77 78 void Dump_(Sink& sink) const override; 79 void Inspect_(std::ostream& os, unsigned indent) const override; 80 81 Source src; 82 }; 83 84 template <typename T, typename... Args> 85 inline auto& MaybeCreate(ItemPointer ptr, Args&&... args) 86 { 87 auto item = ptr.Maybe<RawItem>(); 88 if (item) 89 return T::CreateAndInsert(ptr, std::forward<Args>(args)...); 90 else 91 return ptr.AsChecked0<T>(); // check it 92 } 93 94 template <typename T, typename... Args> 95 inline void MaybeCreateUnchecked(ItemPointer ptr, Args&&... args) 96 { 97 if (ptr.Maybe<RawItem>()) 98 T::CreateAndInsert(ptr, std::forward<Args>(args)...); 99 } 100 101 } 102 103 template<> struct Libshit::Lua::TupleLike<Neptools::RawItem::GetSourceRet> 104 { 105 template <size_t I> 106 static auto& Get(const Neptools::RawItem::GetSourceRet& ret) noexcept 107 { 108 if constexpr (I == 0) return ret.ritem; 109 else if constexpr (I == 1) return ret.src; 110 } 111 static constexpr size_t SIZE = 2; 112 }; 113 114 #endif