613a093dc331412b3655700fc75d7b4326c570ce
[strongswan.git] / src / libstrongswan / chunk.h
1 /*
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
6 *
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>.
11 *
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
15 * for more details.
16 *
17 * $Id$
18 */
19
20 /**
21 * @defgroup chunk chunk
22 * @{ @ingroup libstrongswan
23 */
24
25 #ifndef CHUNK_H_
26 #define CHUNK_H_
27
28 #include <string.h>
29 #include <stdarg.h>
30 #include <sys/types.h>
31
32 typedef struct chunk_t chunk_t;
33
34 /**
35 * General purpose pointer/length abstraction.
36 */
37 struct chunk_t {
38 /** Pointer to start of data */
39 u_char *ptr;
40 /** Length of data in bytes */
41 size_t len;
42 };
43
44 #include <library.h>
45
46 /**
47 * A { NULL, 0 }-chunk handy for initialization.
48 */
49 extern chunk_t chunk_empty;
50
51 /**
52 * Create a new chunk pointing to "ptr" with length "len"
53 */
54 static inline chunk_t chunk_create(u_char *ptr, size_t len)
55 {
56 chunk_t chunk = {ptr, len};
57 return chunk;
58 }
59
60 /**
61 * Create a clone of a chunk pointing to "ptr"
62 */
63 chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk);
64
65 /**
66 * Calculate length of multiple chunks
67 */
68 size_t chunk_length(const char *mode, ...);
69
70 /**
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 "..."
74 */
75 chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...);
76
77 /**
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);
84 */
85 void chunk_split(chunk_t chunk, const char *mode, ...);
86
87 /**
88 * Write the binary contents of a chunk_t to a file
89 */
90 bool chunk_write(chunk_t chunk, char *path, mode_t mask, bool force);
91
92 /**
93 * Convert a chunk of data to hex encoding.
94 *
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).
97 *
98 * @param chunk data to convert
99 * @param buff buffer to write to, NULL to malloc
100 * @param uppercase TRUE to use uppercase letters
101 * @return chunk of encoded data
102 */
103 chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase);
104
105 /**
106 * Convert a hex encoded in a binary chunk.
107 *
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.
110 *
111 * @param hex hex encoded input data
112 * @param buf buffer to write decoded data, NULL to malloc
113 * @return converted data
114 */
115 chunk_t chunk_from_hex(chunk_t hex, char *buf);
116
117 /**
118 * Convert a chunk of data to its base64 encoding.
119 *
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).
122 *
123 * @param chunk data to convert
124 * @param buff buffer to write to, NULL to malloc
125 * @return chunk of encoded data
126 */
127 chunk_t chunk_to_base64(chunk_t chunk, char *buf);
128
129 /**
130 * Convert a base64 in a binary chunk.
131 *
132 * If buf is supplied, it must hold at least (base64.len / 4 * 3).
133 *
134 * @param base64 base64 encoded input data
135 * @param buf buffer to write decoded data, NULL to malloc
136 * @return converted data
137 */
138 chunk_t chunk_from_base64(chunk_t base64, char *buf);
139
140 /**
141 * Free contents of a chunk
142 */
143 static inline void chunk_free(chunk_t *chunk)
144 {
145 free(chunk->ptr);
146 *chunk = chunk_empty;
147 }
148
149 /**
150 * Overwrite the contents of a chunk and free it
151 */
152 static inline void chunk_clear(chunk_t *chunk)
153 {
154 if (chunk->ptr)
155 {
156 memset(chunk->ptr, 0, chunk->len);
157 chunk_free(chunk);
158 }
159 }
160
161 /**
162 * Initialize a chunk to point to buffer inspectable by sizeof()
163 */
164 #define chunk_from_buf(str) { str, sizeof(str) }
165
166 /**
167 * Initialize a chunk to point to a thing
168 */
169 #define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
170
171 /**
172 * Allocate a chunk on the heap
173 */
174 #define chunk_alloc(bytes) chunk_create(malloc(bytes), bytes)
175
176 /**
177 * Allocate a chunk on the stack
178 */
179 #define chunk_alloca(bytes) chunk_create(alloca(bytes), bytes)
180
181 /**
182 * Clone a chunk on heap
183 */
184 #define chunk_clone(chunk) chunk_create_clone((chunk).len ? malloc(chunk.len) : NULL, chunk)
185
186 /**
187 * Clone a chunk on stack
188 */
189 #define chunk_clonea(chunk) chunk_create_clone(alloca(chunk.len), chunk)
190
191 /**
192 * Concatenate chunks into a chunk on heap
193 */
194 #define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
195
196 /**
197 * Concatenate chunks into a chunk on stack
198 */
199 #define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
200
201 /**
202 * Skip n bytes in chunk (forward pointer, shorten length)
203 */
204 static inline chunk_t chunk_skip(chunk_t chunk, size_t bytes)
205 {
206 if (chunk.len > bytes)
207 {
208 chunk.ptr += bytes;
209 chunk.len -= bytes;
210 return chunk;
211 }
212 return chunk_empty;
213 }
214
215 /**
216 * Compare two chunks, returns zero if a equals b
217 * or negative/positive if a is small/greater than b
218 */
219 int chunk_compare(chunk_t a, chunk_t b);
220
221 /**
222 * Compare two chunks for equality,
223 * NULL chunks are never equal.
224 */
225 static inline bool chunk_equals(chunk_t a, chunk_t b)
226 {
227 return a.ptr != NULL && b.ptr != NULL &&
228 a.len == b.len && memeq(a.ptr, b.ptr, a.len);
229 }
230
231 /**
232 * Computes a 32 bit hash of the given chunk.
233 * Note: This hash is only intended for hash tables not for cryptographic purposes.
234 */
235 u_int32_t chunk_hash(chunk_t chunk);
236
237 /**
238 * Incremental version of chunk_hash. Use this to hash two or more chunks.
239 */
240 u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash);
241
242 /**
243 * printf hook function for chunk_t.
244 *
245 * Arguments are:
246 * chunk_t *chunk
247 * Use #-modifier to print a compact version
248 */
249 int chunk_printf_hook(char *dst, size_t len, printf_hook_spec_t *spec,
250 const void *const *args);
251
252 #endif /* CHUNK_H_ @}*/