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