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 {
39 /* Parses arguments and returns them into Argument Payload structure. */
41 SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload,
45 SilcBufferStruct buffer;
46 SilcArgumentPayload new;
48 unsigned char arg_num = 0;
49 unsigned char arg_type = 0;
53 SILC_LOG_DEBUG(("Parsing argument payload"));
55 silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
56 new = silc_calloc(1, sizeof(*new));
57 new->argv = silc_calloc(argc, sizeof(unsigned char *));
58 new->argv_lens = silc_calloc(argc, sizeof(uint32));
59 new->argv_types = silc_calloc(argc, sizeof(uint32));
63 for (i = 0; i < argc; i++) {
64 ret = silc_buffer_unformat(&buffer,
65 SILC_STR_UI_SHORT(&p_len),
66 SILC_STR_UI_CHAR(&arg_type),
71 new->argv_lens[i] = p_len;
72 new->argv_types[i] = arg_type;
74 if (p_len > buffer.len - 3)
77 /* Get argument data */
78 silc_buffer_pull(&buffer, 3);
79 ret = silc_buffer_unformat(&buffer,
80 SILC_STR_UI_XNSTRING_ALLOC(&new->argv[i],
86 silc_buffer_pull(&buffer, p_len);
87 pull_len += 3 + p_len;
96 silc_buffer_push(&buffer, pull_len);
104 for (k = 0; k < i; k++)
105 silc_free(new->argv[k]);
108 silc_free(new->argv);
109 silc_free(new->argv_lens);
110 silc_free(new->argv_types);
118 /* Encodes arguments in to Argument Paylods returning them to SilcBuffer. */
120 SilcBuffer silc_argument_payload_encode(uint32 argc,
121 unsigned char **argv,
129 SILC_LOG_DEBUG(("Encoding Argument payload"));
132 for (i = 0; i < argc; i++)
133 len += 3 + argv_lens[i];
135 buffer = silc_buffer_alloc(len);
136 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
139 for (i = 0; i < argc; i++) {
140 silc_buffer_format(buffer,
141 SILC_STR_UI_SHORT(argv_lens[i]),
142 SILC_STR_UI_CHAR(argv_types[i]),
143 SILC_STR_UI_XNSTRING(argv[i], argv_lens[i]),
145 silc_buffer_pull(buffer, 3 + argv_lens[i]);
148 silc_buffer_push(buffer, len);
153 /* Same as above but encode the buffer from SilcArgumentPayload structure
154 instead of raw data. */
156 SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload)
162 SILC_LOG_DEBUG(("Encoding Argument payload"));
165 for (i = 0; i < payload->argc; i++)
166 len += 3 + payload->argv_lens[i];
168 buffer = silc_buffer_alloc(len);
169 silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
172 for (i = 0; i < payload->argc; i++) {
173 silc_buffer_format(buffer,
174 SILC_STR_UI_SHORT(payload->argv_lens[i]),
175 SILC_STR_UI_CHAR(payload->argv_types[i]),
176 SILC_STR_UI_XNSTRING(payload->argv[i],
177 payload->argv_lens[i]),
179 silc_buffer_pull(buffer, 3 + payload->argv_lens[i]);
182 silc_buffer_push(buffer, len);
187 /* Frees Argument Payload */
189 void silc_argument_payload_free(SilcArgumentPayload payload)
194 for (i = 0; i < payload->argc; i++)
195 silc_free(payload->argv[i]);
197 silc_free(payload->argv);
198 silc_free(payload->argv_lens);
199 silc_free(payload->argv_types);
204 /* Returns number of arguments in payload */
206 uint32 silc_argument_get_arg_num(SilcArgumentPayload payload)
208 return payload ? payload->argc : 0;
211 /* Returns first argument from payload. */
213 unsigned char *silc_argument_get_first_arg(SilcArgumentPayload payload,
222 *ret_len = payload->argv_lens[payload->pos];
224 return payload->argv[payload->pos++];
227 /* Returns next argument from payload or NULL if no more arguments. */
229 unsigned char *silc_argument_get_next_arg(SilcArgumentPayload payload,
235 if (payload->pos >= payload->argc)
239 *ret_len = payload->argv_lens[payload->pos];
241 return payload->argv[payload->pos++];
244 /* Returns argument which type is `type'. */
246 unsigned char *silc_argument_get_arg_type(SilcArgumentPayload payload,
255 for (i = 0; i < payload->argc; i++)
256 if (payload->argv_types[i] == type)
259 if (i >= payload->argc)
263 *ret_len = payload->argv_lens[i];
265 return payload->argv[i];