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