forked from pmachapman/unrar
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rawint.hpp
122 lines (102 loc) · 2.57 KB
/
rawint.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef _RAR_RAWINT_
#define _RAR_RAWINT_
#define rotls(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n))))
#define rotrs(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n))))
#define rotl32(x,n) rotls(x,n,32)
#define rotr32(x,n) rotrs(x,n,32)
inline uint RawGet2(const void *Data)
{
byte *D=(byte *)Data;
return D[0]+(D[1]<<8);
}
inline uint32 RawGet4(const void *Data)
{
#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
byte *D=(byte *)Data;
return D[0]+(D[1]<<8)+(D[2]<<16)+(D[3]<<24);
#else
return *(uint32 *)Data;
#endif
}
inline uint64 RawGet8(const void *Data)
{
#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
byte *D=(byte *)Data;
return INT32TO64(RawGet4(D+4),RawGet4(D));
#else
return *(uint64 *)Data;
#endif
}
inline void RawPut2(uint Field,void *Data)
{
byte *D=(byte *)Data;
D[0]=(byte)(Field);
D[1]=(byte)(Field>>8);
}
inline void RawPut4(uint32 Field,void *Data)
{
#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
byte *D=(byte *)Data;
D[0]=(byte)(Field);
D[1]=(byte)(Field>>8);
D[2]=(byte)(Field>>16);
D[3]=(byte)(Field>>24);
#else
*(uint32 *)Data=Field;
#endif
}
inline void RawPut8(uint64 Field,void *Data)
{
#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED)
byte *D=(byte *)Data;
D[0]=(byte)(Field);
D[1]=(byte)(Field>>8);
D[2]=(byte)(Field>>16);
D[3]=(byte)(Field>>24);
D[4]=(byte)(Field>>32);
D[5]=(byte)(Field>>40);
D[6]=(byte)(Field>>48);
D[7]=(byte)(Field>>56);
#else
*(uint64 *)Data=Field;
#endif
}
#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
#define USE_MEM_BYTESWAP
#endif
// Load 4 big endian bytes from memory and return uint32.
inline uint32 RawGetBE4(const byte *m)
{
#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
return _byteswap_ulong(*(uint32 *)m);
#elif defined(USE_MEM_BYTESWAP) && (defined(__clang__) || defined(__GNUC__))
return __builtin_bswap32(*(uint32 *)m);
#else
return uint32(m[0]<<24) | uint32(m[1]<<16) | uint32(m[2]<<8) | m[3];
#endif
}
// Save integer to memory as big endian.
inline void RawPutBE4(uint32 i,byte *mem)
{
#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
*(uint32*)mem = _byteswap_ulong(i);
#elif defined(USE_MEM_BYTESWAP) && (defined(__clang__) || defined(__GNUC__))
*(uint32*)mem = __builtin_bswap32(i);
#else
mem[0]=byte(i>>24);
mem[1]=byte(i>>16);
mem[2]=byte(i>>8);
mem[3]=byte(i);
#endif
}
inline uint32 ByteSwap32(uint32 i)
{
#ifdef _MSC_VER
return _byteswap_ulong(i);
#elif defined(__clang__) || defined(__GNUC__)
return __builtin_bswap32(i);
#else
return (rotl32(i,24)&0xFF00FF00)|(rotl32(i,8)&0x00FF00FF);
#endif
}
#endif