5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2004 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
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.
20 /****h* silcutil/SILC Buffer Format Interface
24 * SILC Buffer Format API provides a few functions for formatting
25 * various different data types into a buffer, and retrieving
26 * various data from buffer into specific data types. It is usefull
27 * to format for example packets and later unformat them.
36 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format
40 * int silc_buffer_format(SilcBuffer dst, ...);
44 * Formats a buffer from a variable argument list. Returns -1 on error
45 * and the length of the formatted buffer otherwise.
49 * ret = silc_buffer_format(buffer,
50 * SILC_STR_INT(intval),
51 * SILC_STR_CHAR(charval),
52 * SILC_STR_INT(intval),
53 * SILC_STR_SHORT(str_len),
54 * SILC_STR_UI_XNSTRING(str, str_len),
60 int silc_buffer_format(SilcBuffer dst, ...);
62 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat
66 * int silc_buffer_unformat(SilcBuffer src, ...);
70 * Unformats a buffer from a variable argument list. Returns -1 on error
71 * and the length of the unformatted buffer otherwise.
75 * ret = silc_buffer_unformat(buffer,
76 * SILC_STR_INT(&intval),
77 * SILC_STR_CHAR(&charval),
78 * SILC_STR_INT(&intval2),
79 * SILC_STR_UI16_NSTRING_ALLOC(&str, &str_len),
85 int silc_buffer_unformat(SilcBuffer src, ...);
87 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format_vp
91 * int silc_buffer_format_vp(SilcBuffer dst, va_list vp);
95 * Formats a buffer from a variable argument list indicated by the `ap'.
96 * Returns -1 on error and the length of the formatted buffer otherwise.
99 int silc_buffer_format_vp(SilcBuffer dst, va_list ap);
101 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat_vp
105 * int silc_buffer_unformat_vp(SilcBuffer src, va_list vp);
109 * Unformats a buffer from a variable argument list indicated by the `ap'.
110 * Returns -1 on error and the length of the unformatted buffer otherwise.
113 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap);
115 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_strformat
119 * int silc_buffer_strformat(SilcBuffer dst, ...);
123 * Formats a buffer from variable argument list of strings. Each
124 * string must be NULL-terminated and the variable argument list must
125 * be end with SILC_STRFMT_END argument. This allows that a string in
126 * the list can be NULL, in which case it is skipped. This automatically
127 * allocates the space for the buffer data but `dst' must be already
128 * allocated by the caller.
132 * ret = silc_buffer_strformat(buffer, "foo", "bar", SILC_STRFMT_END);
137 int silc_buffer_strformat(SilcBuffer dst, ...);
139 /* Macros for expanding parameters into variable function argument list.
140 These are passed to silc_buffer_format and silc_buffer_unformat
143 /* Buffer parameter types.
148 Any XXX_STRING_ALLOC types will allocate space for the data and
149 memcpy the data to the pointer sent as argument (in unformatting).
151 Any XXX_STRING will not allocate or copy any data. Instead it
152 will set the pointer to the data. Note that the data pointer
153 returned (in unformatting) must not be freed.
157 SILC_BUFFER_PARAM_SI8_CHAR,
158 SILC_BUFFER_PARAM_UI8_CHAR,
160 SILC_BUFFER_PARAM_SI16_SHORT,
161 SILC_BUFFER_PARAM_UI16_SHORT,
163 SILC_BUFFER_PARAM_SI32_INT,
164 SILC_BUFFER_PARAM_UI32_INT,
166 SILC_BUFFER_PARAM_SI64_INT,
167 SILC_BUFFER_PARAM_UI64_INT,
169 SILC_BUFFER_PARAM_UI8_STRING, /* No copy */
170 SILC_BUFFER_PARAM_UI8_STRING_ALLOC, /* Alloc + memcpy */
171 SILC_BUFFER_PARAM_UI16_STRING, /* No copy */
172 SILC_BUFFER_PARAM_UI16_STRING_ALLOC, /* Alloc + memcpy */
173 SILC_BUFFER_PARAM_UI32_STRING, /* No copy */
174 SILC_BUFFER_PARAM_UI32_STRING_ALLOC, /* Alloc + memcpy */
175 SILC_BUFFER_PARAM_UI8_NSTRING, /* No copy */
176 SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC, /* Alloc + memcpy */
177 SILC_BUFFER_PARAM_UI16_NSTRING, /* No copy */
178 SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, /* Alloc + memcpy */
179 SILC_BUFFER_PARAM_UI32_NSTRING, /* No copy */
180 SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, /* Alloc + memcpy */
181 SILC_BUFFER_PARAM_UI_XNSTRING, /* No copy */
182 SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC, /* Alloc + memcpy */
184 SILC_BUFFER_PARAM_END
185 } SilcBufferParamType;
187 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_CHAR
191 * #define SILC_STR_UI_CHAR() ...
192 * #define SILC_STR_SI_CHAR() ...
196 * One signed/unsigned character.
198 * Formatting: SILC_STR_SI_CHAR(char)
199 * SILC_STR_UI_CHAR(unsigned char)
200 * Unformatting: SILC_STR_SI_CHAR(char *)
201 * SILC_STR_UI_CHAR(unsigned char *)
204 #define SILC_STR_SI_CHAR(x) SILC_BUFFER_PARAM_SI8_CHAR, (x)
205 #define SILC_STR_UI_CHAR(x) SILC_BUFFER_PARAM_UI8_CHAR, (x)
207 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_SHORT
211 * #define SILC_STR_UI_SHORT() ...
212 * #define SILC_STR_SI_SHORT() ...
218 * Formatting: SILC_STR_SI_SHORT(short)
219 * SILC_STR_UI_SHORT(SilcUInt16)
220 * Unformatting: SILC_STR_SI_SHORT(short *)
221 * SILC_STR_UI_SHORT(SilcUInt16 *)
224 #define SILC_STR_SI_SHORT(x) SILC_BUFFER_PARAM_SI16_SHORT, (x)
225 #define SILC_STR_UI_SHORT(x) SILC_BUFFER_PARAM_UI16_SHORT, (x)
227 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT
231 * #define SILC_STR_UI_INT() ...
232 * #define SILC_STR_SI_INT() ...
238 * Formatting: SILC_STR_SI_INT(int)
239 * SILC_STR_UI_INT(SilcUInt32)
240 * Unformatting: SILC_STR_SI_INT(int *)
241 * SILC_STR_UI_INT(SilcUInt32 *)
244 #define SILC_STR_SI_INT(x) SILC_BUFFER_PARAM_SI32_INT, (x)
245 #define SILC_STR_UI_INT(x) SILC_BUFFER_PARAM_UI32_INT, (x)
247 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT64
251 * #define SILC_STR_UI_INT64() ...
252 * #define SILC_STR_SI_INT64() ...
258 * Formatting: SILC_STR_SI_INT64(int)
259 * SILC_STR_UI_INT64(SilcUInt32)
260 * Unformatting: SILC_STR_SI_INT64(int *)
261 * SILC_STR_UI_INT64(SilcUInt32 *)
264 #define SILC_STR_SI_INT64(x) SILC_BUFFER_PARAM_SI64_INT, (x)
265 #define SILC_STR_UI_INT64(x) SILC_BUFFER_PARAM_UI64_INT, (x)
267 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_STRING
271 * #define SILC_STR_UI8_STRING() ...
272 * #define SILC_STR_UI8_STRING_ALLOC() ...
273 * #define SILC_STR_UI16_STRING() ...
274 * #define SILC_STR_UI16_STRING_ALLOC() ...
275 * #define SILC_STR_UI32_STRING() ...
276 * #define SILC_STR_UI32_STRING_ALLOC() ...
280 * Unsigned NULL terminated string. Note that the string must be
281 * NULL terminated because strlen() will be used to get the length of
284 * Formatting: SILC_STR_UI32_STRING(unsigned char *)
285 * Unformatting: SILC_STR_UI32_STRING(unsigned char **)
287 * Unformatting procedure will check for length of the string from the
288 * buffer before trying to get the string out. Thus, one *must* format the
289 * length as UI_INT or UI_SHORT into the buffer *before* formatting the
290 * actual string to the buffer, and, in unformatting one must ignore the
291 * length of the string because unformatting procedure will take it
296 * Formatting: ..., SILC_STR_UI_INT(strlen(string)),
297 * SILC_STR_UI32_STRING(string), ...
298 * Unformatting: ..., SILC_STR_UI32_STRING(&string), ...
300 * I.e., you can ignore the formatted length field in unformatting.
302 * UI8, UI16 and UI32 means that the length is considered to be
303 * either char (8 bits), short (16 bits) or int (32 bits) in
306 * _ALLOC routines automatically allocates memory for the variable sent
307 * as argument in unformatting.
310 #define SILC_STR_UI8_STRING(x) SILC_BUFFER_PARAM_UI8_STRING, (x)
311 #define SILC_STR_UI8_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI8_STRING_ALLOC, (x)
312 #define SILC_STR_UI16_STRING(x) SILC_BUFFER_PARAM_UI16_STRING, (x)
313 #define SILC_STR_UI16_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI16_STRING_ALLOC, (x)
314 #define SILC_STR_UI32_STRING(x) SILC_BUFFER_PARAM_UI32_STRING, (x)
315 #define SILC_STR_UI32_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI32_STRING_ALLOC, (x)
317 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_NSTRING
321 * #define SILC_STR_UI8_NSTRING() ...
322 * #define SILC_STR_UI8_NSTRING_ALLOC() ...
323 * #define SILC_STR_UI16_NSTRING() ...
324 * #define SILC_STR_UI16_NSTRING_ALLOC() ...
325 * #define SILC_STR_UI32_NSTRING() ...
326 * #define SILC_STR_UI32_NSTRING_ALLOC() ...
330 * Unsigned string. Second argument is the length of the string.
332 * Formatting: SILC_STR_UI32_NSTRING(unsigned char *, SilcUInt32)
333 * Unformatting: SILC_STR_UI32_NSTRING(unsigned char **, SilcUInt32 *)
335 * Unformatting procedure will check for length of the string from the
336 * buffer before trying to get the string out. Thus, one *must* format the
337 * length as UI_INT or UI_SHORT into the buffer *before* formatting the
338 * actual string to the buffer, and, in unformatting one must ignore the
339 * length of the string because unformatting procedure will take it
344 * Formatting: ..., SILC_STR_UI_INT(strlen(string)),
345 * SILC_STR_UI32_NSTRING(string, strlen(string)), ...
346 * Unformatting: ..., SILC_STR_UI32_NSTRING(&string, &len), ...
348 * I.e., you can ignore the formatted length field in unformatting. The
349 * length taken from the buffer is returned to the pointer sent as
350 * argument (&len in above example).
352 * UI8, UI16 and UI32 means that the length is considered to be
353 * either char (8 bits), short (16 bits) or int (32 bits) in
356 * _ALLOC routines automatically allocates memory for the variable sent
357 * as argument in unformatting.
360 #define SILC_STR_UI8_NSTRING(x, l) SILC_BUFFER_PARAM_UI8_NSTRING, (x), (l)
361 #define SILC_STR_UI8_NSTRING_ALLOC(x, l) \
362 SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC, (x), (l)
363 #define SILC_STR_UI16_NSTRING(x, l) SILC_BUFFER_PARAM_UI16_NSTRING, (x), (l)
364 #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \
365 SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, (x), (l)
366 #define SILC_STR_UI32_NSTRING(x, l) SILC_BUFFER_PARAM_UI32_NSTRING, (x), (l)
367 #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \
368 SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, (x), (l)
370 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_UI_XNSTRING
374 * #define SILC_STR_UI_XNSTRING() ...
375 * #define SILC_STR_UI_XNSTRING_ALLOC() ...
379 * Extended Unsigned string formatting. Second argument is the length of
382 * Formatting: SILC_STR_UI_XNSTRING(unsigned char *, SilcUInt32)
383 * Unformatting: SILC_STR_UI_XNSTRING(unsigned char **, SilcUInt32)
385 * This type can be used to take arbitrary length string from the buffer
386 * by sending the requested amount of bytes as argument. This differs
387 * from *_STRING and *_NSTRING so that this doesn't try to find the
388 * length of the data from the buffer but the length of the data is
389 * sent as argument. This a handy way to unformat fixed length strings
390 * from the buffer without having the length of the string formatted
393 * _ALLOC routines automatically allocates memory for the variable sent
394 * as argument in unformatting.
397 #define SILC_STR_UI_XNSTRING(x, l) SILC_BUFFER_PARAM_UI_XNSTRING, (x), (l)
398 #define SILC_STR_UI_XNSTRING_ALLOC(x, l) \
399 SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC, (x), (l)
401 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_END
405 * #define SILC_STR_END ...
409 * Marks end of the argument list. This must be at the end of the
410 * argument list or error will occur.
413 #define SILC_STR_END SILC_BUFFER_PARAM_END
415 /****d* silcutil/SilcBufferFormatAPI/SILC_STRFMT_END
419 * #define SILC_STRFMT_END ...
423 * Marks end of the argument list in silc_buffer_strformat function.
424 * This must be at the end of the argument list or error will occur.
427 #define SILC_STRFMT_END (void *)SILC_STR_END
429 #endif /* !SILCBUFFMT_H */