f2c8a3efb2b56aa03f5b71618e2e428a83fb4c9f
4 * @brief Pointer/lenght abstraction and its functions.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 #include <printf_hook.h>
33 chunk_t chunk_empty
= { NULL
, 0 };
36 * Described in header.
38 chunk_t
chunk_create(u_char
*ptr
, size_t len
)
40 chunk_t chunk
= {ptr
, len
};
45 * Described in header.
47 chunk_t
chunk_create_clone(u_char
*ptr
, chunk_t chunk
)
49 chunk_t clone
= chunk_empty
;
51 if (chunk
.ptr
&& chunk
.len
> 0)
54 clone
.len
= chunk
.len
;
55 memcpy(clone
.ptr
, chunk
.ptr
, chunk
.len
);
64 size_t chunk_length(const char* mode
, ...)
69 va_start(chunks
, mode
);
77 chunk_t ch
= va_arg(chunks
, chunk_t
);
93 chunk_t
chunk_create_cat(u_char
*ptr
, const char* mode
, ...)
96 chunk_t construct
= chunk_create(ptr
, 0);
98 va_start(chunks
, mode
);
101 bool free_chunk
= FALSE
;
110 chunk_t ch
= va_arg(chunks
, chunk_t
);
111 memcpy(ptr
, ch
.ptr
, ch
.len
);
113 construct
.len
+= ch
.len
;
131 * Decribed in header.
133 void chunk_split(chunk_t chunk
, const char *mode
, ...)
139 va_start(chunks
, mode
);
146 len
= va_arg(chunks
, size_t);
147 ch
= va_arg(chunks
, chunk_t
*);
148 /* a null chunk means skip len bytes */
151 chunk
= chunk_skip(chunk
, len
);
158 ch
->len
= min(chunk
.len
, len
);
167 chunk
= chunk_skip(chunk
, ch
->len
);
172 ch
->len
= min(chunk
.len
, len
);
175 ch
->ptr
= malloc(ch
->len
);
176 memcpy(ch
->ptr
, chunk
.ptr
, ch
->len
);
182 chunk
= chunk_skip(chunk
, ch
->len
);
187 ch
->len
= min(ch
->len
, chunk
.len
);
188 ch
->len
= min(ch
->len
, len
);
191 memcpy(ch
->ptr
, chunk
.ptr
, ch
->len
);
197 chunk
= chunk_skip(chunk
, ch
->len
);
210 * Described in header.
212 void chunk_free(chunk_t
*chunk
)
220 * Described in header.
222 chunk_t
chunk_skip(chunk_t chunk
, size_t bytes
)
224 if (chunk
.len
> bytes
)
234 * Described in header.
236 bool chunk_equals(chunk_t a
, chunk_t b
)
238 return a
.ptr
!= NULL
&& b
.ptr
!= NULL
&&
239 a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
243 * Described in header.
245 bool chunk_equals_or_null(chunk_t a
, chunk_t b
)
247 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
249 return a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
253 * Number of bytes per line to dump raw data
255 #define BYTES_PER_LINE 16
258 * output handler in printf() for byte ranges
260 static int print_bytes(FILE *stream
, const struct printf_info
*info
,
261 const void *const *args
)
263 char *bytes
= *((void**)(args
[0]));
264 int len
= *((size_t*)(args
[1]));
266 char buffer
[BYTES_PER_LINE
* 3];
267 char ascii_buffer
[BYTES_PER_LINE
+ 1];
268 char *buffer_pos
= buffer
;
269 char *bytes_pos
= bytes
;
270 char *bytes_roof
= bytes
+ len
;
275 written
+= fprintf(stream
, "=> %d bytes @ %p", len
, bytes
);
277 while (bytes_pos
< bytes_roof
)
279 static char hexdig
[] = "0123456789ABCDEF";
281 *buffer_pos
++ = hexdig
[(*bytes_pos
>> 4) & 0xF];
282 *buffer_pos
++ = hexdig
[ *bytes_pos
& 0xF];
285 (*bytes_pos
> 31 && *bytes_pos
< 127) ?
*bytes_pos
: '.';
287 if (++bytes_pos
== bytes_roof
|| i
== BYTES_PER_LINE
)
289 int padding
= 3 * (BYTES_PER_LINE
- i
);
296 *buffer_pos
++ = '\0';
297 ascii_buffer
[i
] = '\0';
299 written
+= fprintf(stream
, "\n%4d: %s %s",
300 line_start
, buffer
, ascii_buffer
);
304 line_start
+= BYTES_PER_LINE
;
316 * output handler in printf() for chunks
318 static int print_chunk(FILE *stream
, const struct printf_info
*info
,
319 const void *const *args
)
321 chunk_t
*chunk
= *((chunk_t
**)(args
[0]));
323 chunk_t copy
= *chunk
;
328 const void *new_args
[] = {&chunk
->ptr
, &chunk
->len
};
329 return print_bytes(stream
, info
, new_args
);
340 written
+= fprintf(stream
, ":");
342 written
+= fprintf(stream
, "%02x", *copy
.ptr
++);
349 * register printf() handlers
351 static void __attribute__ ((constructor
))print_register()
353 register_printf_function(PRINTF_CHUNK
, print_chunk
, arginfo_ptr
);
354 register_printf_function(PRINTF_BYTES
, print_bytes
, arginfo_ptr_int
);