- rename log functions to stop conflicts under win32 (wingdi)
[openocd.git] / src / helper / binarybuffer.c
1 /***************************************************************************
2 * Copyright (C) 2004, 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (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 *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "types.h"
28 #include "log.h"
29
30 #include "binarybuffer.h"
31
32 int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value);
33 u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num);
34 u32 flip_u32(u32 value, unsigned int num);
35
36 const unsigned char bit_reverse_table256[] =
37 {
38 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
39 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
40 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
41 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
42 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
43 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
44 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
45 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
46 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
47 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
48 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
49 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
50 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
51 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
52 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
53 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
54 };
55
56 int buf_set_u32(u8* buffer, unsigned int first, unsigned int num, u32 value)
57 {
58 unsigned int i;
59
60 if (!buffer)
61 return ERROR_INVALID_ARGUMENTS;
62
63 for (i=first; i<first+num; i++)
64 {
65 if (((value >> (i-first))&1) == 1)
66 buffer[i/8] |= 1 << (i%8);
67 else
68 buffer[i/8] &= ~(1 << (i%8));
69 }
70
71 return ERROR_OK;
72 }
73
74 u32 buf_get_u32(u8* buffer, unsigned int first, unsigned int num)
75 {
76 u32 result = 0;
77 unsigned int i;
78
79 if (!buffer)
80 {
81 LOG_ERROR("buffer not initialized");
82 return 0;
83 }
84
85 for (i=first; i<first+num; i++)
86 {
87 if (((buffer[i/8]>>(i%8))&1) == 1)
88 result |= 1 << (i-first);
89 }
90
91 return result;
92 }
93
94 u8* buf_cpy(u8 *from, u8 *to, int size)
95 {
96 int num_bytes = CEIL(size, 8);
97 unsigned int i;
98
99 if (from == NULL)
100 return NULL;
101
102 for (i = 0; i < num_bytes; i++)
103 to[i] = from[i];
104
105 /* mask out bits that don't belong to the buffer */
106 if (size % 8)
107 {
108 to[size / 8] &= (0xff >> (8 - (size % 8)));
109 }
110
111 return to;
112 }
113
114 int buf_cmp(u8 *buf1, u8 *buf2, int size)
115 {
116 int num_bytes = CEIL(size, 8);
117 int i;
118
119 if (!buf1 || !buf2)
120 return 1;
121
122 for (i = 0; i < num_bytes; i++)
123 {
124 /* last byte */
125 /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
126 if ((size % 8) && (i == num_bytes -1 ))
127 {
128 if ((buf1[i] & ((1 << (size % 8)) - 1)) != (buf2[i] & ((1 << (size % 8)) - 1)))
129 return 1;
130 }
131 else
132 {
133 if (buf1[i] != buf2[i])
134 return 1;
135 }
136 }
137
138 return 0;
139 }
140
141 int buf_cmp_mask(u8 *buf1, u8 *buf2, u8 *mask, int size)
142 {
143 int num_bytes = CEIL(size, 8);
144 int i;
145
146 for (i = 0; i < num_bytes; i++)
147 {
148 /* last byte */
149 /* mask out bits that don't really belong to the buffer if size isn't a multiple of 8 bits */
150 if ((size % 8) && (i == num_bytes -1 ))
151 {
152 if ((buf1[i] & ((1 << (size % 8)) - 1) & mask[i]) !=
153 (buf2[i] & ((1 << (size % 8)) - 1) & mask[i]))
154 return 1;
155 }
156 else
157 {
158 if ((buf1[i] & mask[i]) != (buf2[i] & mask[i]))
159 return 1;
160 }
161 }
162
163 return 0;
164 }
165
166 u8* buf_set_ones(u8 *buf, int count)
167 {
168 int num_bytes = CEIL(count, 8);
169 int i;
170
171 for (i = 0; i < num_bytes; i++)
172 {
173 if (count >= 8)
174 buf[i] = 0xff;
175 else
176 buf[i] = (1 << count) - 1;
177
178 count -= 8;
179 }
180
181 return buf;
182 }
183
184 u8* buf_set_buf(u8 *src, int src_start, u8 *dst, int dst_start, int len)
185 {
186 int src_idx = src_start, dst_idx = dst_start;
187 int i;
188
189 for (i = 0; i < len; i++)
190 {
191 if (((src[src_idx/8] >> (src_idx % 8)) & 1) == 1)
192 dst[dst_idx/8] |= 1 << (dst_idx%8);
193 else
194 dst[dst_idx/8] &= ~(1 << (dst_idx%8));
195 dst_idx++;
196 src_idx++;
197 }
198
199 return dst;
200 }
201
202 u32 flip_u32(u32 value, unsigned int num)
203 {
204 u32 c;
205
206 c = (bit_reverse_table256[value & 0xff] << 24) |
207 (bit_reverse_table256[(value >> 8) & 0xff] << 16) |
208 (bit_reverse_table256[(value >> 16) & 0xff] << 8) |
209 (bit_reverse_table256[(value >> 24) & 0xff]);
210
211 if (num < 32)
212 c = c >> (32 - num);
213
214 return c;
215 }
216
217 int ceil_f_to_u32(float x)
218 {
219 u32 y;
220
221 if (x < 0) /* return zero for negative numbers */
222 return 0;
223
224 y = x; /* cut off fraction */
225
226 if ((x - y) > 0.0) /* if there was a fractional part, increase by one */
227 y++;
228
229 return y;
230 }
231
232 char* buf_to_str(u8 *buf, int buf_len, int radix)
233 {
234 const char *DIGITS = "0123456789abcdef";
235 float factor;
236 char *str;
237 int str_len;
238 int b256_len = CEIL(buf_len, 8);
239 u32 tmp;
240
241 int j; /* base-256 digits */
242 int i; /* output digits (radix) */
243
244 if (radix == 16)
245 {
246 factor = 2.0; /* log(256) / log(16) = 2.0 */
247 }
248 else if (radix == 10)
249 {
250 factor = 2.40824; /* log(256) / log(10) = 2.40824 */
251 }
252 else if (radix == 8)
253 {
254 factor = 2.66667; /* log(256) / log(8) = 2.66667 */
255 }
256 else
257 return NULL;
258
259 str_len = ceil_f_to_u32(CEIL(buf_len, 8) * factor);
260 str = calloc(str_len + 1, 1);
261
262 for (i = b256_len - 1; i >= 0; i--)
263 {
264 tmp = buf[i];
265 if ((i == (buf_len / 8)) && (buf_len % 8))
266 tmp &= (0xff >> (8 - (buf_len % 8)));
267
268 for (j = str_len; j > 0; j--)
269 {
270 tmp += (u32)str[j-1] * 256;
271 str[j-1] = (u8)(tmp % radix);
272 tmp /= radix;
273 }
274 }
275
276 for (j = 0; j < str_len; j++)
277 str[j] = DIGITS[(int)str[j]];
278
279 return str;
280 }
281
282 int str_to_buf(char* str, int str_len, u8 *buf, int buf_len, int radix)
283 {
284 char *charbuf;
285 u32 tmp;
286 float factor;
287 u8 *b256_buf;
288 int b256_len;
289
290 int j; /* base-256 digits */
291 int i; /* input digits (ASCII) */
292
293 if (radix == 0)
294 {
295 /* identify radix, and skip radix-prefix (0, 0x or 0X) */
296 if ((str[0] == '0') && (str[1] && ((str[1] == 'x') || (str[1] == 'X'))))
297 {
298 radix = 16;
299 str += 2;
300 str_len -= 2;
301 }
302 else if ((str[0] == '0') && (str_len != 1))
303 {
304 radix = 8;
305 str += 1;
306 str_len -= 1;
307 }
308 else
309 {
310 radix = 10;
311 }
312 }
313
314 if (radix == 16)
315 factor = 0.5; /* log(16) / log(256) = 0.5 */
316 else if (radix == 10)
317 factor = 0.41524; /* log(10) / log(256) = 0.41524 */
318 else if (radix == 8)
319 factor = 0.375; /* log(8) / log(256) = 0.375 */
320 else
321 return 0;
322
323 /* copy to zero-terminated buffer */
324 charbuf = malloc(str_len + 1);
325 memcpy(charbuf, str, str_len);
326 charbuf[str_len] = '\0';
327
328 /* number of digits in base-256 notation */
329 b256_len = ceil_f_to_u32(str_len * factor);
330 b256_buf = calloc(b256_len, 1);
331
332 /* go through zero terminated buffer */
333 for (i = 0; charbuf[i]; i++)
334 {
335 tmp = charbuf[i];
336 if ((tmp >= '0') && (tmp <= '9'))
337 tmp = (tmp - '0');
338 else if ((tmp >= 'a') && (tmp <= 'f'))
339 tmp = (tmp - 'a' + 10);
340 else if ((tmp >= 'A') && (tmp <= 'F'))
341 tmp = (tmp - 'A' + 10);
342 else continue; /* skip characters other than [0-9,a-f,A-F] */
343
344 if (tmp >= radix)
345 continue; /* skip digits invalid for the current radix */
346
347 for (j = 0; j < b256_len; j++)
348 {
349 tmp += (u32)b256_buf[j] * radix;
350 b256_buf[j] = (u8)(tmp & 0xFF);
351 tmp >>= 8;
352 }
353
354 }
355
356 for (j = 0; j < CEIL(buf_len, 8); j++)
357 {
358 if (j < b256_len)
359 buf[j] = b256_buf[j];
360 else
361 buf[j] = 0;
362 }
363
364 /* mask out bits that don't belong to the buffer */
365 if (buf_len % 8)
366 buf[(buf_len / 8)] &= 0xff >> (8 - (buf_len % 8));
367
368 free(b256_buf);
369 free(charbuf);
370
371 return i;
372 }
373
374 int buf_to_u32_handler(u8 *in_buf, void *priv, struct scan_field_s *field)
375 {
376 u32 *dest = priv;
377
378 *dest = buf_get_u32(in_buf, 0, 32);
379
380 return ERROR_OK;
381 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)