// Copyright Epic Games, Inc. All Rights Reserved. #include #include #include #include #include #include #include namespace zen { ////////////////////////////////////////////////////////////////////////// UniqueBuffer UniqueBuffer::Alloc(uint64_t Size) { void* Buffer = Memory::Alloc(Size, 16); if (!Buffer) { ThrowOutOfMemory(fmt::format("failed allocating {:#x} bytes aligned to {:#x}", Size, 16)); } IoBufferCore* Owner = new IoBufferCore(Buffer, Size); Owner->SetIsOwnedByThis(true); Owner->SetIsImmutable(false); return UniqueBuffer(Owner); } UniqueBuffer UniqueBuffer::MakeMutableView(void* DataPtr, uint64_t Size) { IoBufferCore* Owner = new IoBufferCore(DataPtr, Size); Owner->SetIsImmutable(false); return UniqueBuffer(Owner); } UniqueBuffer::UniqueBuffer(IoBufferCore* Owner) : m_Buffer(Owner) { } SharedBuffer UniqueBuffer::MoveToShared() { return SharedBuffer(std::move(m_Buffer)); } void UniqueBuffer::Reset() { m_Buffer = nullptr; } ////////////////////////////////////////////////////////////////////////// SharedBuffer::SharedBuffer(UniqueBuffer&& InBuffer) : m_Buffer(std::move(InBuffer.m_Buffer)) { } SharedBuffer SharedBuffer::MakeOwned() const& { if (IsOwned() || !m_Buffer) { return *this; } else { return Clone(GetView()); } } SharedBuffer SharedBuffer::MakeOwned() && { if (IsOwned()) { return std::move(*this); } else { return Clone(GetView()); } } SharedBuffer SharedBuffer::MakeView(MemoryView View, SharedBuffer OuterBuffer) { if (OuterBuffer) { ZEN_ASSERT(OuterBuffer.GetView().Contains(View)); } if (View == OuterBuffer.GetView()) { // Reference to the full buffer contents, so just return the "outer" return OuterBuffer; } IoBufferCore* NewCore = new IoBufferCore(OuterBuffer.m_Buffer, View.GetData(), View.GetSize()); NewCore->SetIsImmutable(true); return SharedBuffer(NewCore); } SharedBuffer SharedBuffer::MakeView(const void* Data, uint64_t Size) { return SharedBuffer(new IoBufferCore(const_cast(Data), Size)); } SharedBuffer SharedBuffer::Clone() { const uint64_t Size = GetSize(); void* Buffer = Memory::Alloc(Size, 16); if (!Buffer) { ThrowOutOfMemory(fmt::format("failed allocating {:#x} bytes aligned to {:#x}", Size, 16)); } auto NewOwner = new IoBufferCore(Buffer, Size); NewOwner->SetIsOwnedByThis(true); memcpy(Buffer, m_Buffer->DataPointer(), Size); return SharedBuffer(NewOwner); } SharedBuffer SharedBuffer::Clone(MemoryView View) { const uint64_t Size = View.GetSize(); void* Buffer = Memory::Alloc(Size, 16); if (!Buffer) { ThrowOutOfMemory(fmt::format("failed allocating {:#x} bytes aligned to {:#x}", Size, 16)); } auto NewOwner = new IoBufferCore(Buffer, Size); NewOwner->SetIsOwnedByThis(true); memcpy(Buffer, View.GetData(), Size); return SharedBuffer(NewOwner); } ////////////////////////////////////////////////////////////////////////// #if ZEN_WITH_TESTS void sharedbuffer_forcelink() { } TEST_CASE("SharedBuffer") { } #endif } // namespace zen