Freeciv-3.3
Loading...
Searching...
No Matches
bitvector.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include "fc_prehdrs.h"
19
20#include <errno.h>
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25
26/* utility */
27#include "fciconv.h"
28#include "fcintl.h"
29#include "mem.h"
30#include "rand.h"
31#include "string_vector.h"
32
33#include "bitvector.h"
34
35/* There are two types of bitvectors defined in this file:
36 (1) bv_* - static bitvectors; used for data where the length is
37 fixed (number of players; flags for enums; ...). They are
38 named bv_*, and BV_* macros are defined.
39 (2) dbv_* - dynamic bitvectors; their size is not known a priori
40 but defined by the player (map known bitvectors).
41 These bitvectors are given as 'struct dbv' and the information
42 can be accessed using dbv_*() functions.
43 They use BV_* macros. */
44
45/***********************************************************************/
50void dbv_init(struct dbv *pdbv, int bits)
51{
52 /* Here used to be asserts checking if pdbv->vec is nullptr
53 * and pdbv->bits is 0, but that's just broken. One would
54 * assume that _init() function can be called when the thing
55 * is currently uninitialized, i.e., can have any values.
56 * Those fc_assert_ret()s caused this function to return
57 * without actually initializing the structure, leading to
58 * crash later. */
59
60 fc_assert_ret(bits > 0 && bits < MAX_DBV_LENGTH);
61
62 pdbv->bits = bits;
63 pdbv->vec = fc_calloc(1, _BV_BYTES(pdbv->bits) * sizeof(*pdbv->vec));
64
66}
67
68/***********************************************************************/
71void dbv_resize(struct dbv *pdbv, int bits)
72{
73 fc_assert_ret(bits > 0 && bits < MAX_DBV_LENGTH);
74
75 if (pdbv->vec == nullptr) {
76 /* Initialise a new dbv. */
77 dbv_init(pdbv, bits);
78 } else {
79 /* Resize an existing dbv. */
80 fc_assert_ret(pdbv->bits != 0);
81
82 if (bits != pdbv->bits) {
83 pdbv->bits = bits;
84 pdbv->vec = fc_realloc(pdbv->vec,
85 _BV_BYTES(pdbv->bits) * sizeof(*pdbv->vec));
86 }
87
89 }
90}
91
92/***********************************************************************/
95void dbv_free(struct dbv *pdbv)
96{
97 if (pdbv != nullptr) {
98 free(pdbv->vec);
99 pdbv->vec = nullptr;
100
101 pdbv->bits = 0;
102 }
103}
104
105/***********************************************************************/
108int dbv_bits(struct dbv *pdbv)
109{
110 if (pdbv != nullptr) {
111 return pdbv->bits;
112 }
113
114 return -1;
115}
116
117/***********************************************************************/
120bool dbv_isset(const struct dbv *pdbv, int bit)
121{
122 fc_assert_ret_val(pdbv->vec != nullptr, FALSE);
124
125 return ((pdbv->vec[_BV_BYTE_INDEX(bit)] & _BV_BITMASK(bit)) != 0);
126}
127
128/***********************************************************************/
131bool dbv_isset_any(const struct dbv *pdbv)
132{
133 fc_assert_ret_val(pdbv->vec != nullptr, FALSE);
134
135 return bv_check_mask(pdbv->vec, pdbv->vec, _BV_BYTES(pdbv->bits),
136 _BV_BYTES(pdbv->bits));
137}
138
139/***********************************************************************/
142void dbv_set(struct dbv *pdbv, int bit)
143{
144 fc_assert_ret(pdbv->vec != nullptr);
146
148}
149
150/***********************************************************************/
153void dbv_set_all(struct dbv *pdbv)
154{
155 fc_assert_ret(pdbv->vec != nullptr);
156
157 memset(pdbv->vec, 0xff, _BV_BYTES(pdbv->bits));
158}
159
160/***********************************************************************/
163void dbv_clr(struct dbv *pdbv, int bit)
164{
165 fc_assert_ret(pdbv->vec != nullptr);
167
169}
170
171/***********************************************************************/
174void dbv_clr_all(struct dbv *pdbv)
175{
176 fc_assert_ret(pdbv->vec != nullptr);
177
178 memset(pdbv->vec, 0, _BV_BYTES(pdbv->bits));
179}
180
181/***********************************************************************/
184bool dbv_are_equal(const struct dbv *pdbv1, const struct dbv *pdbv2)
185{
186 fc_assert_ret_val(pdbv1->vec != nullptr, FALSE);
187 fc_assert_ret_val(pdbv2->vec != nullptr, FALSE);
188
189 return bv_are_equal(pdbv1->vec, pdbv2->vec, _BV_BYTES(pdbv1->bits),
190 _BV_BYTES(pdbv2->bits));
191}
192
193/***********************************************************************/
197bool bv_match_dbv(const struct dbv *match, const unsigned char *src)
198{
199 size_t bytes = _BV_BYTES(match->bits);
200 int i;
201
202 for (i = 0; i < bytes; i++) {
203 if (match->vec[i] != src[i]) {
204 return FALSE;
205 }
206 }
207
208 return TRUE;
209}
210
211/***********************************************************************/
214void dbv_copy(struct dbv *dest, const struct dbv *src)
215{
216 if (dest->bits != src->bits) {
217 dbv_resize(dest, src->bits);
218 }
219
220 memcpy(dest->vec, src->vec, _BV_BYTES(src->bits));
221}
222
223/***********************************************************************/
227void dbv_to_bv(unsigned char *dest, const struct dbv *src)
228{
229 memcpy(dest, src->vec, _BV_BYTES(src->bits));
230}
231
232/***********************************************************************/
236void bv_to_dbv(struct dbv *dest, const unsigned char *src)
237{
238 memcpy(dest->vec, dest, _BV_BYTES(dest->bits));
239}
240
241/***********************************************************************/
244void dbv_debug(struct dbv *pdbv)
245{
246 char test_str[51];
247 int i, j, bit;
248
249 fc_assert_ret(pdbv->vec != nullptr);
250
251 for (i = 0; i < (pdbv->bits - 1) / 50 + 1; i++) {
252 for (j = 0; j < 50; j++) {
253 bit = i * 50 + j;
254 if (bit >= pdbv->bits) {
255 break;
256 }
257 test_str[j] = dbv_isset(pdbv, bit) ? '1' : '0';
258 }
259 test_str[j] = '\0';
260 log_error("[%5d] %s", i, test_str);
261 }
262}
263
264/***********************************************************************/
271bool bv_check_mask(const unsigned char *vec1, const unsigned char *vec2,
272 size_t size1, size_t size2)
273{
274 size_t i;
275
277
278 for (i = 0; i < size1; i++) {
279 if ((vec1[0] & vec2[0]) != 0) {
280 return TRUE;
281 }
282 vec1++;
283 vec2++;
284 }
285
286 return FALSE;
287}
288
289/***********************************************************************/
293bool bv_are_equal(const unsigned char *vec1, const unsigned char *vec2,
294 size_t size1, size_t size2)
295{
296 size_t i;
297
299
300 for (i = 0; i < size1; i++) {
301 if (vec1[0] != vec2[0]) {
302 return FALSE;
303 }
304 vec1++;
305 vec2++;
306 }
307
308 return TRUE;
309}
310
311/***********************************************************************/
320void bv_set_all_from(unsigned char *vec_to,
321 const unsigned char *vec_from,
322 size_t size_to, size_t size_from)
323{
324 size_t i;
325
327
328 for (i = 0; i < size_to; i++) {
329 vec_to[i] |= vec_from[i];
330 }
331}
332
333/***********************************************************************/
342void bv_clr_all_from(unsigned char *vec_to,
343 const unsigned char *vec_from,
344 size_t size_to, size_t size_from)
345{
346 size_t i;
347
349
350 for (i = 0; i < size_to; i++) {
351 vec_to[i] &= ~vec_from[i];
352 }
353}
bool bv_check_mask(const unsigned char *vec1, const unsigned char *vec2, size_t size1, size_t size2)
Definition bitvector.c:271
void bv_to_dbv(struct dbv *dest, const unsigned char *src)
Definition bitvector.c:236
bool dbv_isset_any(const struct dbv *pdbv)
Definition bitvector.c:131
void dbv_resize(struct dbv *pdbv, int bits)
Definition bitvector.c:71
bool bv_match_dbv(const struct dbv *match, const unsigned char *src)
Definition bitvector.c:197
void dbv_init(struct dbv *pdbv, int bits)
Definition bitvector.c:50
void bv_clr_all_from(unsigned char *vec_to, const unsigned char *vec_from, size_t size_to, size_t size_from)
Definition bitvector.c:342
int dbv_bits(struct dbv *pdbv)
Definition bitvector.c:108
void dbv_set_all(struct dbv *pdbv)
Definition bitvector.c:153
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c:142
bool bv_are_equal(const unsigned char *vec1, const unsigned char *vec2, size_t size1, size_t size2)
Definition bitvector.c:293
bool dbv_isset(const struct dbv *pdbv, int bit)
Definition bitvector.c:120
void dbv_copy(struct dbv *dest, const struct dbv *src)
Definition bitvector.c:214
void dbv_debug(struct dbv *pdbv)
Definition bitvector.c:244
void bv_set_all_from(unsigned char *vec_to, const unsigned char *vec_from, size_t size_to, size_t size_from)
Definition bitvector.c:320
void dbv_free(struct dbv *pdbv)
Definition bitvector.c:95
void dbv_clr_all(struct dbv *pdbv)
Definition bitvector.c:174
void dbv_clr(struct dbv *pdbv, int bit)
Definition bitvector.c:163
bool dbv_are_equal(const struct dbv *pdbv1, const struct dbv *pdbv2)
Definition bitvector.c:184
void dbv_to_bv(unsigned char *dest, const struct dbv *src)
Definition bitvector.c:227
#define MAX_DBV_LENGTH
Definition bitvector.h:71
#define _BV_BYTE_INDEX(bits)
Definition bitvector.h:75
#define _BV_BYTES(bits)
Definition bitvector.h:74
#define _BV_BITMASK(bit)
Definition bitvector.h:76
char * incite_cost
Definition comments.c:76
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_error(message,...)
Definition log.h:104
#define fc_calloc(n, esz)
Definition mem.h:38
#define fc_realloc(ptr, sz)
Definition mem.h:36
int bits
Definition bitvector.h:33
unsigned char * vec
Definition bitvector.h:34
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47