51cb5d2c2b2c255a0818955c39847e8430e1d55b
[silc.git] / lib / silcutil / silcbuffmt.h
1 /*
2
3   silcbuffmt.h
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 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; either version 2 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20
21 /****h* silcutil/SILC Buffer Format Interface
22  *
23  * DESCRIPTION
24  *
25  *    SILC Buffer Format API provides a few functions for formatting
26  *    various different data types into a buffer, and retrieving
27  *    various data from buffer into specific data types.  It is usefull
28  *    to format for example packets and later unformat them.
29  *
30  ***/
31
32 #ifndef SILCBUFFMT_H
33 #define SILCBUFFMT_H
34
35 /* Buffer parameter types.
36
37    _SI_ = signed
38    _UI_ = unsigned
39
40   Any XXX_STRING_ALLOC types will allocate space for the data and
41   memcpy the data to the pointer sent as argument (in unformatting).
42
43   Any XXX_STRING will not allocate or copy any data.  Instead it
44   will set the pointer to the data.  Note that the data pointer
45   returned (in unformatting) must not be freed.
46
47 */
48 typedef enum {
49   SILC_BUFFER_PARAM_SI8_CHAR,
50   SILC_BUFFER_PARAM_UI8_CHAR,
51
52   SILC_BUFFER_PARAM_SI16_SHORT,
53   SILC_BUFFER_PARAM_UI16_SHORT,
54
55   SILC_BUFFER_PARAM_SI32_INT,
56   SILC_BUFFER_PARAM_UI32_INT,
57
58   SILC_BUFFER_PARAM_SI64_INT,
59   SILC_BUFFER_PARAM_UI64_INT,
60
61   SILC_BUFFER_PARAM_UI8_STRING,         /* No copy */
62   SILC_BUFFER_PARAM_UI8_STRING_ALLOC,   /* Alloc + memcpy */
63   SILC_BUFFER_PARAM_UI16_STRING,        /* No copy */
64   SILC_BUFFER_PARAM_UI16_STRING_ALLOC,  /* Alloc + memcpy */
65   SILC_BUFFER_PARAM_UI32_STRING,        /* No copy */
66   SILC_BUFFER_PARAM_UI32_STRING_ALLOC,  /* Alloc + memcpy */
67   SILC_BUFFER_PARAM_UI8_NSTRING,        /* No copy */
68   SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC,  /* Alloc + memcpy */
69   SILC_BUFFER_PARAM_UI16_NSTRING,       /* No copy */
70   SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, /* Alloc + memcpy */
71   SILC_BUFFER_PARAM_UI32_NSTRING,       /* No copy */
72   SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, /* Alloc + memcpy */
73   SILC_BUFFER_PARAM_UI_XNSTRING,        /* No copy */
74   SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC,  /* Alloc + memcpy */
75
76   SILC_BUFFER_PARAM_END
77 } SilcBufferParamType;
78
79 /* Macros for expanding parameters into variable function argument list.
80    These are passed to silc_buffer_format and silc_buffer_unformat
81    functions. */
82
83 /* One signed/unsigned character.
84
85    Formatting:    SILC_STR_SI_CHAR(char)
86                   SILC_STR_UI_CHAR(unsigned char)
87    Unformatting:  SILC_STR_SI_CHAR(char *)
88                   SILC_STR_UI_CHAR(unsigned char *)
89
90 */
91 #define SILC_STR_SI_CHAR(x) SILC_BUFFER_PARAM_SI8_CHAR, (x)
92 #define SILC_STR_UI_CHAR(x) SILC_BUFFER_PARAM_UI8_CHAR, (x)
93
94 /* Signed/SilcUInt16.
95
96    Formatting:    SILC_STR_SI_SHORT(short)
97                   SILC_STR_UI_SHORT(SilcUInt16)
98    Unformatting:  SILC_STR_SI_SHORT(short *)
99                   SILC_STR_UI_SHORT(SilcUInt16 *)
100
101 */
102 #define SILC_STR_SI_SHORT(x) SILC_BUFFER_PARAM_SI16_SHORT, (x)
103 #define SILC_STR_UI_SHORT(x) SILC_BUFFER_PARAM_UI16_SHORT, (x)
104
105 /* Signed/SilcUInt32.
106
107    Formatting:    SILC_STR_SI_INT(int)
108                   SILC_STR_UI_INT(SilcUInt32)
109    Unformatting:  SILC_STR_SI_INT(int *)
110                   SILC_STR_UI_INT(SilcUInt32 *)
111
112 */
113 #define SILC_STR_SI_INT(x) SILC_BUFFER_PARAM_SI32_INT, (x)
114 #define SILC_STR_UI_INT(x) SILC_BUFFER_PARAM_UI32_INT, (x)
115
116 /* Signed/SilcUInt64.
117
118    Formatting:    SILC_STR_SI_INT64(int)
119                   SILC_STR_UI_INT64(SilcUInt32)
120    Unformatting:  SILC_STR_SI_INT64(int *)
121                   SILC_STR_UI_INT64(SilcUInt32 *)
122
123 */
124 #define SILC_STR_SI_INT64(x) SILC_BUFFER_PARAM_SI64_INT, (x)
125 #define SILC_STR_UI_INT64(x) SILC_BUFFER_PARAM_UI64_INT, (x)
126
127 /* Unsigned NULL terminated string. Note that the string must be
128    NULL terminated because strlen() will be used to get the length of
129    the string.
130
131    Formatting:    SILC_STR_UI32_STRING(unsigned char *)
132    Unformatting:  SILC_STR_UI32_STRING(unsigned char **)
133
134    Unformatting procedure will check for length of the string from the
135    buffer before trying to get the string out. Thus, one *must* format the
136    length as UI_INT or UI_SHORT into the buffer *before* formatting the
137    actual string to the buffer, and, in unformatting one must ignore the
138    length of the string because unformatting procedure will take it
139    automatically.
140
141    Example:
142
143    Formatting:    ..., SILC_STR_UI_INT(strlen(string)),
144                        SILC_STR_UI32_STRING(string), ...
145    Unformatting:  ..., SILC_STR_UI32_STRING(&string), ...
146
147    I.e., you ignore the formatted length field in unformatting. If you don't
148    the unformatting procedure might fail and it definitely does not unformat
149    the data reliably.
150
151    _ALLOC routines automatically allocates memory for the variable sent
152    as argument in unformatting.
153
154 */
155 #define SILC_STR_UI8_STRING(x) SILC_BUFFER_PARAM_UI8_STRING, (x)
156 #define SILC_STR_UI8_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI8_STRING_ALLOC, (x)
157 #define SILC_STR_UI16_STRING(x) SILC_BUFFER_PARAM_UI16_STRING, (x)
158 #define SILC_STR_UI16_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI16_STRING_ALLOC, (x)
159 #define SILC_STR_UI32_STRING(x) SILC_BUFFER_PARAM_UI32_STRING, (x)
160 #define SILC_STR_UI32_STRING_ALLOC(x) SILC_BUFFER_PARAM_UI32_STRING_ALLOC, (x)
161
162 /* Unsigned string. Second argument is the length of the string.
163
164    Formatting:    SILC_STR_UI32_NSTRING(unsigned char *, SilcUInt32)
165    Unformatting:  SILC_STR_UI32_NSTRING(unsigned char **, SilcUInt32 *)
166
167    Unformatting procedure will check for length of the string from the
168    buffer before trying to get the string out. Thus, one *must* format the
169    length as UI_INT or UI_SHORT into the buffer *before* formatting the
170    actual string to the buffer, and, in unformatting one must ignore the
171    length of the string because unformatting procedure will take it
172    automatically.
173
174    Example:
175
176    Formatting:    ..., SILC_STR_UI_INT(strlen(string)),
177                        SILC_STR_UI32_NSTRING(string, strlen(string)), ...
178    Unformatting:  ..., SILC_STR_UI32_NSTRING(&string, &len), ...
179
180    I.e., you ignore the formatted length field in unformatting. If you don't
181    the unformatting procedure might fail and it definitely does not unformat
182    the data reliably. The length taken from the buffer is returned to the
183    pointer sent as argument (&len in above example).
184
185    UI/SI16 and UI/SI32 means that the length is considered to be either
186    short (16 bits) or int (32 bits) in unformatting.
187
188    _ALLOC routines automatically allocates memory for the variable sent
189    as argument in unformatting.
190
191 */
192 #define SILC_STR_UI8_NSTRING(x, l) SILC_BUFFER_PARAM_UI8_NSTRING, (x), (l)
193 #define SILC_STR_UI8_NSTRING_ALLOC(x, l) \
194   SILC_BUFFER_PARAM_UI8_NSTRING_ALLOC, (x), (l)
195 #define SILC_STR_UI16_NSTRING(x, l) SILC_BUFFER_PARAM_UI16_NSTRING, (x), (l)
196 #define SILC_STR_UI16_NSTRING_ALLOC(x, l) \
197   SILC_BUFFER_PARAM_UI16_NSTRING_ALLOC, (x), (l)
198 #define SILC_STR_UI32_NSTRING(x, l) SILC_BUFFER_PARAM_UI32_NSTRING, (x), (l)
199 #define SILC_STR_UI32_NSTRING_ALLOC(x, l) \
200   SILC_BUFFER_PARAM_UI32_NSTRING_ALLOC, (x), (l)
201
202 /* Extended Unsigned string formatting. Second argument is the length of
203    the string.
204
205    Formatting:    This is equal to using *_NSTRING
206    Unformatting:  SILC_STR_UI_XNSTRING(unsigned char **, SilcUInt32)
207
208    This type can be used to take arbitrary length string from the buffer
209    by sending the requested amount of bytes as argument. This differs
210    from *_STRING and *_NSTRING so that this doesn't try to find the
211    length of the data from the buffer but the length of the data is
212    sent as argument. This a handy way to unformat fixed length strings
213    from the buffer without having the length of the string formatted
214    in the buffer.
215
216    _ALLOC routines automatically allocates memory for the variable sent
217    as argument in unformatting.
218
219 */
220 #define SILC_STR_UI_XNSTRING(x, l) SILC_BUFFER_PARAM_UI_XNSTRING, (x), (l)
221 #define SILC_STR_UI_XNSTRING_ALLOC(x, l) \
222   SILC_BUFFER_PARAM_UI_XNSTRING_ALLOC, (x), (l)
223
224 /* Marks end of the argument list. This must be at the end of the
225    argument list or error will occur. */
226 #define SILC_STR_END SILC_BUFFER_PARAM_END
227
228 /* Prototypes */
229
230 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format
231  *
232  * SYNOPSIS
233  *
234  *    int silc_buffer_format(SilcBuffer dst, ...);
235  *
236  * DESCRIPTION
237  *
238  *    Formats a buffer from a variable argument list.  Returns -1 on error
239  *    and the length of the formatted buffer otherwise.
240  *
241  ***/
242 int silc_buffer_format(SilcBuffer dst, ...);
243
244 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat
245  *
246  * SYNOPSIS
247  *
248  *    int silc_buffer_unformat(SilcBuffer src, ...);
249  *
250  * DESCRIPTION
251  *
252  *    Unformats a buffer from a variable argument list.  Returns -1 on error
253  *    and the length of the unformatted buffer otherwise.
254  *
255  ***/
256 int silc_buffer_unformat(SilcBuffer src, ...);
257
258 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_format_vp
259  *
260  * SYNOPSIS
261  *
262  *    int silc_buffer_format_vp(SilcBuffer dst, va_list vp);
263  *
264  * DESCRIPTION
265  *
266  *    Formats a buffer from a variable argument list indicated by the `ap'.
267  *    Returns -1 on error and the length of the formatted buffer otherwise.
268  *
269  ***/
270 int silc_buffer_format_vp(SilcBuffer dst, va_list ap);
271
272 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_unformat_vp
273  *
274  * SYNOPSIS
275  *
276  *    int silc_buffer_unformat_vp(SilcBuffer src, va_list vp);
277  *
278  * DESCRIPTION
279  *
280  *    Unformats a buffer from a variable argument list indicated by the `ap'.
281  *    Returns -1 on error and the length of the unformatted buffer otherwise.
282  *
283  ***/
284 int silc_buffer_unformat_vp(SilcBuffer src, va_list ap);
285
286 /****f* silcutil/SilcBufferFormatAPI/silc_buffer_strformat
287  *
288  * SYNOPSIS
289  *
290  *   int silc_buffer_strformat(SilcBuffer dst, ...);
291  *
292  * DESCRIPTION
293  *
294  *   Formats a buffer from variable argument list of strings.  Each
295  *   string must be NULL-terminated and the variable argument list must
296  *   be end with SILC_STR_END argument.  This allows that a string in
297  *   the list can be NULL, in which case it is skipped.  This automatically
298  *   allocates the space for the buffer data but `dst' must be already
299  *   allocated by the caller.
300  *
301  ***/
302 int silc_buffer_strformat(SilcBuffer dst, ...);
303
304 #endif  /* !SILCBUFFMT_H */