aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2020-09-14 00:39:37 +0200
committerlaforge <laforge@osmocom.org>2020-09-14 11:53:46 +0000
commitf6db7653270f4c926cd64f2597f19fd657520ae8 (patch)
tree5bf1357d008f30a7b1e1e6520ea31a0fed179894
parent6862cd38a59685d15f9940fcf3882607081e3261 (diff)
bitXXgen: add osmo_loadXXbe_ext_2() to get right-adjusted values
As shown in the recently added bitgen_test.c, using osmo_loadXXbe_ext() with a smaller n produces results aligned on the most significant bytes, which is cumbersome, since it does not return a previously stored value. This problem exists only for the big-endian functions, the little-endian osmo_loadXXle_ext() properly return values adjusted on the least significant octets. Add osmo_loadXXbe_ext_2() variants that properly right-adjust the returned value. Prominently highlight this behavior in API doc. Test the new functions in bitgen_test.c. For example, this eases handling of 24bit integers (e.g. loaded from buffer to uint32_t, and stored into buffer from uint32_t). Also explicitly show this 24 bit case in bitgen_test.c Change-Id: I2806df6f0f7bf1ad705d52fa386d4525b892b928
-rw-r--r--include/osmocom/core/bitXXgen.h.tpl21
-rw-r--r--tests/bitgen/bitgen_test.c27
-rw-r--r--tests/bitgen/bitgen_test.ok54
3 files changed, 98 insertions, 4 deletions
diff --git a/include/osmocom/core/bitXXgen.h.tpl b/include/osmocom/core/bitXXgen.h.tpl
index 7e0ecd7f..258fccb6 100644
--- a/include/osmocom/core/bitXXgen.h.tpl
+++ b/include/osmocom/core/bitXXgen.h.tpl
@@ -24,7 +24,7 @@
#include <osmocom/core/utils.h>
-/*! load unaligned n-byte integer (little-endian encoding) into uintXX_t
+/*! load unaligned n-byte integer (little-endian encoding) into uintXX_t, into the least significant octets.
* \param[in] p Buffer where integer is stored
* \param[in] n Number of bytes stored in p
* \returns XX bit unsigned integer
@@ -39,7 +39,9 @@ static inline uintXX_t osmo_loadXXle_ext(const void *p, uint8_t n)
return r;
}
-/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t
+/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t, into the MOST significant octets.
+ * WARNING: for n < sizeof(uintXX_t), the result is not returned in the least significant octets, as one might expect.
+ * To always return the same value as fed to osmo_storeXXbe_ext() before, use osmo_loadXXbe_ext_2().
* \param[in] p Buffer where integer is stored
* \param[in] n Number of bytes stored in p
* \returns XX bit unsigned integer
@@ -54,6 +56,21 @@ static inline uintXX_t osmo_loadXXbe_ext(const void *p, uint8_t n)
return r;
}
+/*! load unaligned n-byte integer (big-endian encoding) into uintXX_t, into the least significant octets.
+ * \param[in] p Buffer where integer is stored
+ * \param[in] n Number of bytes stored in p
+ * \returns XX bit unsigned integer
+ */
+static inline uintXX_t osmo_loadXXbe_ext_2(const void *p, uint8_t n)
+{
+ uint8_t i;
+ uintXX_t r = 0;
+ const uint8_t *q = (uint8_t *)p;
+ OSMO_ASSERT(n <= sizeof(r));
+ for(i = 0; i < n; r |= ((uintXX_t)q[i] << (XX - 8* (1 + i + (sizeof(r) - n)))), i++);
+ return r;
+}
+
/*! store unaligned n-byte integer (little-endian encoding) from uintXX_t
* \param[in] x unsigned XX bit integer
diff --git a/tests/bitgen/bitgen_test.c b/tests/bitgen/bitgen_test.c
index 0c9821e2..8657bbef 100644
--- a/tests/bitgen/bitgen_test.c
+++ b/tests/bitgen/bitgen_test.c
@@ -22,10 +22,25 @@
read_val = osmo_load##SIZE####BE_LE##_ext(&buf[at_idx], len); \
printf("osmo_load" #SIZE #BE_LE "_ext(&buf[%d], %d) = 0x%" PRIx##SIZE "\n", \
at_idx, len, read_val); \
+ \
+ if (!strcmp(#BE_LE, "be")) { \
+ read_val = osmo_load##SIZE####BE_LE##_ext_2(&buf[at_idx], len); \
+ printf("osmo_load" #SIZE #BE_LE "_ext_2(&buf[%d], %d) = 0x%" PRIx##SIZE "\n", \
+ at_idx, len, read_val); \
+ } \
} \
} \
} while (0)
+/* Shims to allow compiling, the *le_ext_2 are not actually invoked because of the strcmp() condition above. */
+#define osmo_load16le_ext_2 dummy
+#define osmo_load32le_ext_2 dummy
+#define osmo_load64le_ext_2 dummy
+
+static inline uint64_t dummy(const void *p, uint8_t n)
+{
+ OSMO_ASSERT(false);
+}
int main(int argc, char **argv)
{
@@ -37,7 +52,7 @@ int main(int argc, char **argv)
DO_TEST(le, 64);
{
- printf("--- store/load 0x112233 as 24bit big-endian\n");
+ printf("--- store/load 0x112233 as 24bit big-endian, legacy\n");
uint8_t buf[4];
memset(buf, 0, sizeof(buf));
osmo_store32be_ext(0x00112233, buf, 3); // stores 11 22 33
@@ -47,6 +62,16 @@ int main(int argc, char **argv)
}
{
+ printf("--- store/load 0x112233 as 24bit big-endian\n");
+ uint8_t buf[4];
+ memset(buf, 0, sizeof(buf));
+ osmo_store32be_ext(0x00112233, buf, 3); // stores 11 22 33
+ printf("%s\n", osmo_hexdump(buf, 4));
+ uint32_t r = osmo_load32be_ext_2(buf, 3); // returns 0x00112233
+ printf("0x%x\n", r);
+ }
+
+ {
printf("--- store/load 0x112233 as 24bit little-endian\n");
uint8_t buf[4];
memset(buf, 0, sizeof(buf));
diff --git a/tests/bitgen/bitgen_test.ok b/tests/bitgen/bitgen_test.ok
index f89b66ae..b8ce9bc8 100644
--- a/tests/bitgen/bitgen_test.ok
+++ b/tests/bitgen/bitgen_test.ok
@@ -1,10 +1,13 @@
--- 16 be
osmo_store16be_ext(0x2211, &buf[0], 2) = 22 11 00 00
osmo_load16be_ext(&buf[0], 2) = 0x2211
+osmo_load16be_ext_2(&buf[0], 2) = 0x2211
osmo_store16be_ext(0x2211, &buf[1], 2) = 00 22 11 00
osmo_load16be_ext(&buf[1], 2) = 0x2211
+osmo_load16be_ext_2(&buf[1], 2) = 0x2211
osmo_store16be_ext(0x2211, &buf[0], 1) = 11 00
osmo_load16be_ext(&buf[0], 1) = 0x1100
+osmo_load16be_ext_2(&buf[0], 1) = 0x11
--- 16 le
osmo_store16le_ext(0x2211, &buf[0], 2) = 11 22 00 00
osmo_load16le_ext(&buf[0], 2) = 0x2211
@@ -15,24 +18,34 @@ osmo_load16le_ext(&buf[0], 1) = 0x11
--- 32 be
osmo_store32be_ext(0x44332211, &buf[0], 4) = 44 33 22 11 00 00 00 00
osmo_load32be_ext(&buf[0], 4) = 0x44332211
+osmo_load32be_ext_2(&buf[0], 4) = 0x44332211
osmo_store32be_ext(0x44332211, &buf[1], 4) = 00 44 33 22 11 00 00 00
osmo_load32be_ext(&buf[1], 4) = 0x44332211
+osmo_load32be_ext_2(&buf[1], 4) = 0x44332211
osmo_store32be_ext(0x44332211, &buf[2], 4) = 00 00 44 33 22 11 00 00
osmo_load32be_ext(&buf[2], 4) = 0x44332211
+osmo_load32be_ext_2(&buf[2], 4) = 0x44332211
osmo_store32be_ext(0x44332211, &buf[3], 4) = 00 00 00 44 33 22 11 00
osmo_load32be_ext(&buf[3], 4) = 0x44332211
+osmo_load32be_ext_2(&buf[3], 4) = 0x44332211
osmo_store32be_ext(0x44332211, &buf[0], 3) = 33 22 11 00 00 00
osmo_load32be_ext(&buf[0], 3) = 0x33221100
+osmo_load32be_ext_2(&buf[0], 3) = 0x332211
osmo_store32be_ext(0x44332211, &buf[1], 3) = 00 33 22 11 00 00
osmo_load32be_ext(&buf[1], 3) = 0x33221100
+osmo_load32be_ext_2(&buf[1], 3) = 0x332211
osmo_store32be_ext(0x44332211, &buf[2], 3) = 00 00 33 22 11 00
osmo_load32be_ext(&buf[2], 3) = 0x33221100
+osmo_load32be_ext_2(&buf[2], 3) = 0x332211
osmo_store32be_ext(0x44332211, &buf[0], 2) = 22 11 00 00
osmo_load32be_ext(&buf[0], 2) = 0x22110000
+osmo_load32be_ext_2(&buf[0], 2) = 0x2211
osmo_store32be_ext(0x44332211, &buf[1], 2) = 00 22 11 00
osmo_load32be_ext(&buf[1], 2) = 0x22110000
+osmo_load32be_ext_2(&buf[1], 2) = 0x2211
osmo_store32be_ext(0x44332211, &buf[0], 1) = 11 00
osmo_load32be_ext(&buf[0], 1) = 0x11000000
+osmo_load32be_ext_2(&buf[0], 1) = 0x11
--- 32 le
osmo_store32le_ext(0x44332211, &buf[0], 4) = 11 22 33 44 00 00 00 00
osmo_load32le_ext(&buf[0], 4) = 0x44332211
@@ -57,76 +70,112 @@ osmo_load32le_ext(&buf[0], 1) = 0x11
--- 64 be
osmo_store64be_ext(0x8877665544332211, &buf[0], 8) = 88 77 66 55 44 33 22 11 00 00 00 00 00 00 00 00
osmo_load64be_ext(&buf[0], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[0], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[1], 8) = 00 88 77 66 55 44 33 22 11 00 00 00 00 00 00 00
osmo_load64be_ext(&buf[1], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[1], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[2], 8) = 00 00 88 77 66 55 44 33 22 11 00 00 00 00 00 00
osmo_load64be_ext(&buf[2], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[2], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[3], 8) = 00 00 00 88 77 66 55 44 33 22 11 00 00 00 00 00
osmo_load64be_ext(&buf[3], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[3], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[4], 8) = 00 00 00 00 88 77 66 55 44 33 22 11 00 00 00 00
osmo_load64be_ext(&buf[4], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[4], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[5], 8) = 00 00 00 00 00 88 77 66 55 44 33 22 11 00 00 00
osmo_load64be_ext(&buf[5], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[5], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[6], 8) = 00 00 00 00 00 00 88 77 66 55 44 33 22 11 00 00
osmo_load64be_ext(&buf[6], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[6], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[7], 8) = 00 00 00 00 00 00 00 88 77 66 55 44 33 22 11 00
osmo_load64be_ext(&buf[7], 8) = 0x8877665544332211
+osmo_load64be_ext_2(&buf[7], 8) = 0x8877665544332211
osmo_store64be_ext(0x8877665544332211, &buf[0], 7) = 77 66 55 44 33 22 11 00 00 00 00 00 00 00
osmo_load64be_ext(&buf[0], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[0], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[1], 7) = 00 77 66 55 44 33 22 11 00 00 00 00 00 00
osmo_load64be_ext(&buf[1], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[1], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[2], 7) = 00 00 77 66 55 44 33 22 11 00 00 00 00 00
osmo_load64be_ext(&buf[2], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[2], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[3], 7) = 00 00 00 77 66 55 44 33 22 11 00 00 00 00
osmo_load64be_ext(&buf[3], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[3], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[4], 7) = 00 00 00 00 77 66 55 44 33 22 11 00 00 00
osmo_load64be_ext(&buf[4], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[4], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[5], 7) = 00 00 00 00 00 77 66 55 44 33 22 11 00 00
osmo_load64be_ext(&buf[5], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[5], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[6], 7) = 00 00 00 00 00 00 77 66 55 44 33 22 11 00
osmo_load64be_ext(&buf[6], 7) = 0x7766554433221100
+osmo_load64be_ext_2(&buf[6], 7) = 0x77665544332211
osmo_store64be_ext(0x8877665544332211, &buf[0], 6) = 66 55 44 33 22 11 00 00 00 00 00 00
osmo_load64be_ext(&buf[0], 6) = 0x6655443322110000
+osmo_load64be_ext_2(&buf[0], 6) = 0x665544332211
osmo_store64be_ext(0x8877665544332211, &buf[1], 6) = 00 66 55 44 33 22 11 00 00 00 00 00
osmo_load64be_ext(&buf[1], 6) = 0x6655443322110000
+osmo_load64be_ext_2(&buf[1], 6) = 0x665544332211
osmo_store64be_ext(0x8877665544332211, &buf[2], 6) = 00 00 66 55 44 33 22 11 00 00 00 00
osmo_load64be_ext(&buf[2], 6) = 0x6655443322110000
+osmo_load64be_ext_2(&buf[2], 6) = 0x665544332211
osmo_store64be_ext(0x8877665544332211, &buf[3], 6) = 00 00 00 66 55 44 33 22 11 00 00 00
osmo_load64be_ext(&buf[3], 6) = 0x6655443322110000
+osmo_load64be_ext_2(&buf[3], 6) = 0x665544332211
osmo_store64be_ext(0x8877665544332211, &buf[4], 6) = 00 00 00 00 66 55 44 33 22 11 00 00
osmo_load64be_ext(&buf[4], 6) = 0x6655443322110000
+osmo_load64be_ext_2(&buf[4], 6) = 0x665544332211
osmo_store64be_ext(0x8877665544332211, &buf[5], 6) = 00 00 00 00 00 66 55 44 33 22 11 00
osmo_load64be_ext(&buf[5], 6) = 0x6655443322110000
+osmo_load64be_ext_2(&buf[5], 6) = 0x665544332211
osmo_store64be_ext(0x8877665544332211, &buf[0], 5) = 55 44 33 22 11 00 00 00 00 00
osmo_load64be_ext(&buf[0], 5) = 0x5544332211000000
+osmo_load64be_ext_2(&buf[0], 5) = 0x5544332211
osmo_store64be_ext(0x8877665544332211, &buf[1], 5) = 00 55 44 33 22 11 00 00 00 00
osmo_load64be_ext(&buf[1], 5) = 0x5544332211000000
+osmo_load64be_ext_2(&buf[1], 5) = 0x5544332211
osmo_store64be_ext(0x8877665544332211, &buf[2], 5) = 00 00 55 44 33 22 11 00 00 00
osmo_load64be_ext(&buf[2], 5) = 0x5544332211000000
+osmo_load64be_ext_2(&buf[2], 5) = 0x5544332211
osmo_store64be_ext(0x8877665544332211, &buf[3], 5) = 00 00 00 55 44 33 22 11 00 00
osmo_load64be_ext(&buf[3], 5) = 0x5544332211000000
+osmo_load64be_ext_2(&buf[3], 5) = 0x5544332211
osmo_store64be_ext(0x8877665544332211, &buf[4], 5) = 00 00 00 00 55 44 33 22 11 00
osmo_load64be_ext(&buf[4], 5) = 0x5544332211000000
+osmo_load64be_ext_2(&buf[4], 5) = 0x5544332211
osmo_store64be_ext(0x8877665544332211, &buf[0], 4) = 44 33 22 11 00 00 00 00
osmo_load64be_ext(&buf[0], 4) = 0x4433221100000000
+osmo_load64be_ext_2(&buf[0], 4) = 0x44332211
osmo_store64be_ext(0x8877665544332211, &buf[1], 4) = 00 44 33 22 11 00 00 00
osmo_load64be_ext(&buf[1], 4) = 0x4433221100000000
+osmo_load64be_ext_2(&buf[1], 4) = 0x44332211
osmo_store64be_ext(0x8877665544332211, &buf[2], 4) = 00 00 44 33 22 11 00 00
osmo_load64be_ext(&buf[2], 4) = 0x4433221100000000
+osmo_load64be_ext_2(&buf[2], 4) = 0x44332211
osmo_store64be_ext(0x8877665544332211, &buf[3], 4) = 00 00 00 44 33 22 11 00
osmo_load64be_ext(&buf[3], 4) = 0x4433221100000000
+osmo_load64be_ext_2(&buf[3], 4) = 0x44332211
osmo_store64be_ext(0x8877665544332211, &buf[0], 3) = 33 22 11 00 00 00
osmo_load64be_ext(&buf[0], 3) = 0x3322110000000000
+osmo_load64be_ext_2(&buf[0], 3) = 0x332211
osmo_store64be_ext(0x8877665544332211, &buf[1], 3) = 00 33 22 11 00 00
osmo_load64be_ext(&buf[1], 3) = 0x3322110000000000
+osmo_load64be_ext_2(&buf[1], 3) = 0x332211
osmo_store64be_ext(0x8877665544332211, &buf[2], 3) = 00 00 33 22 11 00
osmo_load64be_ext(&buf[2], 3) = 0x3322110000000000
+osmo_load64be_ext_2(&buf[2], 3) = 0x332211
osmo_store64be_ext(0x8877665544332211, &buf[0], 2) = 22 11 00 00
osmo_load64be_ext(&buf[0], 2) = 0x2211000000000000
+osmo_load64be_ext_2(&buf[0], 2) = 0x2211
osmo_store64be_ext(0x8877665544332211, &buf[1], 2) = 00 22 11 00
osmo_load64be_ext(&buf[1], 2) = 0x2211000000000000
+osmo_load64be_ext_2(&buf[1], 2) = 0x2211
osmo_store64be_ext(0x8877665544332211, &buf[0], 1) = 11 00
osmo_load64be_ext(&buf[0], 1) = 0x1100000000000000
+osmo_load64be_ext_2(&buf[0], 1) = 0x11
--- 64 le
osmo_store64le_ext(0x8877665544332211, &buf[0], 8) = 11 22 33 44 55 66 77 88 00 00 00 00 00 00 00 00
osmo_load64le_ext(&buf[0], 8) = 0x8877665544332211
@@ -200,9 +249,12 @@ osmo_store64le_ext(0x8877665544332211, &buf[1], 2) = 00 11 22 00
osmo_load64le_ext(&buf[1], 2) = 0x2211
osmo_store64le_ext(0x8877665544332211, &buf[0], 1) = 11 00
osmo_load64le_ext(&buf[0], 1) = 0x11
---- store/load 0x112233 as 24bit big-endian
+--- store/load 0x112233 as 24bit big-endian, legacy
11 22 33 00
0x11223300
+--- store/load 0x112233 as 24bit big-endian
+11 22 33 00
+0x112233
--- store/load 0x112233 as 24bit little-endian
33 22 11 00
0x112233