neptools

Modding tools to Neptunia games
git clone https://git.neptards.moe/neptards/neptools.git
Log | Files | Refs | Submodules | README | LICENSE

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