1 /*
2 
3   silcbuffmt.h
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 1997 - 2007 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
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 */
811