blob: ab54ba9cf4d99221b6e467d4a594ab12178340f7 [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.
Max53777012014-06-04 19:07:41 +020017 */
18
19#pragma once
20
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020021#include <osmocom/core/utils.h>
22
Neels Hofmeyrf6db7652020-09-14 00:39:37 +020023/*! load unaligned n-byte integer (little-endian encoding) into uintXX_t, into the least significant octets.
Max53777012014-06-04 19:07:41 +020024 * \param[in] p Buffer where integer is stored
25 * \param[in] n Number of bytes stored in p
26 * \returns XX bit unsigned integer
27 */
28static inline uintXX_t osmo_loadXXle_ext(const void *p, uint8_t n)
29{
30 uint8_t i;
31 uintXX_t r = 0;
32 const uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020033 OSMO_ASSERT(n <= sizeof(r));
Max53777012014-06-04 19:07:41 +020034 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (8 * i)), i++);
35 return r;
36}
37
Neels Hofmeyrf6db7652020-09-14 00:39:37 +020038/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t, into the MOST significant octets.
39 * WARNING: for n < sizeof(uintXX_t), the result is not returned in the least significant octets, as one might expect.
40 * To always return the same value as fed to osmo_storeXXbe_ext() before, use osmo_loadXXbe_ext_2().
Max53777012014-06-04 19:07:41 +020041 * \param[in] p Buffer where integer is stored
42 * \param[in] n Number of bytes stored in p
43 * \returns XX bit unsigned integer
44 */
45static inline uintXX_t osmo_loadXXbe_ext(const void *p, uint8_t n)
46{
47 uint8_t i;
48 uintXX_t r = 0;
49 const uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020050 OSMO_ASSERT(n <= sizeof(r));
Max53777012014-06-04 19:07:41 +020051 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (XX - 8* (1 + i))), i++);
52 return r;
53}
54
Neels Hofmeyrf6db7652020-09-14 00:39:37 +020055/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t, into the least significant octets.
56 * \param[in] p Buffer where integer is stored
57 * \param[in] n Number of bytes stored in p
58 * \returns XX bit unsigned integer
59 */
60static inline uintXX_t osmo_loadXXbe_ext_2(const void *p, uint8_t n)
61{
62 uint8_t i;
63 uintXX_t r = 0;
64 const uint8_t *q = (uint8_t *)p;
65 OSMO_ASSERT(n <= sizeof(r));
66 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (XX - 8* (1 + i + (sizeof(r) - n)))), i++);
67 return r;
68}
69
Max53777012014-06-04 19:07:41 +020070
Neels Hofmeyr87e45502017-06-20 00:17:59 +020071/*! store unaligned n-byte integer (little-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_storeXXle_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 >> i * 8) & 0xFF, i++);
Max53777012014-06-04 19:07:41 +020082}
83
Neels Hofmeyr87e45502017-06-20 00:17:59 +020084/*! store unaligned n-byte integer (big-endian encoding) from uintXX_t
Max53777012014-06-04 19:07:41 +020085 * \param[in] x unsigned XX bit integer
86 * \param[out] p Buffer to store integer
87 * \param[in] n Number of bytes to store
88 */
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020089static inline void osmo_storeXXbe_ext(uintXX_t x, void *p, uint8_t n)
Max53777012014-06-04 19:07:41 +020090{
91 uint8_t i;
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020092 uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020093 OSMO_ASSERT(n <= sizeof(x));
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020094 for(i = 0; i < n; q[i] = (x >> ((n - 1 - i) * 8)) & 0xFF, i++);
Max53777012014-06-04 19:07:41 +020095}
96
97
98/* Convenience function for most-used cases */
99
100
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200101/*! load unaligned XX-bit integer (little-endian encoding) */
Max53777012014-06-04 19:07:41 +0200102static inline uintXX_t osmo_loadXXle(const void *p)
103{
104 return osmo_loadXXle_ext(p, XX / 8);
105}
106
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200107/*! load unaligned XX-bit integer (big-endian encoding) */
Max53777012014-06-04 19:07:41 +0200108static inline uintXX_t osmo_loadXXbe(const void *p)
109{
110 return osmo_loadXXbe_ext(p, XX / 8);
111}
112
113
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200114/*! store unaligned XX-bit integer (little-endian encoding) */
Max53777012014-06-04 19:07:41 +0200115static inline void osmo_storeXXle(uintXX_t x, void *p)
116{
Sylvain Munaut5469ef82014-06-16 16:39:08 +0200117 osmo_storeXXle_ext(x, p, XX / 8);
Max53777012014-06-04 19:07:41 +0200118}
119
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200120/*! store unaligned XX-bit integer (big-endian encoding) */
Max53777012014-06-04 19:07:41 +0200121static inline void osmo_storeXXbe(uintXX_t x, void *p)
122{
Sylvain Munaut5469ef82014-06-16 16:39:08 +0200123 osmo_storeXXbe_ext(x, p, XX / 8);
Max53777012014-06-04 19:07:41 +0200124}