silc_buffer_format reallocates automatically now.
[crypto.git] / lib / silcutil / silcbuffmt.h
1 /*
2
3   silcbuffmt.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2006 Pekka Riikonen
8
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.
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 */
19
20 /****h* silcutil/SILC Buffer Format Interface
21  *
22  * DESCRIPTION
23  *
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.
28  *
29  ***/
30
31 #ifndef SILCBUFFMT_H
32 #define SILCBUFFMT_H
33
34 /* Prototypes */
35
36 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format
37  *
38  * SYNOPSIS
39  *
40  *    int silc_buffer_format(SilcBuffer dst, ...);
41  *
42  * DESCRIPTION
43  *
44  *    Formats a buffer from a variable argument list.  Returns -1 on error
45  *    and the length of the formatted buffer otherwise.  The buffer is
46  *    enlarged automatically during formatting, if it doesn't already have
47  *    enough space.
48  *
49  * EXAMPLE
50  *
51  *    SilcBufferStruct buffer;
52  *
53  *    memset(&buffer, 0, sizeof(buffer));
54  *    ret = silc_buffer_format(&buffer,
55  *                             SILC_STR_INT(intval),
56  *                             SILC_STR_CHAR(charval),
57  *                             SILC_STR_INT(intval),
58  *                             SILC_STR_SHORT(str_len),
59  *                             SILC_STR_UI_XNSTRING(str, str_len),
60  *                             SILC_STR_END);
61  *    if (ret < 0)
62  *      error;
63  *
64  ***/
65 int silc_buffer_format(SilcBuffer dst, ...);
66
67 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sformat
68  *
69  * SYNOPSIS
70  *
71  *    int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...);
72  *
73  * DESCRIPTION
74  *
75  *    Same as silc_buffer_format but uses `stack' to allocate the memory.
76  *    if `stack' is NULL reverts back to silc_buffer_format call.
77  *
78  ***/
79 int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...);
80
81 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format_vp
82  *
83  * SYNOPSIS
84  *
85  *    int silc_buffer_format_vp(SilcBuffer dst, va_list vp);
86  *
87  * DESCRIPTION
88  *
89  *    Formats a buffer from a variable argument list indicated by the `ap'.
90  *    Returns -1 on error and the length of the formatted buffer otherwise.
91  *
92  ***/
93 int silc_buffer_format_vp(SilcBuffer dst, va_list ap);
94
95 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format_vp
96  *
97  * SYNOPSIS
98  *
99  *    int silc_buffer_format_vp(SilcBuffer dst, va_list vp);
100  *
101  * DESCRIPTION
102  *
103  *    Same as silc_buffer_format_vp but uses `stack' to allocate the memory.
104  *    if `stack' is NULL reverts back to silc_buffer_format_vp call.
105  *
106  ***/
107 int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap);
108
109 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat
110  *
111  * SYNOPSIS
112  *
113  *    int silc_buffer_unformat(SilcBuffer src, ...);
114  *
115  * DESCRIPTION
116  *
117  *    Unformats a buffer from a variable argument list.  Returns -1 on error
118  *    and the length of the unformatted buffer otherwise.
119  *
120  * EXAMPLE
121  *
122  *    ret = silc_buffer_unformat(buffer,
123  *                               SILC_STR_INT(&intval),
124  *                               SILC_STR_CHAR(&charval),
125  *                               SILC_STR_OFFSET(4),
126  *                               SILC_STR_UI16_NSTRING_ALLOC(&str, &str_len),
127  *                               SILC_STR_END);
128  *    if (ret < 0)
129  *      error;
130  *
131  ***/
132 int silc_buffer_unformat(SilcBuffer src, ...);
133
134 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat_vp
135  *
136  * SYNOPSIS
137  *
138  *    int silc_buffer_unformat_vp(SilcBuffer src, va_list vp);
139  *
140  * DESCRIPTION
141  *
142  *    Unformats a buffer from a variable argument list indicated by the `ap'.
143  *    Returns -1 on error and the length of the unformatted buffer otherwise.
144  *
145  ***/
146 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap);
147
148 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_strformat
149  *
150  * SYNOPSIS
151  *
152  *   int silc_buffer_strformat(SilcBuffer dst, ...);
153  *
154  * DESCRIPTION
155  *
156  *   Formats a buffer from variable argument list of strings.  Each
157  *   string must be NULL-terminated and the variable argument list must
158  *   be end with SILC_STR_END argument.  This allows that a string in
159  *   the list can be NULL, in which case it is skipped.  This automatically
160  *   allocates the space for the buffer data but `dst' must be already
161  *   allocated by the caller.
162  *
163  * EXAMPLE
164  *
165  *    ret = silc_buffer_strformat(buffer, "foo", "bar", SILC_STR_END);
166  *    if (ret < 0)
167  *      error;
168  *
169  ***/
170 int silc_buffer_strformat(SilcBuffer dst, ...);
171
172 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sstrformat
173  *
174  * SYNOPSIS
175  *
176  *   int silc_buffer_strformat(SilcStack stack, SilcBuffer dst, ...);
177  *
178  * DESCRIPTION
179  *
180  *   Formats a buffer from variable argument list of strings.  Each
181  *   string must be NULL-terminated and the variable argument list must
182  *   be end with SILC_STR_END argument.  This allows that a string in
183  *   the list can be NULL, in which case it is skipped.  This automatically
184  *   allocates the space for the buffer data but `dst' must be already
185  *   allocated by the caller.  This function is equivalent to
186  *   silc_buffer_strformat but allocates memory from `stack'.
187  *
188  ***/
189 int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...);
190
191 /* Macros for expanding parameters into variable function argument list.
192    These are passed to silc_buffer_format and silc_buffer_unformat
193    functions. */
194
195 /* Buffer parameter types.
196
197    _SI_ = signed
198    _UI_ = unsigned
199
200   Any XXX_STRING_ALLOC types will allocate space for the data and
201   memcpy the data to the pointer sent as argument (in unformatting).
202
203   Any XXX_STRING will not allocate or copy any data.  Instead it
204   will set the pointer to the data.  Note that the data pointer
205   returned (in unformatting) must not be freed.
206
207 */
208 typedef enum {
209   SILC_BUFFER_PARAM_SI8_CHAR,
210   SILC_BUFFER_PARAM_UI8_CHAR,
211
212   SILC_BUFFER_PARAM_SI16_SHORT,
213   SILC_BUFFER_PARAM_UI16_SHORT,
214
215   SILC_BUFFER_PARAM_SI32_INT,
216   SILC_BUFFER_PARAM_UI32_INT,
217
218   SILC_BUFFER_PARAM_SI64_INT,
219   SILC_BUFFER_PARAM_UI64_INT,
220
221   SILC_BUFFER_PARAM_UI8_STRING,         /* No copy */
222   SILC_BUFFER_PARAM_UI8_STRING_ALLOC,   /* Alloc + memcpy */
223   SILC_BUFFER_PARAM_UI16_STRING,        /* No copy */
224   SILC_BUFFER_PARAM_UI16_STRING_ALLOC,  /* Alloc + memcpy */
225   SILC_BUFFER_PARAM_UI32_STRING,        /* No copy */
226   SILC_BUFFER_PARAM_UI32_STRING_ALLOC,  /* Alloc + memcpy */
227   SILC_BUFFER_PARAM_UI8_NSTRING,        /* No copy */
228   SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC,  /* Alloc + memcpy */
229   SILC_BUFFER_PARAM_UI16_NSTRING,       /* No copy */
230   SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, /* Alloc + memcpy */
231   SILC_BUFFER_PARAM_UI32_NSTRING,       /* No copy */
232   SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, /* Alloc + memcpy */
233   SILC_BUFFER_PARAM_UI_XNSTRING,        /* No copy */
234   SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC,  /* Alloc + memcpy */
235
236   SILC_BUFFER_PARAM_OFFSET,
237
238   SILC_BUFFER_PARAM_END
239 } SilcBufferParamType;
240
241 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_CHAR
242  *
243  * NAME
244  *
245  *    #define SILC_STR_UI_CHAR() ...
246  *    #define SILC_STR_SI_CHAR() ...
247  *
248  * DESCRIPTION
249  *
250  *    One signed/unsigned character.
251  *
252  *    Formatting:    SILC_STR_SI_CHAR(char)
253  *                   SILC_STR_UI_CHAR(unsigned char)
254  *    Unformatting:  SILC_STR_SI_CHAR(char *)
255  *                   SILC_STR_UI_CHAR(unsigned char *)
256  *
257  ***/
258 #define SILC_STR_SI_CHAR(x) SILC_BUFFER_PARAM_SI8_CHAR, (x)
259 #define SILC_STR_UI_CHAR(x) SILC_BUFFER_PARAM_UI8_CHAR, (x)
260
261 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_SHORT
262  *
263  * NAME
264  *
265  *    #define SILC_STR_UI_SHORT() ...
266  *    #define SILC_STR_SI_SHORT() ...
267  *
268  * DESCRIPTION
269  *
270  *    Signed/SilcUInt16.
271  *
272  *    Formatting:    SILC_STR_SI_SHORT(short)
273  *                   SILC_STR_UI_SHORT(SilcUInt16)
274  *    Unformatting:  SILC_STR_SI_SHORT(short *)
275  *                   SILC_STR_UI_SHORT(SilcUInt16 *)
276  *
277  ***/
278 #define SILC_STR_SI_SHORT(x) SILC_BUFFER_PARAM_SI16_SHORT, (x)
279 #define SILC_STR_UI_SHORT(x) SILC_BUFFER_PARAM_UI16_SHORT, (x)
280
281 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT
282  *
283  * NAME
284  *
285  *    #define SILC_STR_UI_INT() ...
286  *    #define SILC_STR_SI_INT() ...
287  *
288  * DESCRIPTION
289  *
290  *    Signed/SilcUInt32.
291  *
292  *    Formatting:    SILC_STR_SI_INT(int)
293  *                   SILC_STR_UI_INT(SilcUInt32)
294  *    Unformatting:  SILC_STR_SI_INT(int *)
295  *                   SILC_STR_UI_INT(SilcUInt32 *)
296  *
297  ***/
298 #define SILC_STR_SI_INT(x) SILC_BUFFER_PARAM_SI32_INT, (x)
299 #define SILC_STR_UI_INT(x) SILC_BUFFER_PARAM_UI32_INT, (x)
300
301 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT64
302  *
303  * NAME
304  *
305  *    #define SILC_STR_UI_INT64() ...
306  *    #define SILC_STR_SI_INT64() ...
307  *
308  * DESCRIPTION
309  *
310  *    Signed/SilcUInt64.
311  *
312  *     Formatting:    SILC_STR_SI_INT64(int)
313  *                    SILC_STR_UI_INT64(SilcUInt32)
314  *     Unformatting:  SILC_STR_SI_INT64(int *)
315  *                    SILC_STR_UI_INT64(SilcUInt32 *)
316  *
317  ***/
318 #define SILC_STR_SI_INT64(x) SILC_BUFFER_PARAM_SI64_INT, (x)
319 #define SILC_STR_UI_INT64(x) SILC_BUFFER_PARAM_UI64_INT, (x)
320
321 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_STRING
322  *
323  * NAME
324  *
325  *    #define SILC_STR_UI8_STRING() ...
326  *    #define SILC_STR_UI8_STRING_ALLOC() ...
327  *    #define SILC_STR_UI16_STRING() ...
328  *    #define SILC_STR_UI16_STRING_ALLOC() ...
329  *    #define SILC_STR_UI32_STRING() ...
330  *    #define SILC_STR_UI32_STRING_ALLOC() ...
331  *
332  * DESCRIPTION
333  *
334  *    Unsigned NULL terminated string. Note that the string must be
335  *    NULL terminated because strlen() will be used to get the length of
336  *    the string.
337  *
338  *    Formatting:    SILC_STR_UI32_STRING(unsigned char *)
339  *    Unformatting:  SILC_STR_UI32_STRING(unsigned char **)
340  *
341  *    Unformatting procedure will check for length of the string from the
342  *    buffer before trying to get the string out. Thus, one *must* format the
343  *    length as UI_INT or UI_SHORT into the buffer *before* formatting the
344  *    actual string to the buffer, and, in unformatting one must ignore the
345  *    length of the string because unformatting procedure will take it
346  *    automatically.
347  *
348  *    Example:
349  *
350  *    Formatting:    ..., SILC_STR_UI_INT(strlen(string)),
351  *                        SILC_STR_UI32_STRING(string), ...
352  *    Unformatting:  ..., SILC_STR_UI32_STRING(&string), ...
353  *
354  *    I.e., you can ignore the formatted length field in unformatting.
355  *
356  *    UI8, UI16 and UI32 means that the length is considered to be
357  *    either char (8 bits), short (16 bits) or int (32 bits) in
358  *    unformatting.
359  *
360  *    _ALLOC routines automatically allocates memory for the variable sent
361  *    as argument in unformatting.
362  *
363  ***/
364 #define SILC_STR_UI8_STRING(x) SILC_BUFFER_PARAM_UI8_STRING, (x)
365 #define SILC_STR_UI8_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI8_STRING_ALLOC, (x)
366 #define SILC_STR_UI16_STRING(x) SILC_BUFFER_PARAM_UI16_STRING, (x)
367 #define SILC_STR_UI16_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI16_STRING_ALLOC, (x)
368 #define SILC_STR_UI32_STRING(x) SILC_BUFFER_PARAM_UI32_STRING, (x)
369 #define SILC_STR_UI32_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI32_STRING_ALLOC, (x)
370
371 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_NSTRING
372  *
373  * NAME
374  *
375  *    #define SILC_STR_UI8_NSTRING() ...
376  *    #define SILC_STR_UI8_NSTRING_ALLOC() ...
377  *    #define SILC_STR_UI16_NSTRING() ...
378  *    #define SILC_STR_UI16_NSTRING_ALLOC() ...
379  *    #define SILC_STR_UI32_NSTRING() ...
380  *    #define SILC_STR_UI32_NSTRING_ALLOC() ...
381  *
382  * DESCRIPTION
383  *
384  *    Unsigned string. Second argument is the length of the string.
385  *
386  *    Formatting:    SILC_STR_UI32_NSTRING(unsigned char *, SilcUInt32)
387  *    Unformatting:  SILC_STR_UI32_NSTRING(unsigned char **, SilcUInt32 *)
388  *
389  *    Unformatting procedure will check for length of the string from the
390  *    buffer before trying to get the string out. Thus, one *must* format the
391  *    length as UI_INT or UI_SHORT into the buffer *before* formatting the
392  *    actual string to the buffer, and, in unformatting one must ignore the
393  *    length of the string because unformatting procedure will take it
394  *    automatically.
395  *
396  *     Example:
397  *
398  *     Formatting:    ..., SILC_STR_UI_INT(strlen(string)),
399  *                         SILC_STR_UI32_NSTRING(string, strlen(string)), ...
400  *     Unformatting:  ..., SILC_STR_UI32_NSTRING(&string, &len), ...
401  *
402  *    I.e., you can ignore the formatted length field in unformatting. The
403  *    length taken from the buffer is returned to the pointer sent as
404  *    argument (&len in above example).
405  *
406  *    UI8, UI16 and UI32 means that the length is considered to be
407  *    either char (8 bits), short (16 bits) or int (32 bits) in
408  *    unformatting.
409  *
410  *    _ALLOC routines automatically allocates memory for the variable sent
411  *    as argument in unformatting.
412  *
413  ***/
414 #define SILC_STR_UI8_NSTRING(x, l) SILC_BUFFER_PARAM_UI8_NSTRING, (x), (l)
415 #define SILC_STR_UI8_NSTRING_ALLOC(x, l) \
416   SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC, (x), (l)
417 #define SILC_STR_UI16_NSTRING(x, l) SILC_BUFFER_PARAM_UI16_NSTRING, (x), (l)
418 #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \
419   SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, (x), (l)
420 #define SILC_STR_UI32_NSTRING(x, l) SILC_BUFFER_PARAM_UI32_NSTRING, (x), (l)
421 #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \
422   SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, (x), (l)
423
424 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_UI_XNSTRING
425  *
426  * NAME
427  *
428  *    #define SILC_STR_UI_XNSTRING() ...
429  *    #define SILC_STR_UI_XNSTRING_ALLOC() ...
430  *
431  * DESCRIPTION
432  *
433  *    Extended Unsigned string formatting. Second argument is the length of
434  *    the string.
435  *
436  *    Formatting:    SILC_STR_UI_XNSTRING(unsigned char *, SilcUInt32)
437  *    Unformatting:  SILC_STR_UI_XNSTRING(unsigned char **, SilcUInt32)
438  *
439  *    This type can be used to take arbitrary length string from the buffer
440  *    by sending the requested amount of bytes as argument. This differs
441  *    from *_STRING and *_NSTRING so that this doesn't try to find the
442  *    length of the data from the buffer but the length of the data is
443  *    sent as argument. This a handy way to unformat fixed length strings
444  *    from the buffer without having the length of the string formatted
445  *    in the buffer.
446  *
447  *    _ALLOC routines automatically allocates memory for the variable sent
448  *    as argument in unformatting.
449  *
450  ***/
451 #define SILC_STR_UI_XNSTRING(x, l) SILC_BUFFER_PARAM_UI_XNSTRING, (x), (l)
452 #define SILC_STR_UI_XNSTRING_ALLOC(x, l) \
453   SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC, (x), (l)
454
455 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET
456  *
457  * NAME
458  *
459  *    #define SILC_STR_OFFSET() ...
460  *
461  * DESCRIPTION
462  *
463  *    Offset in buffer.  This can be used in formatting and unformatting to
464  *    move the data pointer of the buffer either forwards (positive offset)
465  *    or backwards (negative offset).  It can be used to for example skip
466  *    some types during unformatting.
467  *
468  *    Example:
469  *
470  *    ..., SILC_STR_OFFSET(5), ...
471  *    ..., SILC_STR_OFFSET(-3), ...
472  *
473  *    Moves the data pointer at the point of the offset either forward
474  *    or backward and then moves to the next type.  Multiple SILC_STR_OFFSETs
475  *    can be used in formatting and unformatting at the same time.
476  *
477  ***/
478 #define SILC_STR_OFFSET(x) SILC_BUFFER_PARAM_OFFSET, (x)
479
480 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_END
481  *
482  * NAME
483  *
484  *    #define SILC_STR_END ...
485  *
486  * DESCRIPTION
487  *
488  *    Marks end of the argument list. This must be at the end of the
489  *    argument list or error will occur.
490  *
491  ***/
492 #define SILC_STR_END SILC_BUFFER_PARAM_END
493
494 /****d* silcutil/SilcBufferFormatAPI/SILC_STRFMT_END
495  *
496  * NAME
497  *
498  *    #define SILC_STRFMT_END ...
499  *
500  * DESCRIPTION
501  *
502  *    Marks end of the argument list in silc_buffer_strformat function.
503  *    This must be at the end of the argument list or error will occur.
504  *
505  ***/
506 #define SILC_STRFMT_END (void *)SILC_STR_END
507
508 #endif  /* !SILCBUFFMT_H */