// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "PlainPropsTypes.h" #include "PlainPropsRead.h" #include "PlainPropsInternalFormat.h" #include namespace PlainProps { template TConstArrayView GrabInnerRangeTypes(TConstArrayView InnerRangeTypes, IndexType& InOutIdx) { const int32 StartIdx = InOutIdx; int32 Idx = StartIdx; while (InnerRangeTypes[Idx++].IsRange()); InOutIdx = static_cast(Idx); return MakeArrayView(&InnerRangeTypes[StartIdx], Idx - StartIdx); } inline uint64 GrabRangeNum(ERangeSizeType MaxSize, FByteReader& ByteIt, FBitCacheReader& BitIt) { switch(MaxSize) { case ERangeSizeType::Uni: return BitIt.GrabNext(/* in-out */ ByteIt) ? 1 : 0; case ERangeSizeType::S8: return IntCastChecked( ByteIt.Grab()); case ERangeSizeType::U8: return ByteIt.Grab(); case ERangeSizeType::S16: return IntCastChecked( ByteIt.Grab()); case ERangeSizeType::U16: return ByteIt.Grab(); case ERangeSizeType::S32: return IntCastChecked( ByteIt.Grab()); case ERangeSizeType::U32: return ByteIt.Grab(); case ERangeSizeType::S64: return IntCastChecked( ByteIt.Grab()); case ERangeSizeType::U64: return ByteIt.Grab(); } check(false); return 0; } inline FMemoryView GrabRangeValues(uint64 Num, FMemberType InnerType, /* in-out */ FByteReader& ByteIt) { if (Num == 0) { return FMemoryView(); } uint64 NumBytes = InnerType.IsLeaf() ? GetLeafRangeSize(Num, InnerType.AsLeaf()) : ByteIt.GrabVarIntU(); return ByteIt.GrabSlice(NumBytes); } inline FMemberType GetInnermostType(FRangeSchema Schema) { FMemberType Inner = Schema.ItemType; for (const FMemberType* It = Schema.NestedItemTypes; Inner.IsRange(); Inner = *It++) {} return Inner; } ////////////////////////////////////////////////////////////////////////// template struct TSchemaIterator { uintptr_t Base; const uint32* OffsetIt; void operator++() { ++OffsetIt; } bool operator!=(TSchemaIterator O) const { return OffsetIt != O.OffsetIt; } T& operator*() const { return *reinterpret_cast(Base + *OffsetIt); } }; template struct TSchemaRange { static constexpr bool bStructSchema = std::is_convertible_v; TSchemaRange(std::conditional_t, const FSchemaBatch&, FSchemaBatch&> Batch) : Base(reinterpret_cast(&Batch)) , Offsets(Batch.SchemaOffsets + (bStructSchema ? 0 : Batch.NumStructSchemas), bStructSchema ? Batch.NumStructSchemas : Batch.NumSchemas - Batch.NumStructSchemas) { static_assert(bStructSchema ^ std::is_convertible_v); } TSchemaIterator begin() const { return { Base, Offsets.begin() }; } TSchemaIterator end() const { return { Base, Offsets.end() }; } T& First() const { return *reinterpret_cast(Base + Offsets[0]); } T& Last() const { return *reinterpret_cast(Base + Offsets.Last()); } T& operator[](uint32 Idx) const { return *reinterpret_cast(Base + Offsets[Idx]); } uintptr_t Base; TConstArrayView Offsets; }; inline TSchemaRange GetEnumSchemas(FSchemaBatch& Batch) { return { Batch }; } inline TSchemaRange GetEnumSchemas(const FSchemaBatch& Batch) { return { Batch }; } inline TSchemaRange GetStructSchemas(FSchemaBatch& Batch) { return { Batch }; } inline TSchemaRange GetStructSchemas(const FSchemaBatch& Batch) { return { Batch }; } ////////////////////////////////////////////////////////////////////////// const FSchemaBatch& GetReadSchemas(FSchemaBatchId Batch); inline const FStructSchema& ResolveStructSchema(const FSchemaBatch& Batch, FSchemaId Id) { check(Id.Idx < Batch.NumSchemas); return *reinterpret_cast(reinterpret_cast(&Batch) + Batch.SchemaOffsets[Id.Idx]); } inline const FEnumSchema& ResolveEnumSchema(const FSchemaBatch& Batch, FSchemaId Id) { check(Id.Idx < Batch.NumSchemas); return *reinterpret_cast(reinterpret_cast(&Batch) + Batch.SchemaOffsets[Id.Idx]); } inline FNestedScope ResolveNestedScope(const FSchemaBatch& Batch, FNestedScopeId Id) { return Batch.GetNestedScopes()[Id.Idx]; } inline FParametricTypeView ResolveParametricType(const FSchemaBatch& Batch, FParametricTypeId Id) { FParametricType Type = Batch.GetParametricTypes()[Id.Idx]; return {Type.Name, IntCastChecked(Type.Parameters.NumParameters), Batch.GetFirstParameter() + Type.Parameters.Idx}; } ////////////////////////////////////////////////////////////////////////// inline FMemoryView GetSchemaData(const FSchemaBatch& Batch) { check(Batch.NumSchemas > 0); const uint8* BatchPtr = reinterpret_cast(&Batch); TConstArrayView Offsets(Batch.SchemaOffsets, Batch.NumSchemas); bool bHasEnums = Batch.NumSchemas > Batch.NumStructSchemas; uint32 LastSchemaSize = bHasEnums ? CalculateSize(GetEnumSchemas(Batch).Last()) : CalculateSize(GetStructSchemas(Batch).Last()); return FMemoryView(BatchPtr + Offsets[0], Offsets.Last() + LastSchemaSize - Offsets[0]); } } // namespace PlainProps