1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-09 12:42:11 +00:00
OpenMW/components/esm/esmcommon.hpp

157 lines
3.8 KiB
C++
Raw Normal View History

2012-09-23 18:11:08 +00:00
#ifndef OPENMW_ESM_COMMON_H
#define OPENMW_ESM_COMMON_H
2012-09-30 20:51:54 +00:00
#include <string>
2013-03-12 07:15:20 +00:00
#include <cstring>
2020-04-19 14:31:54 +00:00
#include <vector>
#include <string_view>
#include <cstdint>
namespace ESM
{
enum Version
{
VER_12 = 0x3f99999a,
VER_13 = 0x3fa66666
};
enum RecordFlag
{
FLAG_Persistent = 0x00000400,
FLAG_Blocked = 0x00002000
};
2016-05-07 17:32:51 +00:00
template <std::size_t capacity>
struct FixedString
{
static_assert(capacity > 0);
static constexpr std::size_t sCapacity = capacity;
char mData[capacity];
2016-05-07 17:32:51 +00:00
std::string_view toStringView() const noexcept
2016-05-07 17:32:51 +00:00
{
return std::string_view(mData, strnlen(mData, capacity));
2016-05-07 17:32:51 +00:00
}
std::string toString() const
2020-09-27 09:00:41 +00:00
{
return std::string(toStringView());
2020-09-27 09:00:41 +00:00
}
std::uint32_t toInt() const noexcept
2016-05-07 17:32:51 +00:00
{
static_assert(capacity == sizeof(std::uint32_t));
std::uint32_t value;
std::memcpy(&value, mData, capacity);
return value;
2016-05-07 17:32:51 +00:00
}
void clear() noexcept
2016-05-07 17:32:51 +00:00
{
std::memset(mData, 0, capacity);
2016-05-07 17:32:51 +00:00
}
void assign(std::string_view value) noexcept
{
if (value.empty())
{
clear();
return;
}
2016-05-07 17:32:51 +00:00
if (value.size() < capacity)
{
if constexpr (capacity == sizeof(std::uint32_t))
std::memset(mData, 0, capacity);
std::memcpy(mData, value.data(), value.size());
if constexpr (capacity != sizeof(std::uint32_t))
mData[value.size()] = '\0';
return;
}
std::memcpy(mData, value.data(), capacity);
if constexpr (capacity != sizeof(std::uint32_t))
mData[capacity - 1] = '\0';
}
FixedString& operator=(std::uint32_t value) noexcept
{
static_assert(capacity == sizeof(value));
std::memcpy(&mData, &value, capacity);
return *this;
}
};
2013-03-12 07:15:20 +00:00
template <std::size_t capacity, class T, typename = std::enable_if_t<std::is_same_v<T, char>>>
inline bool operator==(const FixedString<capacity>& lhs, const T* const& rhs) noexcept
{
for (std::size_t i = 0; i < capacity; ++i)
2020-09-27 09:00:41 +00:00
{
if (lhs.mData[i] != rhs[i])
return false;
if (lhs.mData[i] == '\0')
return true;
2020-09-27 09:00:41 +00:00
}
return rhs[capacity] == '\0';
}
2020-09-27 09:00:41 +00:00
template <std::size_t capacity>
inline bool operator==(const FixedString<capacity>& lhs, const std::string& rhs) noexcept
{
return lhs == rhs.c_str();
}
template <std::size_t capacity, std::size_t rhsSize>
inline bool operator==(const FixedString<capacity>& lhs, const char (&rhs)[rhsSize]) noexcept
{
return strnlen(rhs, rhsSize) == strnlen(lhs.mData, capacity)
&& std::strncmp(lhs.mData, rhs, capacity) == 0;
}
inline bool operator==(const FixedString<4>& lhs, std::uint32_t rhs) noexcept
{
return lhs.toInt() == rhs;
}
template <std::size_t capacity, class Rhs>
inline bool operator!=(const FixedString<capacity>& lhs, const Rhs& rhs) noexcept
{
return !(lhs == rhs);
}
using NAME = FixedString<4>;
using NAME32 = FixedString<32>;
using NAME64 = FixedString<64>;
2012-09-17 07:37:50 +00:00
/* This struct defines a file 'context' which can be saved and later
restored by an ESMReader instance. It will save the position within
a file, and when restored will let you read from that position as
if you never left it.
*/
struct ESM_Context
{
std::string filename;
uint32_t leftRec, leftSub;
size_t leftFile;
NAME recName, subName;
// When working with multiple esX files, we will generate lists of all files that
// actually contribute to a specific cell. Therefore, we need to store the index
// of the file belonging to this contest. See CellStore::(list/load)refs for details.
int index;
2020-04-19 14:31:54 +00:00
std::vector<int> parentFileIndices;
2012-09-17 07:37:50 +00:00
// True if subName has been read but not used.
bool subCached;
// File position. Only used for stored contexts, not regularly
// updated within the reader itself.
size_t filePos;
};
}
#endif