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