v / vlib / encoding / binary / big_endian.v
276 lines · 255 sloc · 7.78 KB · 3caa1b7297e2959633adb39f1422765aba8a4d50
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module binary
5
6// big_endian_u16 creates a u16 from the first two bytes in the array b in big endian order.
7@[direct_array_access; inline]
8pub fn big_endian_u16(b []u8) u16 {
9 _ = b[1] // bounds check
10 unsafe {
11 mut u := U16{}
12 $if big_endian {
13 u.b[0], u.b[1] = b[0], b[1]
14 } $else {
15 u.b[0], u.b[1] = b[1], b[0]
16 }
17 return u.u
18 }
19}
20
21// big_endian_u16_at creates a u16 from two bytes in the array b at the specified offset in big endian order.
22@[direct_array_access; inline]
23pub fn big_endian_u16_at(b []u8, o int) u16 {
24 _ = b[o] // bounds check
25 _ = b[o + 1] // bounds check
26 unsafe {
27 mut u := U16{}
28 $if big_endian {
29 u.b[0], u.b[1] = b[o], b[o + 1]
30 } $else {
31 u.b[0], u.b[1] = b[o + 1], b[o]
32 }
33 return u.u
34 }
35}
36
37// big_endian_u16_end creates a u16 from two bytes in the array b at the specified offset in big endian order.
38@[direct_array_access; inline]
39pub fn big_endian_u16_end(b []u8) u16 {
40 return big_endian_u16_at(b, b.len - 2)
41}
42
43// big_endian_put_u16 writes a u16 to the first two bytes in the array b in big endian order.
44@[direct_array_access; inline]
45pub fn big_endian_put_u16(mut b []u8, v u16) {
46 _ = b[1] // bounds check
47 unsafe {
48 mut u := U16{
49 u: v
50 }
51 $if big_endian {
52 b[0], b[1] = u.b[0], u.b[1]
53 } $else {
54 b[0], b[1] = u.b[1], u.b[0]
55 }
56 }
57}
58
59// big_endian_put_u16_at writes a u16 to the two bytes in the array b at the specified offset in big endian order.
60@[direct_array_access; inline]
61pub fn big_endian_put_u16_at(mut b []u8, v u16, o int) {
62 _ = b[o] // bounds check
63 _ = b[o + 1] // bounds check
64 unsafe {
65 mut u := U16{
66 u: v
67 }
68 $if big_endian {
69 b[o], b[o + 1] = u.b[0], u.b[1]
70 } $else {
71 b[o], b[o + 1] = u.b[1], u.b[0]
72 }
73 }
74}
75
76// big_endian_put_u16_end writes a u16 to the last two bytes in the array b in big endian order.
77@[direct_array_access; inline]
78pub fn big_endian_put_u16_end(mut b []u8, v u16) {
79 big_endian_put_u16_at(mut b, v, b.len - 2)
80}
81
82// big_endian_get_u16 creates u8 array from the unsigned 16-bit integer v in big endian order.
83@[direct_array_access; inline]
84pub fn big_endian_get_u16(v u16) []u8 {
85 unsafe {
86 mut u := U16{
87 u: v
88 }
89 $if little_endian {
90 u.b[0], u.b[1] = u.b[1], u.b[0]
91 }
92 return u.b[..]
93 }
94}
95
96// big_endian_u32 creates a u32 from four bytes in the array b in big endian order.
97@[direct_array_access; inline]
98pub fn big_endian_u32(b []u8) u32 {
99 _ = b[3] // bounds check
100 unsafe {
101 mut u := U32{}
102 $if big_endian {
103 u.b[0], u.b[1], u.b[2], u.b[3] = b[0], b[1], b[2], b[3]
104 } $else {
105 u.b[0], u.b[1], u.b[2], u.b[3] = b[3], b[2], b[1], b[0]
106 }
107 return u.u
108 }
109}
110
111// big_endian_u32_at creates a u32 from four bytes in the array b at the specified offset in big endian order.
112@[direct_array_access; inline]
113pub fn big_endian_u32_at(b []u8, o int) u32 {
114 _ = b[o] // bounds check
115 _ = b[o + 3] // bounds check
116 unsafe {
117 mut u := U32{}
118 $if big_endian {
119 u.b[0], u.b[1], u.b[2], u.b[3] = b[o], b[o + 1], b[o + 2], b[o + 3]
120 } $else {
121 u.b[0], u.b[1], u.b[2], u.b[3] = b[o + 3], b[o + 2], b[o + 1], b[o]
122 }
123 return u.u
124 }
125}
126
127// big_endian_u32_end creates a u32 from the last four bytes in the array b in big endian order.
128@[direct_array_access; inline]
129pub fn big_endian_u32_end(b []u8) u32 {
130 return big_endian_u32_at(b, b.len - 4)
131}
132
133// big_endian_put_u32 writes a u32 to the first four bytes in the array b in big endian order.
134@[direct_array_access; inline]
135pub fn big_endian_put_u32(mut b []u8, v u32) {
136 _ = b[3] // bounds check
137 unsafe {
138 mut u := U32{
139 u: v
140 }
141 $if big_endian {
142 b[0], b[1], b[2], b[3] = u.b[0], u.b[1], u.b[2], u.b[3]
143 } $else {
144 b[0], b[1], b[2], b[3] = u.b[3], u.b[2], u.b[1], u.b[0]
145 }
146 }
147}
148
149// big_endian_put_u32_at writes a u32 to four bytes in the array b at the specified offset in big endian order.
150@[direct_array_access; inline]
151pub fn big_endian_put_u32_at(mut b []u8, v u32, o int) {
152 _ = b[o] // bounds check
153 _ = b[o + 3] // bounds check
154 unsafe {
155 mut u := U32{
156 u: v
157 }
158 $if big_endian {
159 b[o], b[o + 1], b[o + 2], b[o + 3] = u.b[0], u.b[1], u.b[2], u.b[3]
160 } $else {
161 b[o], b[o + 1], b[o + 2], b[o + 3] = u.b[3], u.b[2], u.b[1], u.b[0]
162 }
163 }
164}
165
166// big_endian_put_u32_end writes a u32 to the last four bytes in the array b in big endian order.
167@[direct_array_access; inline]
168pub fn big_endian_put_u32_end(mut b []u8, v u32) {
169 big_endian_put_u32_at(mut b, v, b.len - 4)
170}
171
172// big_endian_get_u32 creates u8 array from the unsigned 32-bit integer v in big endian order.
173@[direct_array_access; inline]
174pub fn big_endian_get_u32(v u32) []u8 {
175 unsafe {
176 mut u := U32{
177 u: v
178 }
179 $if little_endian {
180 u.b[0], u.b[1], u.b[2], u.b[3] = u.b[3], u.b[2], u.b[1], u.b[0]
181 }
182 return u.b[..]
183 }
184}
185
186// big_endian_u64 creates a u64 from the first eight bytes in the array b in big endian order.
187@[direct_array_access; inline]
188pub fn big_endian_u64(b []u8) u64 {
189 _ = b[7] // bounds check
190 unsafe {
191 mut u := U64{}
192 $if big_endian {
193 u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7] = b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]
194 } $else {
195 u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7] = b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]
196 }
197 return u.u
198 }
199}
200
201// big_endian_u64_at creates a u64 from eight bytes in the array b at the specified offset in big endian order.
202@[direct_array_access; inline]
203pub fn big_endian_u64_at(b []u8, o int) u64 {
204 _ = b[o] // bounds check
205 _ = b[o + 7] // bounds check
206 unsafe {
207 mut u := U64{}
208 $if big_endian {
209 u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7] = b[o], b[o + 1], b[o + 2], b[
210 o + 3], b[o + 4], b[o + 5], b[o + 6], b[o + 7]
211 } $else {
212 u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7] = b[o + 7], b[o + 6], b[
213 o + 5], b[o + 4], b[o + 3], b[o + 2], b[o + 1], b[o]
214 }
215 return u.u
216 }
217}
218
219// big_endian_u64_end creates a u64 from the last eight bytes in the array b in big endian order.
220@[direct_array_access; inline]
221pub fn big_endian_u64_end(b []u8) u64 {
222 return big_endian_u64_at(b, b.len - 8)
223}
224
225// big_endian_put_u64 writes a u64 to the first eight bytes in the array b in big endian order.
226@[direct_array_access; inline]
227pub fn big_endian_put_u64(mut b []u8, v u64) {
228 _ = b[7] // bounds check
229 unsafe {
230 mut u := U64{
231 u: v
232 }
233 $if big_endian {
234 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7] = u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7]
235 } $else {
236 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7] = u.b[7], u.b[6], u.b[5], u.b[4], u.b[3], u.b[2], u.b[1], u.b[0]
237 }
238 }
239}
240
241// big_endian_put_u64_at writes a u64 to eight bytes in the array b at the specified offset in big endian order.
242@[direct_array_access; inline]
243pub fn big_endian_put_u64_at(mut b []u8, v u64, o int) {
244 _ = b[o] // bounds check
245 _ = b[o + 7] // bounds check
246 unsafe {
247 mut u := U64{
248 u: v
249 }
250 $if big_endian {
251 b[o], b[o + 1], b[o + 2], b[o + 3], b[o + 4], b[o + 5], b[o + 6], b[o + 7] = u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7]
252 } $else {
253 b[o], b[o + 1], b[o + 2], b[o + 3], b[o + 4], b[o + 5], b[o + 6], b[o + 7] = u.b[7], u.b[6], u.b[5], u.b[4], u.b[3], u.b[2], u.b[1], u.b[0]
254 }
255 }
256}
257
258// big_endian_put_u64_end writes a u64 to the last eight bytes in the array b at the specified offset in big endian order.
259@[direct_array_access; inline]
260pub fn big_endian_put_u64_end(mut b []u8, v u64) {
261 big_endian_put_u64_at(mut b, v, b.len - 8)
262}
263
264// big_endian_get_u64 creates u8 array from the unsigned 64-bit integer v in big endian order.
265@[direct_array_access; inline]
266pub fn big_endian_get_u64(v u64) []u8 {
267 unsafe {
268 mut u := U64{
269 u: v
270 }
271 $if little_endian {
272 u.b[0], u.b[1], u.b[2], u.b[3], u.b[4], u.b[5], u.b[6], u.b[7] = u.b[7], u.b[6], u.b[5], u.b[4], u.b[3], u.b[2], u.b[1], u.b[0]
273 }
274 return u.b[..]
275 }
276}
277