blob: 258fccb62a871be3353bf4037fbc672dcdccbc86 [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 Hofmeyrf6db7652020-09-14 00:39:37 +020027/*! load unaligned n-byte integer (little-endian encoding) into uintXX_t, into the least significant octets.
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 Hofmeyrf6db7652020-09-14 00:39:37 +020042/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t, into the MOST significant octets.
43 * WARNING: for n < sizeof(uintXX_t), the result is not returned in the least significant octets, as one might expect.
44 * To always return the same value as fed to osmo_storeXXbe_ext() before, use osmo_loadXXbe_ext_2().
Max53777012014-06-04 19:07:41 +020045 * \param[in] p Buffer where integer is stored
46 * \param[in] n Number of bytes stored in p
47 * \returns XX bit unsigned integer
48 */
49static inline uintXX_t osmo_loadXXbe_ext(const void *p, uint8_t n)
50{
51 uint8_t i;
52 uintXX_t r = 0;
53 const uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020054 OSMO_ASSERT(n <= sizeof(r));
Max53777012014-06-04 19:07:41 +020055 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (XX - 8* (1 + i))), i++);
56 return r;
57}
58
Neels Hofmeyrf6db7652020-09-14 00:39:37 +020059/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t, into the least significant octets.
60 * \param[in] p Buffer where integer is stored
61 * \param[in] n Number of bytes stored in p
62 * \returns XX bit unsigned integer
63 */
64static inline uintXX_t osmo_loadXXbe_ext_2(const void *p, uint8_t n)
65{
66 uint8_t i;
67 uintXX_t r = 0;
68 const uint8_t *q = (uint8_t *)p;
69 OSMO_ASSERT(n <= sizeof(r));
70 for(i = 0; i < n; r |= ((uintXX_t)q[i] << (XX - 8* (1 + i + (sizeof(r) - n)))), i++);
71 return r;
72}
73
Max53777012014-06-04 19:07:41 +020074
Neels Hofmeyr87e45502017-06-20 00:17:59 +020075/*! store unaligned n-byte integer (little-endian encoding) from uintXX_t
Max53777012014-06-04 19:07:41 +020076 * \param[in] x unsigned XX bit integer
77 * \param[out] p Buffer to store integer
78 * \param[in] n Number of bytes to store
79 */
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020080static inline void osmo_storeXXle_ext(uintXX_t x, void *p, uint8_t n)
Max53777012014-06-04 19:07:41 +020081{
82 uint8_t i;
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020083 uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020084 OSMO_ASSERT(n <= sizeof(x));
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020085 for(i = 0; i < n; q[i] = (x >> i * 8) & 0xFF, i++);
Max53777012014-06-04 19:07:41 +020086}
87
Neels Hofmeyr87e45502017-06-20 00:17:59 +020088/*! store unaligned n-byte integer (big-endian encoding) from uintXX_t
Max53777012014-06-04 19:07:41 +020089 * \param[in] x unsigned XX bit integer
90 * \param[out] p Buffer to store integer
91 * \param[in] n Number of bytes to store
92 */
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020093static inline void osmo_storeXXbe_ext(uintXX_t x, void *p, uint8_t n)
Max53777012014-06-04 19:07:41 +020094{
95 uint8_t i;
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020096 uint8_t *q = (uint8_t *)p;
Neels Hofmeyrc0ac4e32020-09-14 00:20:24 +020097 OSMO_ASSERT(n <= sizeof(x));
Sylvain Munaut3baa0d62014-06-16 16:38:31 +020098 for(i = 0; i < n; q[i] = (x >> ((n - 1 - i) * 8)) & 0xFF, i++);
Max53777012014-06-04 19:07:41 +020099}
100
101
102/* Convenience function for most-used cases */
103
104
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200105/*! load unaligned XX-bit integer (little-endian encoding) */
Max53777012014-06-04 19:07:41 +0200106static inline uintXX_t osmo_loadXXle(const void *p)
107{
108 return osmo_loadXXle_ext(p, XX / 8);
109}
110
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200111/*! load unaligned XX-bit integer (big-endian encoding) */
Max53777012014-06-04 19:07:41 +0200112static inline uintXX_t osmo_loadXXbe(const void *p)
113{
114 return osmo_loadXXbe_ext(p, XX / 8);
115}
116
117
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200118/*! store unaligned XX-bit integer (little-endian encoding) */
Max53777012014-06-04 19:07:41 +0200119static inline void osmo_storeXXle(uintXX_t x, void *p)
120{
Sylvain Munaut5469ef82014-06-16 16:39:08 +0200121 osmo_storeXXle_ext(x, p, XX / 8);
Max53777012014-06-04 19:07:41 +0200122}
123
Neels Hofmeyr87e45502017-06-20 00:17:59 +0200124/*! store unaligned XX-bit integer (big-endian encoding) */
Max53777012014-06-04 19:07:41 +0200125static inline void osmo_storeXXbe(uintXX_t x, void *p)
126{
Sylvain Munaut5469ef82014-06-16 16:39:08 +0200127 osmo_storeXXbe_ext(x, p, XX / 8);
Max53777012014-06-04 19:07:41 +0200128}