addition of silc.css
[silc.git] / lib / silccore / silcnotify.c
1 /*
2
3   silcnotify.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 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 /* $Id$ */
21
22 #include "silcincludes.h"
23 #include "silcnotify.h"
24
25 /******************************************************************************
26
27                                Notify Payload
28
29 ******************************************************************************/
30
31 struct SilcNotifyPayloadStruct {
32   SilcNotifyType type;
33   unsigned char argc;
34   SilcArgumentPayload args;
35 };
36
37 /* Parse notify payload buffer and return data into payload structure */
38
39 SilcNotifyPayload silc_notify_payload_parse(SilcBuffer buffer)
40 {
41   SilcNotifyPayload new;
42   uint16 len;
43   int ret;
44
45   SILC_LOG_DEBUG(("Parsing Notify payload"));
46
47   new = silc_calloc(1, sizeof(*new));
48
49   ret = silc_buffer_unformat(buffer,
50                              SILC_STR_UI_SHORT(&new->type),
51                              SILC_STR_UI_SHORT(&len),
52                              SILC_STR_UI_CHAR(&new->argc),
53                              SILC_STR_END);
54   if (ret == -1)
55     goto err;
56
57   if (len > buffer->len)
58     goto err;
59
60   if (new->argc) {
61     silc_buffer_pull(buffer, 5);
62     new->args = silc_argument_payload_parse(buffer, new->argc);
63     silc_buffer_push(buffer, 5);
64   }
65
66   return new;
67
68  err:
69   silc_free(new);
70   return NULL;
71 }
72
73 /* Encode notify payload with variable argument list. If `argc' is > 0
74    argument payloads will be associated to the notify payload. Variable
75    arguments must be {usigned char *, uint32 (len)}. */
76
77 SilcBuffer silc_notify_payload_encode(SilcNotifyType type, uint32 argc, 
78                                       va_list ap)
79 {
80   SilcBuffer buffer;
81   SilcBuffer args = NULL;
82   unsigned char **argv;
83   uint32 *argv_lens = NULL, *argv_types = NULL;
84   unsigned char *x;
85   uint32 x_len;
86   int i, k = 0, len = 0;
87
88   if (argc) {
89     argv = silc_calloc(argc, sizeof(unsigned char *));
90     argv_lens = silc_calloc(argc, sizeof(uint32));
91     argv_types = silc_calloc(argc, sizeof(uint32));
92     
93     for (i = 0, k = 0; i < argc; i++) {
94       x = va_arg(ap, unsigned char *);
95       x_len = va_arg(ap, uint32);
96
97       if (!x || !x_len)
98         continue;
99       
100       argv[k] = silc_calloc(x_len + 1, sizeof(unsigned char));
101       memcpy(argv[k], x, x_len);
102       argv_lens[k] = x_len;
103       argv_types[k] = i + 1;
104       k++;
105     }
106
107     args = silc_argument_payload_encode(k, argv, argv_lens, argv_types);
108     len = args->len;
109
110     for (i = 0; i < k; i++)
111       silc_free(argv[i]);
112     silc_free(argv);
113     silc_free(argv_lens);
114     silc_free(argv_types);
115   }
116
117   len += 5;
118   buffer = silc_buffer_alloc(len);
119   silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
120   silc_buffer_format(buffer,
121                      SILC_STR_UI_SHORT(type),
122                      SILC_STR_UI_SHORT(len),
123                      SILC_STR_UI_CHAR(k),
124                      SILC_STR_END);
125
126   if (k) {
127     silc_buffer_pull(buffer, 5);
128     silc_buffer_format(buffer,
129                        SILC_STR_UI_XNSTRING(args->data, args->len),
130                        SILC_STR_END);
131     silc_buffer_push(buffer, 5);
132     silc_buffer_free(args);
133   }
134
135   return buffer;
136 }
137
138 /* Same as above but takes argument from the `args' Argument Payload. */
139
140 SilcBuffer silc_notify_payload_encode_args(SilcNotifyType type, 
141                                            uint32 argc,
142                                            SilcBuffer args)
143 {
144   SilcBuffer buffer;
145   int len;
146
147   len = 5 + (args ? args->len : 0);
148   buffer = silc_buffer_alloc(len);
149   silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer));
150   silc_buffer_format(buffer,
151                      SILC_STR_UI_SHORT(type),
152                      SILC_STR_UI_SHORT(len),
153                      SILC_STR_UI_CHAR(argc),
154                      SILC_STR_END);
155
156   if (args) {
157     silc_buffer_pull(buffer, 5);
158     silc_buffer_format(buffer,
159                        SILC_STR_UI_XNSTRING(args->data, args->len),
160                        SILC_STR_END);
161     silc_buffer_push(buffer, 5);
162   }
163
164   return buffer;
165 }
166
167 /* Frees notify payload */
168
169 void silc_notify_payload_free(SilcNotifyPayload payload)
170 {
171   if (payload) {
172     silc_argument_payload_free(payload->args);
173     silc_free(payload);
174   }
175 }
176
177 /* Return notify type */
178
179 SilcNotifyType silc_notify_get_type(SilcNotifyPayload payload)
180 {
181   return payload->type;
182 }
183
184 /* Return argument nums */
185
186 uint32 silc_notify_get_arg_num(SilcNotifyPayload payload)
187 {
188   return payload->argc;
189 }
190
191 /* Return argument payload */
192
193 SilcArgumentPayload silc_notify_get_args(SilcNotifyPayload payload)
194 {
195   return payload->args;
196 }