blob: 7e0ecd7f7eb470072b2feaf2446bebcf8c13a85a [file] [log] [blame]
Max53777012014-06-04 19:07:41 +02001/*
2 * bitXXgen.h
3 *
4 * Copyright (C) 2014 Max <max.suraev@fairwaves.co>
5 *
6 * All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#pragma once
24
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020025#include <osmocom/core/utils.h>
26
Neels Hofmeyr87e45502017-06-20 00:17:59 +020027/*! load unaligned n-byte integer (little-endian encoding) into uintXX_t
Max53777012014-06-04 19:07:41 +020028 * \param[in] p Buffer where integer is stored
29 * \param[in] n Number of bytes stored in p
30 * \returns XX bit unsigned integer
31 */
32static inline uintXX_t osmo_loadXXle_ext(const void *p, uint8_t n)
33{
34 uint8_t i;
35 uintXX_t r = 0;
36 const uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020037 OSMO_ASSERT(n <= sizeof(r));
Max53777012014-06-04 19:07:41 +020038 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (8 * i)), i++);
39 return r;
40}
41
Neels Hofmeyr87e45502017-06-20 00:17:59 +020042/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t
Max53777012014-06-04 19:07:41 +020043 * \param[in] p Buffer where integer is stored
44 * \param[in] n Number of bytes stored in p
45 * \returns XX bit unsigned integer
46 */
47static inline uintXX_t osmo_loadXXbe_ext(const void *p, uint8_t n)
48{
49 uint8_t i;
50 uintXX_t r = 0;
51 const uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020052 OSMO_ASSERT(n <= sizeof(r));
Max53777012014-06-04 19:07:41 +020053 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (XX - 8* (1 + i))), i++);
54 return r;
55}
56
57
Neels Hofmeyr87e45502017-06-20 00:17:59 +020058/*! store unaligned n-byte integer (little-endian encoding) from uintXX_t
Max53777012014-06-04 19:07:41 +020059 * \param[in] x unsigned XX bit integer
60 * \param[out] p Buffer to store integer
61 * \param[in] n Number of bytes to store
62 */
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020063static inline void osmo_storeXXle_ext(uintXX_t x, void *p, uint8_t n)
Max53777012014-06-04 19:07:41 +020064{
65 uint8_t i;
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020066 uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020067 OSMO_ASSERT(n <= sizeof(x));
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020068 for(i = 0; i < n; q[i] = (x >> i * 8) & 0xFF, i++);
Max53777012014-06-04 19:07:41 +020069}
70
Neels Hofmeyr87e45502017-06-20 00:17:59 +020071/*! store unaligned n-byte integer (big-endian encoding) from uintXX_t
Max53777012014-06-04 19:07:41 +020072 * \param[in] x unsigned XX bit integer
73 * \param[out] p Buffer to store integer
74 * \param[in] n Number of bytes to store
75 */
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020076static inline void osmo_storeXXbe_ext(uintXX_t x, void *p, uint8_t n)
Max53777012014-06-04 19:07:41 +020077{
78 uint8_t i;
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020079 uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020080 OSMO_ASSERT(n <= sizeof(x));
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020081 for(i = 0; i < n; q[i] = (x >> ((n - 1 - i) * 8)) & 0xFF, i++);
Max53777012014-06-04 19:07:41 +020082}
83
84
85/* Convenience function for most-used cases */
86
87
Neels Hofmeyr87e45502017-06-20 00:17:59 +020088/*! load unaligned XX-bit integer (little-endian encoding) */
Max53777012014-06-04 19:07:41 +020089static inline uintXX_t osmo_loadXXle(const void *p)
90{
91 return osmo_loadXXle_ext(p, XX / 8);
92}
93
Neels Hofmeyr87e45502017-06-20 00:17:59 +020094/*! load unaligned XX-bit integer (big-endian encoding) */
Max53777012014-06-04 19:07:41 +020095static inline uintXX_t osmo_loadXXbe(const void *p)
96{
97 return osmo_loadXXbe_ext(p, XX / 8);
98}
99
100
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200101/*! store unaligned XX-bit integer (little-endian encoding) */
Max53777012014-06-04 19:07:41 +0200102static inline void osmo_storeXXle(uintXX_t x, void *p)
103{
Sylvain Munaut5469ef82014-06-16 16:39:08 +0200104 osmo_storeXXle_ext(x, p, XX / 8);
Max53777012014-06-04 19:07:41 +0200105}
106
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200107/*! store unaligned XX-bit integer (big-endian encoding) */
Max53777012014-06-04 19:07:41 +0200108static inline void osmo_storeXXbe(uintXX_t x, void *p)
109{
Sylvain Munaut5469ef82014-06-16 16:39:08 +0200110 osmo_storeXXbe_ext(x, p, XX / 8);
Max53777012014-06-04 19:07:41 +0200111}