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