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