5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2001 Pekka Riikonen
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.
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.
19 /* Implementation of Argument Payload routines */
22 #include "silcincludes.h"
23 #include "silcargument.h"
25 /******************************************************************************
29 ******************************************************************************/
31 struct SilcArgumentPayloadStruct {
34 SilcUInt32 *argv_lens;
35 SilcUInt32 *argv_types;
39 /* Parses arguments and returns them into Argument Payload structure. */
41 SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload,
42 SilcUInt32 payload_len,
45 SilcBufferStruct buffer;
46 SilcArgumentPayload newp;
48 unsigned char arg_num = 0;
49 unsigned char arg_type = 0;
50 SilcUInt32 pull_len = 0;
53 SILC_LOG_DEBUG(("Parsing argument payload"));
55 silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
56 newp = silc_calloc(1, sizeof(*newp));
59 newp->argv = silc_calloc(argc, sizeof(unsigned char *));
62 newp->argv_lens = silc_calloc(argc, sizeof(SilcUInt32));
65 newp->argv_types = silc_calloc(argc, sizeof(SilcUInt32));
66 if (!newp->argv_types)
71 for (i = 0; i < argc; i++) {
72 ret = silc_buffer_unformat(&buffer,
73 SILC_STR_UI_SHORT(&p_len),
74 SILC_STR_UI_CHAR(&arg_type),
79 newp->argv_lens[i] = p_len;
80 newp->argv_types[i] = arg_type;
82 if (p_len > buffer.len - 3)
85 /* Get argument data */
86 silc_buffer_pull(&buffer, 3);
87 ret = silc_buffer_unformat(&buffer,
88 SILC_STR_UI_XNSTRING_ALLOC(&newp->argv[i],
94 silc_buffer_pull(&buffer, p_len);
95 pull_len += 3 + p_len;
104 silc_buffer_push(&buffer, pull_len);
110 for (ret = 0; ret < i; ret++)
111 silc_free(newp->argv[ret]);
113 silc_free(newp->argv);
114 silc_free(newp->argv_lens);
115 silc_free(newp->argv_types);
121 /* Encodes arguments in to Argument Paylods returning them to SilcBuffer. */
123 SilcBuffer silc_argument_payload_encode(SilcUInt32 argc,
124 unsigned char **argv,
125 SilcUInt32 *argv_lens,
126 SilcUInt32 *argv_types)
132 SILC_LOG_DEBUG(("Encoding Argument payload"));
135 for (i = 0; i < argc; i++)
136 len += 3 + argv_lens[i];
138 buffer = silc_buffer_alloc_size(len);
143 for (i = 0; i < argc; i++) {
144 silc_buffer_format(buffer,
145 SILC_STR_UI_SHORT(argv_lens[i]),
146 SILC_STR_UI_CHAR(argv_types[i]),
147 SILC_STR_UI_XNSTRING(argv[i], argv_lens[i]),
149 silc_buffer_pull(buffer, 3 + argv_lens[i]);
152 silc_buffer_push(buffer, len);
157 /* Same as above but encode the buffer from SilcArgumentPayload structure
158 instead of raw data. */
160 SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload)
166 SILC_LOG_DEBUG(("Encoding Argument payload"));
169 for (i = 0; i < payload->argc; i++)
170 len += 3 + payload->argv_lens[i];
172 buffer = silc_buffer_alloc_size(len);
177 for (i = 0; i < payload->argc; i++) {
178 silc_buffer_format(buffer,
179 SILC_STR_UI_SHORT(payload->argv_lens[i]),
180 SILC_STR_UI_CHAR(payload->argv_types[i]),
181 SILC_STR_UI_XNSTRING(payload->argv[i],
182 payload->argv_lens[i]),
184 silc_buffer_pull(buffer, 3 + payload->argv_lens[i]);
187 silc_buffer_push(buffer, len);
192 /* Frees Argument Payload */
194 void silc_argument_payload_free(SilcArgumentPayload payload)
199 for (i = 0; i < payload->argc; i++)
200 silc_free(payload->argv[i]);
202 silc_free(payload->argv);
203 silc_free(payload->argv_lens);
204 silc_free(payload->argv_types);
209 /* Returns number of arguments in payload */
211 SilcUInt32 silc_argument_get_arg_num(SilcArgumentPayload payload)
213 return payload ? payload->argc : 0;
216 /* Returns first argument from payload. */
218 unsigned char *silc_argument_get_first_arg(SilcArgumentPayload payload,
227 *ret_len = payload->argv_lens[payload->pos];
229 return payload->argv[payload->pos++];
232 /* Returns next argument from payload or NULL if no more arguments. */
234 unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload,
240 if (payload->pos >= payload->argc)
244 *ret_len = payload->argv_lens[payload->pos];
246 return payload->argv[payload->pos++];
249 /* Returns argument which type is `type'. */
251 unsigned char *silc_argument_get_arg_type(SilcArgumentPayload payload,
260 for (i = 0; i < payload->argc; i++)
261 if (payload->argv_types[i] == type)
264 if (i >= payload->argc)
268 *ret_len = payload->argv_lens[i];
270 return payload->argv[i];