blob: 3955e3bb178583c1ba0be813d58a77a5e3000673 [file] [log] [blame]
Harald Welte2230c132011-01-19 10:10:16 +01001
2#include <stdint.h>
3
Pablo Neira Ayuso83419342011-03-22 16:36:13 +01004#include <osmocom/core/bits.h>
Harald Welte2230c132011-01-19 10:10:16 +01005
Harald Welteba6988b2011-08-17 12:46:48 +02006/*! \addtogroup bits
7 * @{
8 */
9
10/*! \file bits.c
11 * \brief Osmocom bit level support code
12 */
13
14
15/*! \brief convert unpacked bits to packed bits, return length in bytes
16 * \param[out] out output buffer of packed bits
17 * \param[in] in input buffer of unpacked bits
18 * \param[in] num_bits number of bits
19 */
Harald Welte2230c132011-01-19 10:10:16 +010020int osmo_ubit2pbit(pbit_t *out, const ubit_t *in, unsigned int num_bits)
21{
22 unsigned int i;
23 uint8_t curbyte = 0;
24 pbit_t *outptr = out;
25
26 for (i = 0; i < num_bits; i++) {
27 uint8_t bitnum = 7 - (i % 8);
28
29 curbyte |= (in[i] << bitnum);
30
Christian Vogelc7f84e92011-01-22 22:48:37 +010031 if(i % 8 == 7){
Harald Welte2230c132011-01-19 10:10:16 +010032 *outptr++ = curbyte;
33 curbyte = 0;
34 }
35 }
36 /* we have a non-modulo-8 bitcount */
37 if (i % 8)
38 *outptr++ = curbyte;
39
40 return outptr - out;
41}
42
Harald Welteba6988b2011-08-17 12:46:48 +020043/*! \brief convert packed bits to unpacked bits, return length in bytes
44 * \param[out] out output buffer of unpacked bits
45 * \param[in] in input buffer of packed bits
46 * \param[in] num_bits number of bits
47 */
Harald Welte2230c132011-01-19 10:10:16 +010048int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits)
49{
50 unsigned int i;
51 ubit_t *cur = out;
52 ubit_t *limit = out + num_bits;
53
54 for (i = 0; i < (num_bits/8)+1; i++) {
55 pbit_t byte = in[i];
56 *cur++ = (byte >> 7) & 1;
57 if (cur >= limit)
58 break;
59 *cur++ = (byte >> 6) & 1;
60 if (cur >= limit)
61 break;
62 *cur++ = (byte >> 5) & 1;
63 if (cur >= limit)
64 break;
65 *cur++ = (byte >> 4) & 1;
66 if (cur >= limit)
67 break;
68 *cur++ = (byte >> 3) & 1;
69 if (cur >= limit)
70 break;
71 *cur++ = (byte >> 2) & 1;
72 if (cur >= limit)
73 break;
74 *cur++ = (byte >> 1) & 1;
75 if (cur >= limit)
76 break;
77 *cur++ = (byte >> 0) & 1;
78 if (cur >= limit)
79 break;
80 }
81 return cur - out;
82}
Sylvain Munautaeb10772011-01-21 12:22:30 +010083
Harald Welteba6988b2011-08-17 12:46:48 +020084/*! \brief convert unpacked bits to packed bits (extended options)
85 * \param[out] out output buffer of packed bits
86 * \param[in] out_ofs offset into output buffer
87 * \param[in] in input buffer of unpacked bits
88 * \param[in] in_ofs offset into input buffer
89 * \param[in] num_bits number of bits
90 * \param[in] lsb_mode Encode bits in LSB orde instead of MSB
91 * \returns length in bytes (max written offset of output buffer + 1)
92 */
Sylvain Munautaeb10772011-01-21 12:22:30 +010093int osmo_ubit2pbit_ext(pbit_t *out, unsigned int out_ofs,
94 const ubit_t *in, unsigned int in_ofs,
95 unsigned int num_bits, int lsb_mode)
96{
97 int i, op, bn;
98 for (i=0; i<num_bits; i++) {
99 op = out_ofs + i;
100 bn = lsb_mode ? (op&7) : (7-(op&7));
101 if (in[in_ofs+i])
102 out[op>>3] |= 1 << bn;
103 else
104 out[op>>3] &= ~(1 << bn);
105 }
106 return ((out_ofs + num_bits - 1) >> 3) + 1;
107}
108
Harald Welteba6988b2011-08-17 12:46:48 +0200109/*! \brief convert packed bits to unpacked bits (extended options)
110 * \param[out] out output buffer of unpacked bits
111 * \param[in] out_ofs offset into output buffer
112 * \param[in] in input buffer of packed bits
113 * \param[in] in_ofs offset into input buffer
114 * \param[in] num_bits number of bits
115 * \param[in] lsb_mode Encode bits in LSB orde instead of MSB
116 * \returns length in bytes (max written offset of output buffer + 1)
117 */
Sylvain Munautaeb10772011-01-21 12:22:30 +0100118int osmo_pbit2ubit_ext(ubit_t *out, unsigned int out_ofs,
119 const pbit_t *in, unsigned int in_ofs,
120 unsigned int num_bits, int lsb_mode)
121{
122 int i, ip, bn;
123 for (i=0; i<num_bits; i++) {
124 ip = in_ofs + i;
125 bn = lsb_mode ? (ip&7) : (7-(ip&7));
126 out[out_ofs+i] = !!(in[ip>>3] & (1<<bn));
127 }
128 return out_ofs + num_bits;
129}
Harald Welteba6988b2011-08-17 12:46:48 +0200130
131/*! }@ */