2 * Copyright (C) 2008-2009 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * @defgroup chunk chunk
22 * @{ @ingroup libstrongswan
30 #include <sys/types.h>
32 typedef struct chunk_t chunk_t
;
35 * General purpose pointer/length abstraction.
38 /** Pointer to start of data */
40 /** Length of data in bytes */
47 * A { NULL, 0 }-chunk handy for initialization.
49 extern chunk_t chunk_empty
;
52 * Create a new chunk pointing to "ptr" with length "len"
54 static inline chunk_t
chunk_create(u_char
*ptr
, size_t len
)
56 chunk_t chunk
= {ptr
, len
};
61 * Create a clone of a chunk pointing to "ptr"
63 chunk_t
chunk_create_clone(u_char
*ptr
, chunk_t chunk
);
66 * Calculate length of multiple chunks
68 size_t chunk_length(const char *mode
, ...);
71 * Concatenate chunks into a chunk pointing to "ptr",
72 * "mode" is a string of "c" (copy) and "m" (move), which says
73 * how to handle the chunks in "..."
75 chunk_t
chunk_create_cat(u_char
*ptr
, const char* mode
, ...);
78 * Split up a chunk into parts, "mode" is a string of "a" (alloc),
79 * "c" (copy) and "m" (move). Each letter say for the corresponding chunk if
80 * it should get allocated on heap, copied into existing chunk, or the chunk
81 * should point into "chunk". The length of each part is an argument before
82 * each target chunk. E.g.:
83 * chunk_split(chunk, "mcac", 3, &a, 7, &b, 5, &c, d.len, &d);
85 void chunk_split(chunk_t chunk
, const char *mode
, ...);
88 * Write the binary contents of a chunk_t to a file
90 bool chunk_write(chunk_t chunk
, char *path
, mode_t mask
, bool force
);
93 * Convert a chunk of data to hex encoding.
95 * The resulting string is '\\0' terminated, but the chunk does not include
96 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1).
98 * @param chunk data to convert
99 * @param buf buffer to write to, NULL to malloc
100 * @param uppercase TRUE to use uppercase letters
101 * @return chunk of encoded data
103 chunk_t
chunk_to_hex(chunk_t chunk
, char *buf
, bool uppercase
);
106 * Convert a hex encoded in a binary chunk.
108 * If buf is supplied, it must hold at least (hex.len / 2) + (hex.len % 2)
109 * bytes. It is filled by the right to give correct values for short inputs.
111 * @param hex hex encoded input data
112 * @param buf buffer to write decoded data, NULL to malloc
113 * @return converted data
115 chunk_t
chunk_from_hex(chunk_t hex
, char *buf
);
118 * Convert a chunk of data to its base64 encoding.
120 * The resulting string is '\\0' terminated, but the chunk does not include
121 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1).
123 * @param chunk data to convert
124 * @param buf buffer to write to, NULL to malloc
125 * @return chunk of encoded data
127 chunk_t
chunk_to_base64(chunk_t chunk
, char *buf
);
130 * Convert a base64 in a binary chunk.
132 * If buf is supplied, it must hold at least (base64.len / 4 * 3).
134 * @param base64 base64 encoded input data
135 * @param buf buffer to write decoded data, NULL to malloc
136 * @return converted data
138 chunk_t
chunk_from_base64(chunk_t base64
, char *buf
);
141 * Free contents of a chunk
143 static inline void chunk_free(chunk_t
*chunk
)
146 *chunk
= chunk_empty
;
150 * Overwrite the contents of a chunk and free it
152 static inline void chunk_clear(chunk_t
*chunk
)
156 memset(chunk
->ptr
, 0, chunk
->len
);
162 * Initialize a chunk to point to buffer inspectable by sizeof()
164 #define chunk_from_buf(str) { str, sizeof(str) }
167 * Initialize a chunk to point to a thing
169 #define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
172 * Allocate a chunk on the heap
174 #define chunk_alloc(bytes) chunk_create(malloc(bytes), bytes)
177 * Allocate a chunk on the stack
179 #define chunk_alloca(bytes) chunk_create(alloca(bytes), bytes)
182 * Clone a chunk on heap
184 #define chunk_clone(chunk) chunk_create_clone((chunk).len ? malloc((chunk).len) : NULL, chunk)
187 * Clone a chunk on stack
189 #define chunk_clonea(chunk) chunk_create_clone(alloca((chunk).len), chunk)
192 * Concatenate chunks into a chunk on heap
194 #define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
197 * Concatenate chunks into a chunk on stack
199 #define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
202 * Skip n bytes in chunk (forward pointer, shorten length)
204 static inline chunk_t
chunk_skip(chunk_t chunk
, size_t bytes
)
206 if (chunk
.len
> bytes
)
216 * Compare two chunks, returns zero if a equals b
217 * or negative/positive if a is small/greater than b
219 int chunk_compare(chunk_t a
, chunk_t b
);
222 * Compare two chunks for equality,
223 * NULL chunks are never equal.
225 static inline bool chunk_equals(chunk_t a
, chunk_t b
)
227 return a
.ptr
!= NULL
&& b
.ptr
!= NULL
&&
228 a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
232 * Computes a 32 bit hash of the given chunk.
233 * Note: This hash is only intended for hash tables not for cryptographic purposes.
235 u_int32_t
chunk_hash(chunk_t chunk
);
238 * Incremental version of chunk_hash. Use this to hash two or more chunks.
240 u_int32_t
chunk_hash_inc(chunk_t chunk
, u_int32_t hash
);
243 * printf hook function for chunk_t.
247 * Use #-modifier to print a compact version
249 int chunk_printf_hook(char *dst
, size_t len
, printf_hook_spec_t
*spec
,
250 const void *const *args
);
252 #endif /** CHUNK_H_ @}*/