1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-16 15:29:55 +00:00

Check FormIdRefId value in constructor

This commit is contained in:
elsid 2023-04-20 02:12:56 +02:00
parent 4738f0ff4d
commit c97df7d770
No known key found for this signature in database
GPG key ID: 4DE04C198CBA7625
4 changed files with 22 additions and 9 deletions

View file

@ -177,6 +177,11 @@ namespace ESM
EXPECT_FALSE(formIdRefId < stringView); EXPECT_FALSE(formIdRefId < stringView);
} }
TEST(ESMRefIdTest, formIdRefIdIndexShouldHaveOnly24SignificantBits)
{
EXPECT_THROW(FormIdRefId(FormId{ .mIndex = 1 << 25, .mContentFile = 0 }), std::invalid_argument);
}
TEST(ESMRefIdTest, canBeUsedAsMapKeyWithLookupByStringView) TEST(ESMRefIdTest, canBeUsedAsMapKeyWithLookupByStringView)
{ {
const std::map<RefId, int, std::less<>> map({ { RefId::stringRefId("a"), 42 } }); const std::map<RefId, int, std::less<>> map({ { RefId::stringRefId("a"), 42 } });

View file

@ -1,18 +1,24 @@
#include "formidrefid.hpp" #include "formidrefid.hpp"
#include <cassert>
#include <ostream> #include <ostream>
#include "serializerefid.hpp" #include "serializerefid.hpp"
namespace ESM namespace ESM
{ {
namespace
{
std::uint64_t truncate(FormId value)
{
return (static_cast<std::uint64_t>(value.mContentFile) << 24) | value.mIndex;
}
}
std::string FormIdRefId::toString() const std::string FormIdRefId::toString() const
{ {
std::string result; std::string result;
assert((mValue.mIndex & 0xff000000) == 0); const std::uint64_t v = truncate(mValue);
size_t v = (static_cast<size_t>(mValue.mContentFile) << 24) | mValue.mIndex; result.resize(getHexIntegralSizeWith0x(v), '\0');
result.resize(getHexIntegralSize(v) + 2, '\0');
serializeHexIntegral(v, 0, result); serializeHexIntegral(v, 0, result);
return result; return result;
} }
@ -20,8 +26,7 @@ namespace ESM
std::string FormIdRefId::toDebugString() const std::string FormIdRefId::toDebugString() const
{ {
std::string result; std::string result;
assert((mValue.mIndex & 0xff000000) == 0); const std::uint64_t v = truncate(mValue);
size_t v = (static_cast<size_t>(mValue.mContentFile) << 24) | mValue.mIndex;
serializeRefIdValue(v, formIdRefIdPrefix, result); serializeRefIdValue(v, formIdRefIdPrefix, result);
return result; return result;
} }

View file

@ -3,6 +3,7 @@
#include <functional> #include <functional>
#include <iosfwd> #include <iosfwd>
#include <stdexcept>
#include <components/esm/formid.hpp> #include <components/esm/formid.hpp>
@ -13,9 +14,11 @@ namespace ESM
public: public:
constexpr FormIdRefId() = default; constexpr FormIdRefId() = default;
constexpr explicit FormIdRefId(ESM::FormId value) noexcept constexpr explicit FormIdRefId(ESM::FormId value)
: mValue(value) : mValue(value)
{ {
if ((mValue.mIndex & 0xff000000) != 0)
throw std::invalid_argument("Invalid FormIdRefId index value: " + std::to_string(mValue.mIndex));
} }
ESM::FormId getValue() const { return mValue; } ESM::FormId getValue() const { return mValue; }

View file

@ -63,7 +63,7 @@ namespace ESM
static RefId stringRefId(std::string_view value); static RefId stringRefId(std::string_view value);
// Constructs RefId from FormId storing the value in-place. // Constructs RefId from FormId storing the value in-place.
static RefId formIdRefId(FormId value) noexcept { return RefId(FormIdRefId(value)); } static RefId formIdRefId(FormId value) { return RefId(FormIdRefId(value)); }
// Constructs RefId from uint64 storing the value in-place. Should be used for generated records where id is a // Constructs RefId from uint64 storing the value in-place. Should be used for generated records where id is a
// global counter. // global counter.
@ -87,7 +87,7 @@ namespace ESM
{ {
} }
constexpr RefId(FormIdRefId value) noexcept constexpr RefId(FormIdRefId value)
: mValue(value) : mValue(value)
{ {
} }