-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBitConverter.cpp
More file actions
148 lines (120 loc) · 4.6 KB
/
BitConverter.cpp
File metadata and controls
148 lines (120 loc) · 4.6 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#ifndef __BITCONVERTER_INCLUDED__
#define __BITCONVERTER_INCLUDED__
#include <cstdint>
#ifdef BITCONVERTER_VECTOR_CONVS
#include <vector>
#endif
#ifdef BITCONVERTER_ARRAY_CONVS
#include <array>
#endif
namespace BitConverter {
#if !defined(__BIG_ENDIAN_OVERRIDE) && ( \
defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN || \
defined(__LITTLE_ENDIAN__) || \
defined(__ARMEL__) || \
defined(__THUMBEL__) || \
defined(__AARCH64EL__) || \
defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) )
// system is natively little-endian, no conversion needed
// Write a uint64_t to ptr, exists for portability with big-endian systems
inline void writeBytes (void * ptr, uint64_t input) { *(uint64_t *)ptr = input; }
// Write a uint32_t to ptr, exists for portability with big-endian systems
inline void writeBytes (void * ptr, uint32_t input) { *(uint32_t *)ptr = input; }
// Write a uint16_t to ptr, exists for portability with big-endian systems
inline void writeBytes (void * ptr, uint16_t input) { *(uint16_t *)ptr = input; }
// Read a uint64_t from ptr, exists for portability with big-endian systems
inline uint64_t readUint64 (const void * ptr) {return *(uint64_t *) ptr;}
// Read a uint32_t from ptr, exists for portability with big-endian systems
inline uint32_t readUint32 (const void * ptr) {return *(uint32_t *) ptr;}
// Read a uint16_t from ptr, exists for portability with big-endian systems
inline uint16_t readUint16 (const void * ptr) {return *(uint16_t *) ptr;}
#elif defined(__BIG_ENDIAN_OVERRIDE) || \
defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || \
defined(__BIG_ENDIAN__) || \
defined(__ARMEB__) || \
defined(__THUMBEB__) || \
defined(__AARCH64EB__) || \
defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) || \
defined(_MSC_VER) // MSVC YOU FUCKING SON OF A BITCH
// system is natively big-endian (or undetermined in case of MSVC), conversion required
// Write a uint64_t to ptr, while converting it to little-endian
inline void writeBytes (void * ptr, uint64_t input) {
uint8_t * tmp = (uint8_t*) ptr;
*(tmp )= (input )&0xFF;
*(tmp+1)= (input>> 8)&0xFF;
*(tmp+2)= (input>>16)&0xFF;
*(tmp+3)= (input>>24)&0xFF;
*(tmp+4)= (input>>32)&0xFF;
*(tmp+5)= (input>>40)&0xFF;
*(tmp+6)= (input>>48)&0xFF;
*(tmp+7)= (input>>56)&0xFF;
}
// Write a uint32_t to ptr, while converting it to little-endian
inline void writeBytes (void * ptr, uint32_t input) {
uint8_t * tmp = (uint8_t*) ptr;
*(tmp )= (input )&0xFF;
*(tmp+1)= (input>> 8)&0xFF;
*(tmp+2)= (input>>16)&0xFF;
*(tmp+3)= (input>>24)&0xFF;
}
// Write a uint16_t to ptr, while converting it to little-endian
inline void writeBytes (void * ptr, uint16_t input) {
uint8_t * tmp = (uint8_t*) ptr;
*(tmp )= (input )&0xFF;
*(tmp+1)= (input>> 8)&0xFF;
}
// Read a uint64_t from ptr in little-endian
inline uint64_t readUint64 (const void * ptr) {
uint8_t * tmp = (uint8_t*) ptr;
return \
(uint64_t)*(tmp ) |
(uint64_t)*(tmp+1)<< 8|
(uint64_t)*(tmp+2)<<16|
(uint64_t)*(tmp+3)<<24|
(uint64_t)*(tmp+4)<<32|
(uint64_t)*(tmp+5)<<40|
(uint64_t)*(tmp+6)<<48|
(uint64_t)*(tmp+7)<<56;
}
// Read a uint32_t from ptr in little-endian
inline uint32_t readUint32 (const void * ptr) {
uint8_t * tmp = (uint8_t*) ptr;
return \
(uint32_t)*(tmp ) |
(uint32_t)*(tmp+1)<< 8|
(uint32_t)*(tmp+2)<<16|
(uint32_t)*(tmp+3)<<24;
}
// Read a uint16_t from ptr in little-endian
inline uint16_t readUint16 (const void * ptr) {
uint8_t * tmp = (uint8_t*) ptr;
return *(tmp) | *(tmp+1)<<8;
}
#else
#error "Unsupported architecture. Please contact the lead dev and report what architecture you're compiling on"
#endif
// Architecture independent funcs
#ifdef BITCONVERTER_ARRAY_CONVS
std::array<uint8_t, 2> toByteArray(uint16_t data) {
std::array<uint8_t, 2> output; writeBytes(output.data(), data); return output;
}
std::array<uint8_t, 4> toByteArray(uint32_t data) {
std::array<uint8_t, 4> output; writeBytes(output.data(), data); return output;
}
std::array<uint8_t, 8> toByteArray(uint64_t data) {
std::array<uint8_t, 8> output; writeBytes(output.data(), data); return output;
}
#endif // BITCONVERTER_ARRAY_CONVS
#ifdef BITCONVERTER_VECTOR_CONVS
std::vector<uint8_t> toVector(uint16_t data) {
std::vector<uint8_t> output(2); writeBytes(output.data(), data); return output;
}
std::vector<uint8_t> toVector(uint32_t data) {
std::vector<uint8_t> output(4); writeBytes(output.data(), data); return output;
}
std::vector<uint8_t> toVector(uint64_t data) {
std::vector<uint8_t> output(8); writeBytes(output.data(), data); return output;
}
#endif // BITCONVERTER_VECTOR_CONVS
} // namespace BitConverter
#endif // __BITCONVERTER_INCLUDED__