VideoCommon: Use GetSpanForAddress safely in texture decoding

Now only VertexLoader remains... But that one might be tricky.
This commit is contained in:
JosJuice
2024-04-13 18:29:52 +02:00
parent 5c9bb80638
commit 3cfa233b63
14 changed files with 220 additions and 101 deletions

View File

@ -126,6 +126,7 @@ add_library(common
SmallVector.h
SocketContext.cpp
SocketContext.h
SpanUtils.h
SPSCQueue.h
StringLiteral.h
StringUtil.cpp

View File

@ -0,0 +1,41 @@
// Copyright 2024 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <algorithm>
#include <cstddef>
#include <span>
#include <utility>
#include "Common/CommonTypes.h"
namespace Common
{
// Like std::span::subspan, except undefined behavior is replaced with returning a 0-length span.
template <class T>
[[nodiscard]] constexpr std::span<T> SafeSubspan(std::span<T> span, size_t offset,
size_t count = std::dynamic_extent)
{
if (count == std::dynamic_extent || offset > span.size())
return span.subspan(std::min(offset, span.size()));
else
return span.subspan(offset, std::min(count, span.size() - offset));
}
// Default-constructs an object of type T, then copies data into it from the specified offset in
// the specified span. Out-of-bounds reads will be skipped, meaning that specifying a too large
// offset results in the object partially or entirely remaining default constructed.
template <class T>
[[nodiscard]] T SafeSpanRead(std::span<const u8> span, size_t offset)
{
static_assert(std::is_trivially_copyable<T>());
const std::span<const u8> subspan = SafeSubspan(span, offset);
T result{};
std::memcpy(&result, subspan.data(), std::min(subspan.size(), sizeof(result)));
return result;
}
} // namespace Common