CommonLibVR
BSStringPool.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/B/BSAtomic.h"
4 
5 namespace RE
6 {
7  using GlobalStringHandle = char*;
8  using GlobalStringHandleW = wchar_t*;
9 
10  struct BSStringPool
11  {
12  public:
13  class Entry
14  {
15  public:
16  enum
17  {
18  kWide = 1 << 15,
19  kRefCountMask = 0x7FFF,
20  kLengthMask = 0xFFFFFF
21  };
22 
23  static inline void release(const char*& a_entry) { release8(a_entry); }
24  static inline void release(const wchar_t*& a_entry) { release16(a_entry); }
25 
26  static inline void release8(const char*& a_entry)
27  {
28  using func_t = decltype(&Entry::release8);
29  static REL::Relocation<func_t> func{ RELOCATION_ID(67847, 69192) };
30  func(a_entry);
31  }
32 
33  static inline void release16(const wchar_t*& a_entry)
34  {
35  using func_t = decltype(&Entry::release16);
36  static REL::Relocation<func_t> func{ RELOCATION_ID(67848, 69193) };
37  func(a_entry);
38  }
39 
40  inline void acquire()
41  {
42  stl::atomic_ref flags{ _flags };
43  std::uint16_t expected{ 0 };
44  do {
45  expected = flags;
46  if ((expected & kRefCountMask) >= kRefCountMask) {
47  break;
48  }
49  } while (!flags.compare_exchange_weak(expected, static_cast<std::uint16_t>(expected + 1)));
50  }
51 
52  [[nodiscard]] constexpr std::uint16_t crc() const noexcept { return _crc; }
53 
54  template <class T>
55  [[nodiscard]] const T* data() const noexcept;
56 
57  template <>
58  [[nodiscard]] inline const char* data<char>() const noexcept
59  {
60  return u8();
61  }
62 
63  template <>
64  [[nodiscard]] inline const wchar_t* data<wchar_t>() const noexcept
65  {
66  return u16();
67  }
68 
69  [[nodiscard]] constexpr std::uint32_t length() const noexcept { return _length & kLengthMask; }
70  [[nodiscard]] constexpr std::uint32_t size() const noexcept { return length(); }
71 
72  [[nodiscard]] inline const char* u8() const noexcept
73  {
74  assert(!wide());
75  return reinterpret_cast<const char*>(this + 1);
76  }
77 
78  [[nodiscard]] inline const wchar_t* u16() const noexcept
79  {
80  assert(wide());
81  return reinterpret_cast<const wchar_t*>(this + 1);
82  }
83 
84  [[nodiscard]] constexpr bool wide() const noexcept { return static_cast<bool>(_flags & kWide); }
85 
86  // members
87  Entry* _left; // 00
88  std::uint16_t _flags; // 08
89  volatile std::uint16_t _crc; // 08
90  union
91  {
92  std::uint32_t _length;
94  }; // 10
95  };
96  static_assert(sizeof(Entry) == 0x18);
97  };
98  static_assert(std::is_empty_v<BSStringPool>);
99 
100  struct BucketTable
101  {
102  enum HashMask
103  {
104  kEntryIndexMask = 0xFFFF,
105  kLockIndexMask = 0x7F
106  };
107 
109 
110  // members
111  BSStringPool::Entry* buckets[0x10000]; // 00000 - index using hash & kEntryIndexMask
112  mutable BSSpinLock locks[0x10000 / 0x800]; // 80000 - index using hash & kLockIndexMask
113  bool initialized; // 80100
114  };
115  static_assert(sizeof(BucketTable) == 0x80108);
116 }
#define RELOCATION_ID(SE, AE)
Definition: PCH.h:702
Definition: Relocation.h:210
Definition: BSAtomic.h:92
Definition: BSStringPool.h:14
constexpr bool wide() const noexcept
Definition: BSStringPool.h:84
constexpr std::uint32_t length() const noexcept
Definition: BSStringPool.h:69
const wchar_t * u16() const noexcept
Definition: BSStringPool.h:78
std::uint32_t _length
Definition: BSStringPool.h:92
static void release16(const wchar_t *&a_entry)
Definition: BSStringPool.h:33
Entry * _left
Definition: BSStringPool.h:87
constexpr std::uint16_t crc() const noexcept
Definition: BSStringPool.h:52
static void release(const char *&a_entry)
Definition: BSStringPool.h:23
const T * data() const noexcept
constexpr std::uint32_t size() const noexcept
Definition: BSStringPool.h:70
volatile std::uint16_t _crc
Definition: BSStringPool.h:89
static void release(const wchar_t *&a_entry)
Definition: BSStringPool.h:24
Entry * _right
Definition: BSStringPool.h:93
std::uint16_t _flags
Definition: BSStringPool.h:88
static void release8(const char *&a_entry)
Definition: BSStringPool.h:26
const char * u8() const noexcept
Definition: BSStringPool.h:72
void acquire()
Definition: BSStringPool.h:40
@ kRefCountMask
Definition: BSStringPool.h:19
@ kLengthMask
Definition: BSStringPool.h:20
@ kWide
Definition: BSStringPool.h:18
Definition: PCH.h:437
Definition: AbsorbEffect.h:6
char * GlobalStringHandle
Definition: BSStringPool.h:7
wchar_t * GlobalStringHandleW
Definition: BSStringPool.h:8
Definition: BSStringPool.h:11
Definition: BSStringPool.h:101
HashMask
Definition: BSStringPool.h:103
@ kEntryIndexMask
Definition: BSStringPool.h:104
@ kLockIndexMask
Definition: BSStringPool.h:105
static BucketTable * GetSingleton()
bool initialized
Definition: BSStringPool.h:113
BSStringPool::Entry * buckets[0x10000]
Definition: BSStringPool.h:111
BSSpinLock locks[0x10000/0x800]
Definition: BSStringPool.h:112