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

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)