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

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)