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 | |
---|
26 | static pj_cis_buf_t cis_buf; |
---|
27 | static pj_cis_t pjsip_GENERIC_URI_SPEC; |
---|
28 | |
---|
29 | static const pj_str_t *generic_uri_get_scheme(const pjsip_generic_uri*); |
---|
30 | static void *generic_uri_get_uri(pjsip_generic_uri*); |
---|
31 | static 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); |
---|
35 | static int generic_uri_cmp( |
---|
36 | pjsip_uri_context_e context, |
---|
37 | const pjsip_generic_uri *url1, |
---|
38 | const pjsip_generic_uri *url2); |
---|
39 | static pjsip_generic_uri* generic_uri_clone( |
---|
40 | pj_pool_t *pool, |
---|
41 | const pjsip_generic_uri *rhs); |
---|
42 | |
---|
43 | |
---|
44 | |
---|
45 | static void* generic_uri_parse( |
---|
46 | pj_scanner *scanner, |
---|
47 | pj_pool_t *pool, |
---|
48 | pj_bool_t parse_params); |
---|
49 | |
---|
50 | static 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 | |
---|
59 | pj_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 | |
---|
77 | PJ_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 | |
---|
83 | static const pj_str_t *generic_uri_get_scheme( const pjsip_generic_uri *uri ) { |
---|
84 | return &(uri->scheme); |
---|
85 | } |
---|
86 | |
---|
87 | static void *generic_uri_get_uri( pjsip_generic_uri *uri ) { |
---|
88 | return uri; |
---|
89 | } |
---|
90 | |
---|
91 | static 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 | |
---|
111 | static 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 */ |
---|
133 | static 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 | |
---|
147 | static 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 | |
---|