blob: acd20092e79e71e40dd5742b3386685aa21d33af [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
Benny Prijono834aee32006-02-19 01:38:06 +000019#include <pjsip-simple/pidf.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000020#include <pj/string.h>
21#include <pj/pool.h>
Benny Prijono834aee32006-02-19 01:38:06 +000022#include <pj/assert.h>
23
Benny Prijono5dcb38d2005-11-21 01:55:47 +000024
25struct pjpidf_op_desc pjpidf_op =
26{
27 {
28 &pjpidf_pres_construct,
29 &pjpidf_pres_add_tuple,
30 &pjpidf_pres_get_first_tuple,
31 &pjpidf_pres_get_next_tuple,
32 &pjpidf_pres_find_tuple,
33 &pjpidf_pres_remove_tuple,
34 &pjpidf_pres_add_note,
35 &pjpidf_pres_get_first_note,
36 &pjpidf_pres_get_next_note
37 },
38 {
39 &pjpidf_tuple_construct,
40 &pjpidf_tuple_get_id,
41 &pjpidf_tuple_set_id,
42 &pjpidf_tuple_get_status,
43 &pjpidf_tuple_get_contact,
44 &pjpidf_tuple_set_contact,
45 &pjpidf_tuple_set_contact_prio,
46 &pjpidf_tuple_get_contact_prio,
47 &pjpidf_tuple_add_note,
48 &pjpidf_tuple_get_first_note,
49 &pjpidf_tuple_get_next_note,
50 &pjpidf_tuple_get_timestamp,
51 &pjpidf_tuple_set_timestamp,
52 &pjpidf_tuple_set_timestamp_np
53 },
54 {
55 &pjpidf_status_construct,
56 &pjpidf_status_is_basic_open,
57 &pjpidf_status_set_basic_open
58 }
59};
60
61static pj_str_t PRESENCE = { "presence", 8 };
62static pj_str_t ENTITY = { "entity", 6};
63static pj_str_t TUPLE = { "tuple", 5 };
64static pj_str_t ID = { "id", 2 };
65static pj_str_t NOTE = { "note", 4 };
66static pj_str_t STATUS = { "status", 6 };
67static pj_str_t CONTACT = { "contact", 7 };
68static pj_str_t PRIORITY = { "priority", 8 };
69static pj_str_t TIMESTAMP = { "timestamp", 9 };
70static pj_str_t BASIC = { "basic", 5 };
71static pj_str_t OPEN = { "open", 4 };
72static pj_str_t CLOSED = { "closed", 6 };
73static pj_str_t EMPTY_STRING = { NULL, 0 };
74
75static void xml_init_node(pj_pool_t *pool, pj_xml_node *node,
76 pj_str_t *name, const pj_str_t *value)
77{
78 pj_list_init(&node->attr_head);
79 pj_list_init(&node->node_head);
80 node->name = *name;
81 if (value) pj_strdup(pool, &node->content, value);
82 else node->content.ptr=NULL, node->content.slen=0;
83}
84
85static pj_xml_attr* xml_create_attr(pj_pool_t *pool, pj_str_t *name,
86 const pj_str_t *value)
87{
88 pj_xml_attr *attr = pj_pool_alloc(pool, sizeof(*attr));
89 attr->name = *name;
90 pj_strdup(pool, &attr->value, value);
91 return attr;
92}
93
94/* Presence */
95PJ_DEF(void) pjpidf_pres_construct(pj_pool_t *pool, pjpidf_pres *pres,
96 const pj_str_t *entity)
97{
98 pj_xml_attr *attr;
99
100 xml_init_node(pool, pres, &PRESENCE, NULL);
101 attr = xml_create_attr(pool, &ENTITY, entity);
102 pj_xml_add_attr(pres, attr);
103}
104
105PJ_DEF(pjpidf_tuple*) pjpidf_pres_add_tuple(pj_pool_t *pool, pjpidf_pres *pres,
106 const pj_str_t *id)
107{
108 pjpidf_tuple *t = pj_pool_alloc(pool, sizeof(*t));
109 pjpidf_tuple_construct(pool, t, id);
110 pj_xml_add_node(pres, t);
111 return t;
112}
113
114PJ_DEF(pjpidf_tuple*) pjpidf_pres_get_first_tuple(pjpidf_pres *pres)
115{
116 return pj_xml_find_node(pres, &TUPLE);
117}
118
119PJ_DEF(pjpidf_tuple*) pjpidf_pres_get_next_tuple(pjpidf_pres *pres,
120 pjpidf_tuple *tuple)
121{
122 return pj_xml_find_next_node(pres, tuple, &TUPLE);
123}
124
125static pj_bool_t find_tuple_by_id(pj_xml_node *node, const void *id)
126{
127 return pj_xml_find_attr(node, &ID, id) != NULL;
128}
129
130PJ_DEF(pjpidf_tuple*) pjpidf_pres_find_tuple(pjpidf_pres *pres, const pj_str_t *id)
131{
132 return pj_xml_find(pres, &TUPLE, id, &find_tuple_by_id);
133}
134
135PJ_DEF(void) pjpidf_pres_remove_tuple(pjpidf_pres *pres, pjpidf_tuple *t)
136{
Benny Prijono834aee32006-02-19 01:38:06 +0000137 PJ_UNUSED_ARG(pres);
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000138 pj_list_erase(t);
139}
140
141PJ_DEF(pjpidf_note*) pjpidf_pres_add_note(pj_pool_t *pool, pjpidf_pres *pres,
142 const pj_str_t *text)
143{
144 pjpidf_note *note = pj_pool_alloc(pool, sizeof(*note));
145 xml_init_node(pool, note, &NOTE, text);
146 pj_xml_add_node(pres, note);
147 return note;
148}
149
150PJ_DEF(pjpidf_note*) pjpidf_pres_get_first_note(pjpidf_pres *pres)
151{
152 return pj_xml_find_node( pres, &NOTE);
153}
154
155PJ_DEF(pjpidf_note*) pjpidf_pres_get_next_note(pjpidf_pres *t, pjpidf_note *note)
156{
157 return pj_xml_find_next_node(t, note, &NOTE);
158}
159
160
161/* Tuple */
162PJ_DEF(void) pjpidf_tuple_construct(pj_pool_t *pool, pjpidf_tuple *t,
163 const pj_str_t *id)
164{
165 pj_xml_attr *attr;
166 pjpidf_status *st;
167
168 xml_init_node(pool, t, &TUPLE, NULL);
169 attr = xml_create_attr(pool, &ID, id);
170 pj_xml_add_attr(t, attr);
171 st = pj_pool_alloc(pool, sizeof(*st));
172 pjpidf_status_construct(pool, st);
173 pj_xml_add_node(t, st);
174}
175
176PJ_DEF(const pj_str_t*) pjpidf_tuple_get_id(const pjpidf_tuple *t)
177{
178 const pj_xml_attr *attr = pj_xml_find_attr((pj_xml_node*)t, &ID, NULL);
179 pj_assert(attr);
180 return &attr->value;
181}
182
183PJ_DEF(void) pjpidf_tuple_set_id(pj_pool_t *pool, pjpidf_tuple *t, const pj_str_t *id)
184{
185 pj_xml_attr *attr = pj_xml_find_attr(t, &ID, NULL);
186 pj_assert(attr);
187 pj_strdup(pool, &attr->value, id);
188}
189
190
191PJ_DEF(pjpidf_status*) pjpidf_tuple_get_status(pjpidf_tuple *t)
192{
193 pjpidf_status *st = (pjpidf_status*)pj_xml_find_node(t, &STATUS);
194 pj_assert(st);
195 return st;
196}
197
198
199PJ_DEF(const pj_str_t*) pjpidf_tuple_get_contact(const pjpidf_tuple *t)
200{
201 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &CONTACT);
202 if (!node)
203 return &EMPTY_STRING;
204 return &node->content;
205}
206
207PJ_DEF(void) pjpidf_tuple_set_contact(pj_pool_t *pool, pjpidf_tuple *t,
208 const pj_str_t *contact)
209{
210 pj_xml_node *node = pj_xml_find_node(t, &CONTACT);
211 if (!node) {
212 node = pj_pool_alloc(pool, sizeof(*node));
213 xml_init_node(pool, node, &CONTACT, contact);
214 pj_xml_add_node(t, node);
215 } else {
216 pj_strdup(pool, &node->content, contact);
217 }
218}
219
220PJ_DEF(void) pjpidf_tuple_set_contact_prio(pj_pool_t *pool, pjpidf_tuple *t,
221 const pj_str_t *prio)
222{
223 pj_xml_node *node = pj_xml_find_node(t, &CONTACT);
224 pj_xml_attr *attr;
225
226 if (!node) {
227 node = pj_pool_alloc(pool, sizeof(*node));
228 xml_init_node(pool, node, &CONTACT, NULL);
229 pj_xml_add_node(t, node);
230 }
231 attr = pj_xml_find_attr(node, &PRIORITY, NULL);
232 if (!attr) {
233 attr = xml_create_attr(pool, &PRIORITY, prio);
234 pj_xml_add_attr(node, attr);
235 } else {
236 pj_strdup(pool, &attr->value, prio);
237 }
238}
239
240PJ_DEF(const pj_str_t*) pjpidf_tuple_get_contact_prio(const pjpidf_tuple *t)
241{
242 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &CONTACT);
243 pj_xml_attr *attr;
244
245 if (!node)
246 return &EMPTY_STRING;
247 attr = pj_xml_find_attr(node, &PRIORITY, NULL);
248 if (!attr)
249 return &EMPTY_STRING;
250 return &attr->value;
251}
252
253
254PJ_DEF(pjpidf_note*) pjpidf_tuple_add_note(pj_pool_t *pool, pjpidf_tuple *t,
255 const pj_str_t *text)
256{
257 pjpidf_note *note = pj_pool_alloc(pool, sizeof(*note));
258 xml_init_node(pool, note, &NOTE, text);
259 pj_xml_add_node(t, note);
260 return note;
261}
262
263PJ_DEF(pjpidf_note*) pjpidf_tuple_get_first_note(pjpidf_tuple *t)
264{
265 return pj_xml_find_node(t, &NOTE);
266}
267
268PJ_DEF(pjpidf_note*) pjpidf_tuple_get_next_note(pjpidf_tuple *t, pjpidf_note *n)
269{
270 return pj_xml_find_next_node(t, n, &NOTE);
271}
272
273
274PJ_DEF(const pj_str_t*) pjpidf_tuple_get_timestamp(const pjpidf_tuple *t)
275{
276 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)t, &TIMESTAMP);
277 return node ? &node->content : &EMPTY_STRING;
278}
279
280PJ_DEF(void) pjpidf_tuple_set_timestamp(pj_pool_t *pool, pjpidf_tuple *t,
281 const pj_str_t *ts)
282{
283 pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP);
284 if (!node) {
285 node = pj_pool_alloc(pool, sizeof(*node));
286 xml_init_node(pool, node, &TIMESTAMP, ts);
287 } else {
288 pj_strdup(pool, &node->content, ts);
289 }
290}
291
292
293PJ_DEF(void) pjpidf_tuple_set_timestamp_np(pj_pool_t *pool, pjpidf_tuple *t,
294 pj_str_t *ts)
295{
296 pj_xml_node *node = pj_xml_find_node(t, &TIMESTAMP);
297 if (!node) {
298 node = pj_pool_alloc(pool, sizeof(*node));
299 xml_init_node(pool, node, &TIMESTAMP, ts);
300 } else {
301 node->content = *ts;
302 }
303}
304
305
306/* Status */
307PJ_DEF(void) pjpidf_status_construct(pj_pool_t *pool, pjpidf_status *st)
308{
309 pj_xml_node *node;
310
311 xml_init_node(pool, st, &STATUS, NULL);
312 node = pj_pool_alloc(pool, sizeof(*node));
313 xml_init_node(pool, node, &BASIC, &CLOSED);
314 pj_xml_add_node(st, node);
315}
316
317PJ_DEF(pj_bool_t) pjpidf_status_is_basic_open(const pjpidf_status *st)
318{
319 pj_xml_node *node = pj_xml_find_node((pj_xml_node*)st, &BASIC);
320 pj_assert(node != NULL);
321 return pj_stricmp(&node->content, &OPEN)==0;
322}
323
324PJ_DEF(void) pjpidf_status_set_basic_open(pjpidf_status *st, pj_bool_t open)
325{
326 pj_xml_node *node = pj_xml_find_node(st, &BASIC);
327 pj_assert(node != NULL);
328 node->content = open ? OPEN : CLOSED;
329}
330
331PJ_DEF(pjpidf_pres*) pjpidf_create(pj_pool_t *pool, const pj_str_t *entity)
332{
333 pjpidf_pres *pres = pj_pool_alloc(pool, sizeof(*pres));
334 pjpidf_pres_construct(pool, pres, entity);
335 return pres;
336}
337
338PJ_DEF(pjpidf_pres*) pjpidf_parse(pj_pool_t *pool, char *text, int len)
339{
340 pjpidf_pres *pres = pj_xml_parse(pool, text, len);
341 if (pres) {
342 if (pj_stricmp(&pres->name, &PRESENCE) != 0)
343 return NULL;
344 }
345 return pres;
346}
347
348PJ_DEF(int) pjpidf_print(const pjpidf_pres* pres, char *buf, int len)
349{
350 return pj_xml_print(pres, buf, len, PJ_TRUE);
351}
352