Ticket #551: sip_generic_uri.c

File sip_generic_uri.c, 3.9 KB (added by bennylp, 16 years ago)
Line 
1
2#include <pjsip/sip_generic_uri.h>
3#include <pjsip/sip_msg.h>
4#include <pjsip/sip_parser.h>
5#include <pjsip/print_util.h>
6#include <pj/pool.h>
7#include <pj/assert.h>
8#include <pj/string.h>
9#include <pj/ctype.h>
10#include <pj/except.h>
11#include <pjlib-util/string.h>
12#include <pjlib-util/scanner.h>
13
14#ifdef __GNUC__
15#  define HAPPY_FLAG    (void*)
16#else
17#  define HAPPY_FLAG
18#endif
19
20/*
21        A generic URI can consist of (For a complete BNF see RFC 2396):
22        #?;:@&=+-_.!~*'()%$,/
23*/
24#define ALLOWED_CHARS "#?;:@&=+-_.!~*'()%$,/"
25
26static pj_cis_buf_t cis_buf;
27static pj_cis_t pjsip_GENERIC_URI_SPEC;
28
29static const pj_str_t *generic_uri_get_scheme(const pjsip_generic_uri*);
30static void *generic_uri_get_uri(pjsip_generic_uri*);
31static pj_ssize_t generic_uri_print(
32        pjsip_uri_context_e context,
33        const pjsip_generic_uri *url,
34        char *buf, pj_size_t size);
35static int generic_uri_cmp(
36        pjsip_uri_context_e context,
37        const pjsip_generic_uri *url1,
38        const pjsip_generic_uri *url2);
39static pjsip_generic_uri* generic_uri_clone(
40        pj_pool_t *pool,
41        const pjsip_generic_uri *rhs);
42
43
44
45static void* generic_uri_parse(
46        pj_scanner *scanner,
47        pj_pool_t *pool,
48        pj_bool_t parse_params);
49
50static pjsip_uri_vptr generic_uri_vptr = {
51        HAPPY_FLAG &generic_uri_get_scheme,
52        HAPPY_FLAG &generic_uri_get_uri,
53        HAPPY_FLAG &generic_uri_print,
54        HAPPY_FLAG &generic_uri_cmp,
55        HAPPY_FLAG &generic_uri_clone
56};
57
58
59pj_status_t pjsip_generic_uri_subsys_init(void) {
60       
61        pj_status_t status;
62
63        pj_cis_buf_init(&cis_buf);
64        status = pj_cis_init(&cis_buf, &pjsip_GENERIC_URI_SPEC);
65  PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
66        pj_cis_add_alpha(&pjsip_GENERIC_URI_SPEC); /* a-zA-Z*/
67        pj_cis_add_num(&pjsip_GENERIC_URI_SPEC); /* 0-9 */
68  pj_cis_add_str(&pjsip_GENERIC_URI_SPEC, ALLOWED_CHARS); /* #?;:@&=+-_.!~*'()%$,/ */
69
70        status = pjsip_register_generic_uri_parser(&generic_uri_parse);
71        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status);
72       
73        return PJ_SUCCESS;
74}
75
76
77PJ_DEF(pjsip_generic_uri*) pjsip_generic_uri_create(pj_pool_t *pool) {
78        pjsip_generic_uri *uri = (pjsip_generic_uri *)pj_pool_zalloc(pool, sizeof(pjsip_generic_uri));
79  uri->vptr = &generic_uri_vptr;
80  return uri;
81}
82
83static const pj_str_t *generic_uri_get_scheme( const pjsip_generic_uri *uri ) {
84        return &(uri->scheme);
85}
86
87static void *generic_uri_get_uri( pjsip_generic_uri *uri ) {
88    return uri;
89}
90
91static pj_ssize_t generic_uri_print(
92        pjsip_uri_context_e context,
93        const pjsip_generic_uri *uri,
94        char *buf, pj_size_t size) {
95
96        char *startbuf = buf;
97  char *endbuf = buf + size;
98
99  PJ_UNUSED_ARG(context);
100 
101  /* Print scheme. */
102  copy_advance(buf, uri->scheme);
103  *buf++ = ':';
104
105  /* Print uri. */
106  copy_advance(buf, uri->uri);
107 
108        return (buf - startbuf);
109}
110
111static int generic_uri_cmp(
112        pjsip_uri_context_e context,
113        const pjsip_generic_uri *uri1,
114        const pjsip_generic_uri *uri2) {
115       
116        PJ_UNUSED_ARG(context);
117
118        /* Scheme must match. */
119        if(pj_strcmp(&(uri1->scheme), &(uri2->scheme)) != 0) {
120                return -1;
121        }
122
123        /* URI must match. */
124        if(pj_strcmp(&(uri1->uri), &(uri2->uri)) != 0) {
125                return -1;
126        }
127
128        /* Equal. */
129        return 0;
130}
131
132/* Clone *: URI */
133static pjsip_generic_uri* generic_uri_clone(
134        pj_pool_t *pool,
135        const pjsip_generic_uri *rhs) {
136       
137        pjsip_generic_uri *uri = pjsip_generic_uri_create(pool);
138        pj_strdup(pool, &uri->scheme, &rhs->scheme);
139        pj_strdup(pool, &uri->uri, &rhs->uri);
140
141        return uri;
142}
143
144/* Parse *: URI
145 * THis actually returns (pjsip_generic_uri *) type. */
146
147static void* generic_uri_parse(
148        pj_scanner *scanner,
149        pj_pool_t *pool,
150        pj_bool_t parse_params) {
151
152        pjsip_generic_uri *uri = 0;
153        const pjsip_parser_const_t *pc = pjsip_parser_const();
154  int skip_ws = scanner->skip_ws;
155
156        scanner->skip_ws = 0;
157       
158        uri = pjsip_generic_uri_create(pool);
159
160  pj_scan_get(scanner, &pc->pjsip_TOKEN_SPEC, &uri->scheme);
161        if (pj_scan_get_char(scanner) != ':') {
162                PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
163        }
164       
165        pj_scan_get(scanner, &pjsip_GENERIC_URI_SPEC, &uri->uri);
166        scanner->skip_ws = skip_ws;
167
168        return uri;
169}
170
171