Added examples to headers.
[crypto.git] / lib / silcutil / silcbuffmt.h
1 /*
2
3   silcbuffmt.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2007 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 functions for formatting different data
25  * types into a buffer and retrieving different data types from a buffer
26  * into specified data types.  It is especially useful to format packets,
27  * protocol payloads and such.
28  *
29  * As the SilcBuffer API is not thread-safe these routines may not be used
30  * in multithreaded environment with a same SilcBuffer context without
31  * concurrency control.
32  *
33  * EXAMPLE
34  *
35  * SilcBufferStruct buffer;
36  *
37  * memset(&buffer, 0, sizeof(buffer));
38  * ret = silc_buffer_format(&buffer,
39  *                          SILC_STR_UI_INT(intval),
40  *                          SILC_STR_CHAR(charval),
41  *                          SILC_STR_UI_INT(intval),
42  *                          SILC_STR_SHORT(str_len),
43  *                          SILC_STR_DATA(str, str_len),
44  *                          SILC_STR_END);
45  * if (ret < 0)
46  *   error;
47  *
48  ***/
49
50 #ifndef SILCBUFFMT_H
51 #define SILCBUFFMT_H
52
53 /****f* silcutil/SilcBufferFormatAPI/SilcBufferFormatFunc
54  *
55  * SYNOPSIS
56  *
57  *    typedef int (*SilcBuffeSFormatFunc)(SilcStack stack,
58  *                                        SilcBuffer buffer,
59  *                                        void *value,
60  *                                        void *context);
61  *
62  * DESCRIPTION
63  *
64  *    Formatting function callback given with SILC_STR_FUNC type.  The
65  *    `buffer' is the buffer being formatted at the location where the
66  *    SILC_STR_FUNC was placed in formatting.  The function should call
67  *    silc_buffer_senlarge before it adds the data to the buffer to make
68  *    sure that it has enough space.  The buffer->head points to the
69  *    start of the buffer and silc_buffer_headlen() gives the length
70  *    of the currently formatted data area.  It is also possible to use
71  *    silc_buffer_sformat with `buffer' which will enlarge the buffer if
72  *    needed.
73  *
74  *    The `value' is the value given to SILC_STR_FUNC that is to be formatted
75  *    into the buffer.  It may be NULL if the function is not formatting
76  *    new data into the buffer.  The `context' is caller specific context.
77  *    Returns -1 on error and length of the formatted value otherwise, and
78  *    0 if nothing was formatted.
79  *
80  ***/
81 typedef int (*SilcBufferFormatFunc)(SilcStack stack, SilcBuffer buffer,
82                                     void *value, void *context);
83
84 /****f* silcutil/SilcBufferFormatAPI/SilcBufferUnformatFunc
85  *
86  * SYNOPSIS
87  *
88  *    typedef int (*SilcBufferUnformatFunc)(SilcBuffer buffer,
89  *                                          void **value,
90  *                                          void *context);
91  *
92  * DESCRIPTION
93  *
94  *    Unformatting function callback given with SILC_STR_FUNC type.  The
95  *    `buffer' is the buffer being unformatted and is at the location where
96  *    the SILC_STR_FUNC was placed in unformatting.  The function should
97  *    check there is enough data in the `buffer' before trying to decode
98  *    from it.
99  *
100  *    If this function unformats anything from the buffer its value is to
101  *    be returned to the `value' pointer.  The implementation should itself
102  *    decide whether the unformatted value is allocated or not.  If this
103  *    function does not unformat anything, nothing is returned to `value'
104  *
105  *    The `context' is caller specific context.  Returns -1 on error, and
106  *    length of the unformatted value otherwise, and 0 if nothing was
107  *    unformatted.
108  *
109  ***/
110 typedef int (*SilcBufferUnformatFunc)(SilcStack stack, SilcBuffer buffer,
111                                       void **value, void *context);
112
113 /* Prototypes */
114
115 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format
116  *
117  * SYNOPSIS
118  *
119  *    int silc_buffer_format(SilcBuffer dst, ...);
120  *
121  * DESCRIPTION
122  *
123  *    Formats a buffer from a variable argument list.  Returns -1 on error
124  *    and the length of the formatted buffer otherwise.  The buffer is
125  *    enlarged automatically during formatting, if it doesn't already have
126  *    enough space.
127  *
128  * EXAMPLE
129  *
130  *    Three basic ways of using silc_buffer_format:
131  *
132  *    // Statically allocated zero size buffer
133  *    SilcBufferStruct buffer;
134  *
135  *    memset(&buffer, 0, sizeof(buffer));
136  *    ret = silc_buffer_format(&buffer,
137  *                             SILC_STR_UI_INT(intval),
138  *                             SILC_STR_CHAR(charval),
139  *                             SILC_STR_UI_INT(intval),
140  *                             SILC_STR_SHORT(str_len),
141  *                             SILC_STR_DATA(str, str_len),
142  *                             SILC_STR_END);
143  *    if (ret < 0)
144  *      error;
145  *
146  *    // Free the allocated data
147  *    silc_buffer_purge(&buffer);
148  *
149  *    // Dynamically allocated zero size buffer
150  *    SilcBuffer buf;
151  *    buf = silc_buffer_alloc(0);
152  *    ret = silc_buffer_format(buf,
153  *                             SILC_STR_UI_INT(intval),
154  *                             SILC_STR_CHAR(charval),
155  *                             SILC_STR_END);
156  *    if (ret < 0)
157  *      error;
158  *
159  *    // Free the allocated buffer
160  *    silc_buffer_free(buf);
161  *
162  *    // Dynamically allocated buffer with enough space
163  *    SilcBuffer buf;
164  *    buf = silc_buffer_alloc(2 + str_len);
165  *    ret = silc_buffer_format(buf,
166  *                             SILC_STR_UI_SHORT(str_len),
167  *                             SILC_STR_DATA(str, str_len),
168  *                             SILC_STR_END);
169  *    if (ret < 0)
170  *      error;
171  *
172  ***/
173 int silc_buffer_format(SilcBuffer dst, ...);
174
175 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sformat
176  *
177  * SYNOPSIS
178  *
179  *    int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...);
180  *
181  * DESCRIPTION
182  *
183  *    Same as silc_buffer_format but uses `stack' to allocate the memory.
184  *    if `stack' is NULL reverts back to silc_buffer_format call.
185  *
186  *    Note that this call consumes the `stack'.  The caller should push the
187  *    stack before calling the function and pop it later.
188  *
189  ***/
190 int silc_buffer_sformat(SilcStack stack, SilcBuffer dst, ...);
191
192 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format_vp
193  *
194  * SYNOPSIS
195  *
196  *    int silc_buffer_format_vp(SilcBuffer dst, va_list vp);
197  *
198  * DESCRIPTION
199  *
200  *    Formats a buffer from a variable argument list indicated by the `ap'.
201  *    Returns -1 on error and the length of the formatted buffer otherwise.
202  *
203  ***/
204 int silc_buffer_format_vp(SilcBuffer dst, va_list ap);
205
206 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sformat_vp
207  *
208  * SYNOPSIS
209  *
210  *    int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list vp);
211  *
212  * DESCRIPTION
213  *
214  *    Same as silc_buffer_format_vp but uses `stack' to allocate the memory.
215  *    if `stack' is NULL reverts back to silc_buffer_format_vp call.
216  *
217  *    Note that this call consumes the `stack'.  The caller should push the
218  *    stack before calling the function and pop it later.
219  *
220  ***/
221 int silc_buffer_sformat_vp(SilcStack stack, SilcBuffer dst, va_list ap);
222
223 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat
224  *
225  * SYNOPSIS
226  *
227  *    int silc_buffer_unformat(SilcBuffer src, ...);
228  *
229  * DESCRIPTION
230  *
231  *    Unformats a buffer from a variable argument list.  Returns -1 on error
232  *    and the length of the unformatted buffer otherwise.
233  *
234  * EXAMPLE
235  *
236  *    ret = silc_buffer_unformat(buffer,
237  *                               SILC_STR_UI_INT(&intval),
238  *                               SILC_STR_CHAR(&charval),
239  *                               SILC_STR_OFFSET(4),
240  *                               SILC_STR_UI16_NSTRING_ALLOC(&str, &str_len),
241  *                               SILC_STR_END);
242  *    if (ret < 0)
243  *      error;
244  *
245  ***/
246 int silc_buffer_unformat(SilcBuffer src, ...);
247
248 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sunformat
249  *
250  * SYNOPSIS
251  *
252  *    int silc_buffer_sunformat(SilcStack stack, SilcBuffer src, ...);
253  *
254  * DESCRIPTION
255  *
256  *    Same as silc_buffer_unformat but uses `stack' to allocate the memory.
257  *    if `stack' is NULL reverts back to silc_buffer_format call.
258  *
259  *    Note that this call consumes the `stack'.  The caller should push the
260  *    stack before calling the function and pop it later.
261  *
262  ***/
263 int silc_buffer_sunformat(SilcStack stack, SilcBuffer src, ...);
264
265 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat_vp
266  *
267  * SYNOPSIS
268  *
269  *    int silc_buffer_unformat_vp(SilcBuffer src, va_list vp);
270  *
271  * DESCRIPTION
272  *
273  *    Unformats a buffer from a variable argument list indicated by the `ap'.
274  *    Returns -1 on error and the length of the unformatted buffer otherwise.
275  *
276  ***/
277 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap);
278
279 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sunformat_vp
280  *
281  * SYNOPSIS
282  *
283  *    int silc_buffer_sunformat_vp(SilcBuffer src, va_list vp);
284  *
285  * DESCRIPTION
286  *
287  *    Same as silc_buffer_unformat_vp but uses `stack' to allocate the
288  *    memory.  if `stack' is NULL reverts back to silc_buffer_format_vp call.
289  *
290  *    Note that this call consumes the `stack'.  The caller should push the
291  *    stack before calling the function and pop it later.
292  *
293  ***/
294 int silc_buffer_sunformat_vp(SilcStack stack, SilcBuffer src, va_list ap);
295
296 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_strformat
297  *
298  * SYNOPSIS
299  *
300  *    int silc_buffer_strformat(SilcBuffer dst, ...);
301  *
302  * DESCRIPTION
303  *
304  *    Formats a buffer from variable argument list of strings.  Each
305  *    string must be NULL-terminated and the variable argument list must
306  *    be end with SILC_STRFMT_END argument.  This allows that a string in
307  *    the list can be NULL, in which case it is skipped.  This automatically
308  *    allocates the space for the buffer data but `dst' must be already
309  *    allocated by the caller.
310  *
311  * EXAMPLE
312  *
313  *    ret = silc_buffer_strformat(buffer, "foo", "bar", SILC_STRFMT_END);
314  *    if (ret < 0)
315  *      error;
316  *
317  ***/
318 int silc_buffer_strformat(SilcBuffer dst, ...);
319
320 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_sstrformat
321  *
322  * SYNOPSIS
323  *
324  *    int silc_buffer_strformat(SilcStack stack, SilcBuffer dst, ...);
325  *
326  * DESCRIPTION
327  *
328  *    Formats a buffer from variable argument list of strings.  Each
329  *    string must be NULL-terminated and the variable argument list must
330  *    be end with SILC_STRFMT_END argument.  This allows that a string in
331  *    the list can be NULL, in which case it is skipped.  This automatically
332  *    allocates the space for the buffer data but `dst' must be already
333  *    allocated by the caller.  This function is equivalent to
334  *    silc_buffer_strformat but allocates memory from `stack'.
335  *
336  *    Note that this call consumes the `stack'.  The caller should push the
337  *    stack before calling the function and pop it later.
338  *
339  ***/
340 int silc_buffer_sstrformat(SilcStack stack, SilcBuffer dst, ...);
341
342 /****d* silcutil/SilcBufferFormatAPI/SilcBufferParamType
343  *
344  * NAME
345  *
346  *    typedef enum { ... } SilcBufferParamType;
347  *
348  * DESCRIPTION
349  *
350  *    Buffer parameter types.  These are not needed when formatting or
351  *    unformatting buffers.  Use the macros such as SILC_STR_UI_CHAR and
352  *    others instead.  These types may be used when describing what a
353  *    buffer looks like, and how it may be formatted and unformatted.
354  *
355  * SOURCE
356  */
357 typedef enum {
358   SILC_PARAM_SI8_CHAR,             /* Signed 8-bit char */
359   SILC_PARAM_UI8_CHAR,             /* Unsigned 8-bit char */
360   SILC_PARAM_SI16_SHORT,           /* Signed 16-bit int */
361   SILC_PARAM_UI16_SHORT,           /* Unsigned 16-bit int */
362   SILC_PARAM_SI32_INT,             /* Signed 32-bit int */
363   SILC_PARAM_UI32_INT,             /* Unsigned 32-bit int */
364   SILC_PARAM_SI64_INT,             /* Signed 64-bit int */
365   SILC_PARAM_UI64_INT,             /* Unsigned 64-bit int */
366   SILC_PARAM_UI8_STRING,           /* String (max len 8-bits)*/
367   SILC_PARAM_UI16_STRING,          /* String (max len 16-bits) */
368   SILC_PARAM_UI32_STRING,          /* String (max len 32-bits) */
369   SILC_PARAM_BUFFER,               /* SilcBuffer */
370
371   /* Internal types */
372   SILC_PARAM_DATA,                 /* Binary data */
373   SILC_PARAM_UI8_NSTRING,          /* String (max len 8-bits) */
374   SILC_PARAM_UI16_NSTRING,         /* String (max len 16-bits) */
375   SILC_PARAM_UI32_NSTRING,         /* String (max len 32-bits) */
376   SILC_PARAM_UI8_STRING_ALLOC,     /* Alloc + memcpy */
377   SILC_PARAM_UI16_STRING_ALLOC,    /* Alloc + memcpy */
378   SILC_PARAM_UI32_STRING_ALLOC,    /* Alloc + memcpy */
379   SILC_PARAM_UI8_NSTRING_ALLOC,    /* Alloc + memcpy */
380   SILC_PARAM_UI16_NSTRING_ALLOC,   /* Alloc + memcpy */
381   SILC_PARAM_UI32_NSTRING_ALLOC,   /* Alloc + memcpy */
382   SILC_PARAM_DATA_ALLOC,           /* Alloc + memcpy */
383   SILC_PARAM_BUFFER_ALLOC,         /* Alloc + memcpy */
384
385   SILC_PARAM_OFFSET,
386   SILC_PARAM_ADVANCE,
387   SILC_PARAM_FUNC,
388
389   SILC_PARAM_UI_XNSTRING,
390   SILC_PARAM_UI_XNSTRING_ALLOC,
391
392   SILC_PARAM_END
393 } SilcBufferParamType;
394 /***/
395
396 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_CHAR
397  *
398  * NAME
399  *
400  *    #define SILC_STR_UI_CHAR() ...
401  *    #define SILC_STR_SI_CHAR() ...
402  *
403  * DESCRIPTION
404  *
405  *    One signed/unsigned character.
406  *
407  *    Formatting:    SILC_STR_SI_CHAR(char)
408  *                   SILC_STR_UI_CHAR(unsigned char)
409  *    Unformatting:  SILC_STR_SI_CHAR(char *)
410  *                   SILC_STR_UI_CHAR(unsigned char *)
411  *
412  ***/
413 #define SILC_STR_SI_CHAR(x) SILC_PARAM_SI8_CHAR, (x)
414 #define SILC_STR_UI_CHAR(x) SILC_PARAM_UI8_CHAR, (x)
415
416 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_SHORT
417  *
418  * NAME
419  *
420  *    #define SILC_STR_UI_SHORT() ...
421  *    #define SILC_STR_SI_SHORT() ...
422  *
423  * DESCRIPTION
424  *
425  *    SilcInt16/SilcUInt16.
426  *
427  *    Formatting:    SILC_STR_SI_SHORT(SilcInt16)
428  *                   SILC_STR_UI_SHORT(SilcUInt16)
429  *    Unformatting:  SILC_STR_SI_SHORT(SilcInt16 *)
430  *                   SILC_STR_UI_SHORT(SilcUInt16 *)
431  *
432  ***/
433 #define SILC_STR_SI_SHORT(x) SILC_PARAM_SI16_SHORT, (x)
434 #define SILC_STR_UI_SHORT(x) SILC_PARAM_UI16_SHORT, (x)
435
436 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT
437  *
438  * NAME
439  *
440  *    #define SILC_STR_UI_INT() ...
441  *    #define SILC_STR_SI_INT() ...
442  *
443  * DESCRIPTION
444  *
445  *    SilcInt32/SilcUInt32.
446  *
447  *    Formatting:    SILC_STR_SI_INT(SilcInt32)
448  *                   SILC_STR_UI_INT(SilcUInt32)
449  *    Unformatting:  SILC_STR_SI_INT(SilcInt32 *)
450  *                   SILC_STR_UI_INT(SilcUInt32 *)
451  *
452  ***/
453 #define SILC_STR_SI_INT(x) SILC_PARAM_SI32_INT, (x)
454 #define SILC_STR_UI_INT(x) SILC_PARAM_UI32_INT, (x)
455
456 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_INT64
457  *
458  * NAME
459  *
460  *    #define SILC_STR_UI_INT64() ...
461  *    #define SILC_STR_SI_INT64() ...
462  *
463  * DESCRIPTION
464  *
465  *    SilcInt64/SilcUInt64.
466  *
467  *     Formatting:    SILC_STR_SI_INT64(SilcInt64)
468  *                    SILC_STR_UI_INT64(SilcUInt64)
469  *     Unformatting:  SILC_STR_SI_INT64(SilcInt64 *)
470  *                    SILC_STR_UI_INT64(SilcUInt64 *)
471  *
472  ***/
473 #define SILC_STR_SI_INT64(x) SILC_PARAM_SI64_INT, (x)
474 #define SILC_STR_UI_INT64(x) SILC_PARAM_UI64_INT, (x)
475
476 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_STRING
477  *
478  * NAME
479  *
480  *    #define SILC_STR_UI8_STRING() ...
481  *    #define SILC_STR_UI8_STRING_ALLOC() ...
482  *    #define SILC_STR_UI16_STRING() ...
483  *    #define SILC_STR_UI16_STRING_ALLOC() ...
484  *    #define SILC_STR_UI32_STRING() ...
485  *    #define SILC_STR_UI32_STRING_ALLOC() ...
486  *
487  * DESCRIPTION
488  *
489  *    Unsigned NULL terminated string. Note that the string must be
490  *    NULL terminated because strlen() will be used to get the length of
491  *    the string.
492  *
493  *    Formatting:    SILC_STR_UI32_STRING(unsigned char *)
494  *    Unformatting:  SILC_STR_UI32_STRING(unsigned char **)
495  *
496  *    Unformatting procedure will check for length of the string from the
497  *    buffer before trying to get the string out. Thus, one *must* format the
498  *    length as UI_INT or UI_SHORT into the buffer *before* formatting the
499  *    actual string to the buffer, and, in unformatting one must ignore the
500  *    length of the string because unformatting procedure will take it
501  *    automatically.
502  *
503  *    Example:
504  *
505  *    Formatting:    ..., SILC_STR_UI_INT(strlen(string)),
506  *                        SILC_STR_UI32_STRING(string), ...
507  *    Unformatting:  ..., SILC_STR_UI32_STRING(&string), ...
508  *
509  *    I.e., you can ignore the formatted length field in unformatting.
510  *
511  *    UI8, UI16 and UI32 means that the length is considered to be
512  *    either char (8 bits), short (16 bits) or int (32 bits) in
513  *    unformatting.
514  *
515  *    _ALLOC routines automatically allocates memory for the variable sent
516  *    as argument in unformatting.
517  *
518  ***/
519 #define SILC_STR_UI8_STRING(x) SILC_PARAM_UI8_STRING, (x)
520 #define SILC_STR_UI8_STRING_ALLOC(x) SILC_PARAM_UI8_STRING_ALLOC, (x)
521 #define SILC_STR_UI16_STRING(x) SILC_PARAM_UI16_STRING, (x)
522 #define SILC_STR_UI16_STRING_ALLOC(x) SILC_PARAM_UI16_STRING_ALLOC, (x)
523 #define SILC_STR_UI32_STRING(x) SILC_PARAM_UI32_STRING, (x)
524 #define SILC_STR_UI32_STRING_ALLOC(x) SILC_PARAM_UI32_STRING_ALLOC, (x)
525
526 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_*_NSTRING
527  *
528  * NAME
529  *
530  *    #define SILC_STR_UI8_NSTRING() ...
531  *    #define SILC_STR_UI8_NSTRING_ALLOC() ...
532  *    #define SILC_STR_UI16_NSTRING() ...
533  *    #define SILC_STR_UI16_NSTRING_ALLOC() ...
534  *    #define SILC_STR_UI32_NSTRING() ...
535  *    #define SILC_STR_UI32_NSTRING_ALLOC() ...
536  *
537  * DESCRIPTION
538  *
539  *    Unsigned string. Second argument is the length of the string.
540  *
541  *    Formatting:    SILC_STR_UI32_NSTRING(unsigned char *, SilcUInt32)
542  *    Unformatting:  SILC_STR_UI32_NSTRING(unsigned char **, SilcUInt32 *)
543  *
544  *    Unformatting procedure will check for length of the string from the
545  *    buffer before trying to get the string out. Thus, one *must* format the
546  *    length as UI_INT or UI_SHORT into the buffer *before* formatting the
547  *    actual string to the buffer, and, in unformatting one must ignore the
548  *    length of the string because unformatting procedure will take it
549  *    automatically.
550  *
551  *     Example:
552  *
553  *     Formatting:    ..., SILC_STR_UI_INT(strlen(string)),
554  *                         SILC_STR_UI32_NSTRING(string, strlen(string)), ...
555  *     Unformatting:  ..., SILC_STR_UI32_NSTRING(&string, &len), ...
556  *
557  *    I.e., you can ignore the formatted length field in unformatting. The
558  *    length taken from the buffer is returned to the pointer sent as
559  *    argument (&len in above example).
560  *
561  *    UI8, UI16 and UI32 means that the length is considered to be
562  *    either char (8 bits), short (16 bits) or int (32 bits) in
563  *    unformatting.
564  *
565  *    _ALLOC routines automatically allocates memory for the variable sent
566  *    as argument in unformatting.
567  *
568  ***/
569 #define SILC_STR_UI8_NSTRING(x, l) SILC_PARAM_UI8_NSTRING, (x), (l)
570 #define SILC_STR_UI8_NSTRING_ALLOC(x, l) \
571   SILC_PARAM_UI8_NSTRING_ALLOC, (x), (l)
572 #define SILC_STR_UI16_NSTRING(x, l) SILC_PARAM_UI16_NSTRING, (x), (l)
573 #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \
574   SILC_PARAM_UI16_NSTRING_ALLOC, (x), (l)
575 #define SILC_STR_UI32_NSTRING(x, l) SILC_PARAM_UI32_NSTRING, (x), (l)
576 #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \
577   SILC_PARAM_UI32_NSTRING_ALLOC, (x), (l)
578
579 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_DATA
580  *
581  * NAME
582  *
583  *    #define SILC_STR_DATA() ...
584  *    #define SILC_STR_DATA_ALLOC() ...
585  *
586  * DESCRIPTION
587  *
588  *    Binary data formatting.  Second argument is the length of the data.
589  *
590  *    Formatting:    SILC_STR_DATA(unsigned char *, SilcUInt32)
591  *    Unformatting:  SILC_STR_DATA(unsigned char **, SilcUInt32)
592  *
593  *    This type can be used to take arbitrary size data block from the buffer
594  *    by sending the requested amount of bytes as argument.
595  *
596  *    _ALLOC routines automatically allocates memory for the variable sent
597  *    as argument in unformatting.
598  *
599  ***/
600 #define SILC_STR_DATA(x, l) SILC_PARAM_DATA, (x), (l)
601 #define SILC_STR_DATA_ALLOC(x, l) SILC_PARAM_DATA_ALLOC, (x), (l)
602
603 /* Deprecated */
604 #define SILC_STR_UI_XNSTRING(x, l) SILC_PARAM_UI_XNSTRING, (x), (l)
605 #define SILC_STR_UI_XNSTRING_ALLOC(x, l) SILC_PARAM_UI_XNSTRING_ALLOC, (x), (l)
606
607 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_BUFFER
608  *
609  * NAME
610  *
611  *    #define SILC_STR_BUFFER() ...
612  *    #define SILC_STR_BUFFER_ALLOC() ...
613  *
614  * DESCRIPTION
615  *
616  *    SilcBuffer formatting.
617  *
618  *    Formatting:    SILC_STR_BUFFER(SilcBuffer)
619  *    Unformatting:  SILC_STR_BUFFER(SilcBuffer)
620  *
621  *    This type can be used to format and unformat SilcBuffer.  Note that, the
622  *    length of the buffer will be automatically encoded into the buffer as
623  *    a 32-bit integer.  In unformatting the SilcBuffer context must be
624  *    pre-allocated.
625  *
626  *    _ALLOC routines automatically allocates memory inside SilcBuffer in
627  *    unformatting.
628  *
629  ***/
630 #define SILC_STR_BUFFER(x) SILC_PARAM_BUFFER, (x)
631 #define SILC_STR_BUFFER_ALLOC(x) SILC_PARAM_BUFFER_ALLOC, (x)
632
633 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_FUNC
634  *
635  * NAME
636  *
637  *    #define SILC_STR_FUNC() ...
638  *
639  * DESCRIPTION
640  *
641  *    SilcBuffer formatting.
642  *
643  *    Formatting:    SILC_STR_FUNC(function, void *value, void *context)
644  *    Unformatting:  SILC_STR_FUNC(function, void **value, void *context)
645  *
646  *    This type can be used to call the `function' of the type
647  *    SilcBufferFormatFunc or SilcBufferUnformatFunc to encode or decode
648  *    the `value'.  In encoding the `value' will be passed to the `function'
649  *    and can be encoded into the buffer.  The buffer will be passed as
650  *    well to the `function' at the location where SILC_STR_FUNC is placed
651  *    in formatting.  The `context' delivers caller specific context to
652  *    the `function'
653  *
654  *    In unformatting the `function' will decode the encoded type and
655  *    return it to `value' pointer.  The decoding function should decide
656  *    itself whether to allocate or not the decoded value.
657  *
658  *    The `function' does not have to encode anything and passing `value'
659  *    as NULL is allowed.  The `function' could for example modify the
660  *    existing buffer.
661  *
662  * EXAMPLE
663  *
664  *    // Encode payload, encrypt and compute MAC.
665  *    silc_buffer_format(buf,
666  *                       SILC_STR_FUNC(foo_encode_id, id, ctx),
667  *                       SILC_STR_UI_SHORT(len),
668  *                       SILC_STR_DATA(data, len),
669  *                       SILC_STR_FUNC(foo_buf_encrypt, NULL, key),
670  *                       SILC_STR_FUNC(foo_buf_hmac, NULL, hmac),
671  *                       SILC_STR_DATA(iv, iv_len);
672  *                       SILC_STR_END);
673  *
674  *    // Check MAC, decrypt and decode payload
675  *    silc_buffer_unformat(buf,
676  *                         SILC_STR_FUNC(foo_buf_hmac, NULL, hmac),
677  *                         SILC_STR_FUNC(foo_buf_decrypt, NULL, key),
678  *                         SILC_STR_FUNC(foo_decode_id, &id, ctx),
679  *                         SILC_STR_UI_SHORT(&len),
680  *                         SILC_STR_END);
681  *
682  ***/
683 #define SILC_STR_FUNC(func, val, context) SILC_PARAM_FUNC, \
684     func, (val), (context)
685
686 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_OFFSET
687  *
688  * NAME
689  *
690  *    #define SILC_STR_OFFSET() ...
691  *
692  * DESCRIPTION
693  *
694  *    Offset in buffer.  This can be used in formatting and unformatting to
695  *    move the data pointer of the buffer either forwards (positive offset)
696  *    or backwards (negative offset).  It can be used to for example skip
697  *    some types during unformatting.
698  *
699  *    Example:
700  *
701  *    ..., SILC_STR_OFFSET(5), ...
702  *    ..., SILC_STR_OFFSET(-3), ...
703  *
704  *    Moves the data pointer at the point of the offset either forward
705  *    or backward and then moves to the next type.  Multiple SILC_STR_OFFSETs
706  *    can be used in formatting and unformatting at the same time.
707  *
708  ***/
709 #define SILC_STR_OFFSET(x) SILC_PARAM_OFFSET, (x)
710
711 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_ADVANCE
712  *
713  * NAME
714  *
715  *    #define SILC_STR_ADVANCE ...
716  *
717  * DESCRIPTION
718  *
719  *    Advance the buffer to the end of the data after the formatting is
720  *    done.  In normal operation when the formatted data is written the
721  *    buffer is located at the start of the data.  With SILC_STR_ADVANCE
722  *    the buffer will be located at the end of the data.  This makes it
723  *    easy to add new data immediately after the previously added data.
724  *    The SILC_STR_ADVANCE may also be used in unformatting.
725  *
726  * EXAMPLE
727  *
728  *    do {
729  *      len = read(fd, buf, sizeof(buf));
730  *      if (len > 0)
731  *        // Add read data to the buffer
732  *        silc_buffer_format(buffer,
733  *                           SILC_STR_ADVANCE,
734  *                           SILC_STR_DATA(buf, len),
735  *                           SILC_STR_END);
736  *    } while (len > 0);
737  *
738  *    // Move to beginning of buffer
739  *    silc_buffer_start(buffer);
740  *
741  ***/
742 #define SILC_STR_ADVANCE SILC_PARAM_ADVANCE
743
744 /****d* silcutil/SilcBufferFormatAPI/SILC_STR_END
745  *
746  * NAME
747  *
748  *    #define SILC_STR_END ...
749  *
750  * DESCRIPTION
751  *
752  *    Marks end of the argument list. This must be at the end of the
753  *    argument list or error will occur.
754  *
755  ***/
756 #define SILC_STR_END SILC_PARAM_END
757
758 /****d* silcutil/SilcBufferFormatAPI/SILC_STRFMT_END
759  *
760  * NAME
761  *
762  *    #define SILC_STRFMT_END ...
763  *
764  * DESCRIPTION
765  *
766  *    Marks end of the argument list in silc_buffer_strformat function.
767  *    This must be at the end of the argument list or error will occur.
768  *
769  ***/
770 #define SILC_STRFMT_END (void *)SILC_STR_END
771
772 #endif  /* !SILCBUFFMT_H */