Skip to content

Commit b24059e

Browse files
committed
xrCore: thread safe crc32
Thanks to Im-Dex. From commit: Im-dex/xray-162@1f60c4d
1 parent 9e0ca32 commit b24059e

File tree

1 file changed

+38
-41
lines changed

1 file changed

+38
-41
lines changed

src/xrCore/crc32.cpp

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,56 @@
11
#include "stdafx.h"
22
#pragma hdrstop
33

4-
static BOOL crc32_ready = FALSE;
54
static u32 crc32_table[256]; // Lookup table array
65

7-
inline u32 Reflect(u32 ref, char ch) // Reflects CRC bits in the lookup table
6+
class Crc32Initializer final
87
{
9-
// Used only by Init_CRC32_Table().
8+
public:
9+
static void init() noexcept { static Crc32Initializer initializer; }
1010

11-
u32 value(0);
11+
private:
12+
Crc32Initializer() noexcept { crc32_init(); }
1213

13-
// Swap bit 0 for bit 7
14-
// bit 1 for bit 6, etc.
15-
for (int i = 1; i < (ch + 1); i++)
14+
static u32 reflect(u32 ref, char ch) noexcept // Reflects CRC bits in the lookup table
1615
{
17-
if (ref & 1)
18-
value |= 1 << (ch - i);
19-
ref >>= 1;
20-
}
21-
return value;
22-
}
16+
// Used only by Init_CRC32_Table().
2317

24-
void crc32_init()
25-
{
26-
// Call this function only once to initialize the CRC table.
18+
u32 value(0);
2719

28-
// This is the official polynomial used by CRC-32
29-
// in PKZip, WinZip and Ethernet.
30-
u32 ulPolynomial = 0x04c11db7;
20+
// Swap bit 0 for bit 7
21+
// bit 1 for bit 6, etc.
22+
for (int i = 1; i < (ch + 1); i++)
23+
{
24+
if (ref & 1)
25+
value |= 1 << (ch - i);
26+
ref >>= 1;
27+
}
28+
return value;
29+
}
3130

32-
// 256 values representing ASCII character codes.
33-
for (int i = 0; i <= 0xFF; i++)
31+
static void crc32_init() noexcept
3432
{
35-
crc32_table[i] = Reflect(i, 8) << 24;
36-
for (int j = 0; j < 8; j++)
37-
crc32_table[i] = (crc32_table[i] << 1) ^ (crc32_table[i] & (1 << 31) ? ulPolynomial : 0);
38-
crc32_table[i] = Reflect(crc32_table[i], 32);
33+
// Call this function only once to initialize the CRC table.
34+
35+
// This is the official polynomial used by CRC-32
36+
// in PKZip, WinZip and Ethernet.
37+
u32 ulPolynomial = 0x04c11db7;
38+
39+
// 256 values representing ASCII character codes.
40+
for (int i = 0; i <= 0xFF; i++)
41+
{
42+
crc32_table[i] = reflect(i, 8) << 24;
43+
for (int j = 0; j < 8; j++)
44+
crc32_table[i] =
45+
(crc32_table[i] << 1) ^ (crc32_table[i] & (1 << 31) ? ulPolynomial : 0);
46+
crc32_table[i] = reflect(crc32_table[i], 32);
47+
}
3948
}
40-
}
49+
};
4150

4251
u32 crc32(const void* P, u32 len)
4352
{
44-
if (!crc32_ready)
45-
{
46-
crc32_init();
47-
crc32_ready = TRUE;
48-
}
53+
Crc32Initializer::init();
4954

5055
// Pass a text string to this function and it will return the CRC.
5156

@@ -71,11 +76,7 @@ u32 crc32(const void* P, u32 len)
7176

7277
u32 crc32(const void* P, u32 len, u32 starting_crc)
7378
{
74-
if (!crc32_ready)
75-
{
76-
crc32_init();
77-
crc32_ready = TRUE;
78-
}
79+
Crc32Initializer::init();
7980

8081
u32 ulCRC = 0xffffffff ^ starting_crc;
8182
u8* buffer = (u8*)P;
@@ -88,11 +89,7 @@ u32 crc32(const void* P, u32 len, u32 starting_crc)
8889

8990
u32 path_crc32(const char* path, u32 len)
9091
{
91-
if (!crc32_ready)
92-
{
93-
crc32_init();
94-
crc32_ready = TRUE;
95-
}
92+
Crc32Initializer::init();
9693

9794
u32 ulCRC = 0xffffffff;
9895
u8* buffer = (u8*)path;

0 commit comments

Comments
 (0)