blob: 10284073e7c23ec214903e9337d241a82d640e78 [file] [log] [blame]
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +04001/* bitvector.cpp
2 *
3 * Copyright (C) 2012 Ivan Klyuchnikov
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20/*! \addtogroup bitvector
21 * @{
22 */
23
24/*! \file bitvector.cpp
25 * \brief Additional functions for Osmocom bit vector abstraction.
26 */
27
28#include <bitvector.h>
29extern "C" {
30#include <osmocom/core/talloc.h>
31}
32
33void *bv_tall_ctx;
34
35struct bitvec *bitvec_alloc(unsigned size)
36{
37 struct bitvec *bv = talloc_zero(bv_tall_ctx, struct bitvec);
38 bv->data_len = size;
39 bv->cur_bit = 0;
40 bv->data = talloc_zero_array(bv_tall_ctx, uint8_t, size);
41 return bv;
42}
43
44void bitvec_free(struct bitvec *bv)
45{
46 talloc_free(bv->data);
47 talloc_free(bv);
48}
49
Holger Hans Peter Freyther939bfae2013-07-28 16:04:35 +020050unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer)
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +040051{
Holger Hans Peter Freyther939bfae2013-07-28 16:04:35 +020052 unsigned int i = 0;
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +040053 for (i = 0; i < bv->data_len; i++)
54 {
55 buffer[i] = bv->data[i];
56 }
57 return i;
58}
59
Holger Hans Peter Freyther939bfae2013-07-28 16:04:35 +020060unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer)
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +040061{
Holger Hans Peter Freyther939bfae2013-07-28 16:04:35 +020062 unsigned int i = 0;
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +040063 for (i = 0; i < bv->data_len; i++)
64 {
65 bv->data[i] = buffer[i];
66 }
67 return i;
68}
69
70
71int bitvec_unhex(struct bitvec *bv, const char* src)
72{
73 unsigned val;
74 unsigned write_index = 0;
75 unsigned digits = bv->data_len*2;
76 for (unsigned i=0; i<digits; i++) {
77 if (sscanf(src+i, "%1x", &val) < 1) {
78 return 1;
79 }
80 bitvec_write_field(bv, write_index,val, 4);
81 }
82 return 0;
83}
84
85uint64_t bitvec_read_field(struct bitvec *bv, unsigned& read_index, unsigned len)
86{
Holger Hans Peter Freyther939bfae2013-07-28 16:04:35 +020087 unsigned int i;
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +040088 uint64_t ui = 0;
89 bv->cur_bit = read_index;
90
91 for (i = 0; i < len; i++) {
92 int bit = bitvec_get_bit_pos((const struct bitvec *)bv, bv->cur_bit);
93 if (bit < 0)
94 return bit;
95 if (bit)
96 ui |= ((uint64_t)1 << (len - i - 1));
97 bv->cur_bit++;
98 }
99 read_index += len;
100 return ui;
101}
102
103
104int bitvec_write_field(struct bitvec *bv, unsigned& write_index, uint64_t val, unsigned len)
105{
Holger Hans Peter Freyther939bfae2013-07-28 16:04:35 +0200106 unsigned int i;
107 int rc;
Ivan Kluchnikov962f97b2012-04-30 17:51:23 +0400108 bv->cur_bit = write_index;
109 for (i = 0; i < len; i++) {
110 int bit = 0;
111 if (val & ((uint64_t)1 << (len - i - 1)))
112 bit = 1;
113 rc = bitvec_set_bit(bv, (bit_value)bit);
114 if (rc)
115 return rc;
116 }
117 write_index += len;
118 return 0;
119}
Jacob Erlbeck4e7424d2016-02-01 13:26:22 +0100120
121int bitvec_write_field_lh(struct bitvec *bv, unsigned& write_index,
122 uint64_t val, unsigned len)
123{
124 unsigned int i;
125 int rc;
126 bv->cur_bit = write_index;
127 for (i = 0; i < len; i++) {
128 bit_value bit = L;
129 if (val & ((uint64_t)1 << (len - i - 1)))
130 bit = H;
131 rc = bitvec_set_bit(bv, bit);
132 if (rc)
133 return rc;
134 }
135 write_index += len;
136 return 0;
137}