msg
1.12.11
|
00001 /* 00002 * This file is part of the Sofia-SIP package 00003 * 00004 * Copyright (C) 2005 Nokia Corporation. 00005 * 00006 * Contact: Pekka Pessi <pekka.pessi@nokia-email.address.hidden> 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public License 00010 * as published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00021 * 02110-1301 USA 00022 * 00023 */ 00024 00025 #ifndef MSG_PARSER_H 00026 00027 #define MSG_PARSER_H 00028 00040 #ifndef SU_ALLOC_H 00041 #include <sofia-sip/su_alloc.h> 00042 #endif 00043 #ifndef MSG_HEADER_H 00044 #include <sofia-sip/msg_header.h> 00045 #endif 00046 #ifndef BNF_H 00047 #include <sofia-sip/bnf.h> 00048 #endif 00049 #ifndef URL_H 00050 #include <sofia-sip/url.h> 00051 #endif 00052 00053 SOFIA_BEGIN_DECLS 00054 00055 /* --------------------------------------------------------------------------- 00056 * 1) Header class definitions. 00057 */ 00058 00059 /* Do not use keywords until you fix msg_kind_foo_critical thing! */ \ 00060 #if HAVE_STRUCT_KEYWORDS && 0 00061 00062 #define MSG_HEADER_CLASS(pr, c, l, s, params, kind, dup, upd) \ 00063 {{ \ 00064 hc_hash: pr##c##_hash, \ 00065 hc_parse: pr##c##_d, \ 00066 hc_print: pr##c##_e, \ 00067 hc_dxtra: dup##_dup_xtra, \ 00068 hc_dup_one: dup##_dup_one, \ 00069 hc_update: upd##_update, \ 00070 hc_name: l, \ 00071 hc_len: sizeof(l) - 1, \ 00072 hc_short: s, \ 00073 hc_size: MSG_ALIGN(sizeof(pr##c##_t), sizeof(void*)), \ 00074 hc_params: offsetof(pr##c##_t, params), \ 00075 hc_kind: msg_kind_##kind, \ 00076 }} 00077 #else 00078 00079 #define MSG_HEADER_CLASS(pr, c, l, s, params, kind, dup, upd) \ 00080 {{ \ 00081 pr##c##_hash, \ 00082 pr##c##_d, \ 00083 pr##c##_e, \ 00084 dup##_dup_xtra, \ 00085 dup##_dup_one, \ 00086 upd##_update, \ 00087 l, \ 00088 sizeof(l) - 1, \ 00089 s, \ 00090 MSG_ALIGN(sizeof(pr##c##_t), sizeof(void*)), \ 00091 offsetof(pr##c##_t, params), \ 00092 msg_kind_##kind, \ 00093 }} 00094 #endif 00095 00096 /* Mark headers critical for understanding the message */ 00097 #define msg_kind_single_critical msg_kind_single, 1 00098 #define msg_kind_list_critical msg_kind_list, 1 00099 00100 SOFIAPUBFUN issize_t msg_extract_header(msg_t *msg, msg_pub_t *mo, 00101 char b[], isize_t bsiz, int eos); 00102 SOFIAPUBFUN issize_t msg_extract_separator(msg_t *msg, msg_pub_t *mo, 00103 char b[], isize_t bsiz, int eos); 00104 SOFIAPUBFUN issize_t msg_extract_payload(msg_t *msg, msg_pub_t *mo, 00105 msg_header_t **return_payload, 00106 usize_t body_len, 00107 char b[], isize_t bsiz, int eos); 00108 00109 /* --------------------------------------------------------------------------- 00110 * 2) Header processing methods for common headers. 00111 */ 00112 00113 SOFIAPUBFUN int msg_firstline_d(char *s, char **ss2, char **ss3); 00114 00115 SOFIAPUBFUN isize_t msg_default_dup_xtra(msg_header_t const *header, isize_t offset); 00116 SOFIAPUBFUN char *msg_default_dup_one(msg_header_t *dst, 00117 msg_header_t const *src, 00118 char *b, 00119 isize_t xtra); 00120 00121 SOFIAPUBFUN issize_t msg_numeric_d(su_home_t *, msg_header_t *h, char *s, isize_t slen); 00122 SOFIAPUBFUN issize_t msg_numeric_e(char [], isize_t, msg_header_t const *, int); 00123 00124 SOFIAPUBFUN issize_t msg_list_d(su_home_t *, msg_header_t *h, char *s, isize_t slen); 00125 SOFIAPUBFUN issize_t msg_list_e(char [], isize_t, msg_header_t const *, int); 00126 SOFIAPUBFUN isize_t msg_list_dup_xtra(msg_header_t const *h, isize_t offset); 00127 SOFIAPUBFUN char *msg_list_dup_one(msg_header_t *dst, 00128 msg_header_t const *src, 00129 char *b, isize_t xtra); 00130 00131 SOFIAPUBFUN issize_t msg_generic_d(su_home_t *, msg_header_t *, char *, isize_t); 00132 SOFIAPUBFUN issize_t msg_generic_e(char [], isize_t, msg_header_t const *, int); 00133 SOFIAPUBFUN isize_t msg_generic_dup_xtra(msg_header_t const *h, isize_t offset); 00134 SOFIAPUBFUN char *msg_generic_dup_one(msg_header_t *dst, 00135 msg_header_t const *src, 00136 char *b, 00137 isize_t xtra); 00138 00139 SOFIAPUBFUN isize_t msg_unknown_dup_xtra(msg_header_t const *h, isize_t offset); 00140 SOFIAPUBFUN char *msg_unknown_dup_one(msg_header_t *dst, 00141 msg_header_t const *src, 00142 char *b, isize_t xtra); 00143 00144 SOFIAPUBFUN isize_t msg_error_dup_xtra(msg_header_t const *h, isize_t offset); 00145 SOFIAPUBFUN char *msg_error_dup_one(msg_header_t *dst, 00146 msg_header_t const *src, 00147 char *b, isize_t xtra); 00148 00149 SOFIAPUBFUN issize_t msg_payload_d(su_home_t *, msg_header_t *h, char *s, isize_t slen); 00150 SOFIAPUBFUN issize_t msg_payload_e(char b[], isize_t bsiz, msg_header_t const *, int f); 00151 SOFIAPUBFUN isize_t msg_payload_dup_xtra(msg_header_t const *h, isize_t offset); 00152 SOFIAPUBFUN char *msg_payload_dup_one(msg_header_t *dst, 00153 msg_header_t const *src, 00154 char *b, isize_t xtra); 00155 00156 SOFIAPUBFUN issize_t msg_separator_d(su_home_t *, msg_header_t *, char *, isize_t); 00157 SOFIAPUBFUN issize_t msg_separator_e(char [], isize_t, msg_header_t const *, int); 00158 00159 SOFIAPUBFUN issize_t msg_auth_d(su_home_t *, msg_header_t *h, char *s, isize_t slen); 00160 SOFIAPUBFUN issize_t msg_auth_e(char b[], isize_t bsiz, msg_header_t const *h, int f); 00161 SOFIAPUBFUN isize_t msg_auth_dup_xtra(msg_header_t const *h, isize_t offset); 00162 SOFIAPUBFUN char *msg_auth_dup_one(msg_header_t *dst, msg_header_t const *src, 00163 char *b, isize_t xtra); 00164 00165 /* --------------------------------------------------------------------------- 00166 * 2) Macros and prototypes for building header decoding/encoding functions. 00167 */ 00168 00169 #define MSG_HEADER_DATA(h) ((char *)(h) + (h)->sh_class->hc_size) 00170 00171 #define MSG_HEADER_TEST(h) ((h) && (h)->sh_class) 00172 00173 su_inline void *msg_header_data(msg_frg_t *h); 00174 00175 SOFIAPUBFUN int msg_hostport_d(char **ss, 00176 char const **return_host, 00177 char const **return_port); 00178 00179 SOFIAPUBFUN issize_t msg_token_d(char **ss, char const **return_token); 00180 SOFIAPUBFUN issize_t msg_uint32_d(char **ss, uint32_t *return_value); 00181 SOFIAPUBFUN issize_t msg_comment_d(char **ss, char const **return_comment); 00182 SOFIAPUBFUN issize_t msg_quoted_d(char **ss, char **return_unquoted); 00183 SOFIAPUBFUN issize_t msg_unquoted_e(char *b, isize_t bsiz, char const *s); 00184 00185 SOFIAPUBFUN issize_t msg_parse_next_field(su_home_t *home, msg_header_t *prev, 00186 char *s, isize_t slen); 00187 00189 #define MSG_TERM_E(p, e) ((p) < (e) ? (p)[0] = '\0' : '\0') 00190 00192 #define MSG_CHAR_E(p, e, c) (++(p) < (e) ? ((p)[-1]=(c)) : (c)) 00193 00195 #define MSG_STRING_LEN(s, sep_size) ((s) ? (strlen(s) + sep_size) : 0) 00196 00198 #define MSG_STRING_E(p, e, s) do { \ 00199 size_t _n = strlen(s); if (p + _n+1 < e) memcpy(p, s, _n+1); p+= _n; } while(0) 00200 00202 #define MSG_STRING_DUP(p, d, s) \ 00203 (void)((s)?((p)=(char*)memccpy((void *)((d)=(char*)p),(s),0,INT_MAX))\ 00204 :((d)=NULL)) 00205 00206 /* Solaris has broken memccpy - it considers last argument as signed */ 00207 00209 #define MSG_STRING_SIZE(s) ((s) ? (strlen(s) + 1) : 0) 00210 00211 SOFIAPUBFUN issize_t msg_commalist_d(su_home_t *, char **ss, 00212 msg_param_t **append_list, 00213 issize_t (*scanner)(char *s)); 00214 SOFIAPUBFUN issize_t msg_token_scan(char *start); 00215 SOFIAPUBFUN issize_t msg_attribute_value_scanner(char *s); 00216 00217 SOFIAPUBFUN issize_t msg_any_list_d(su_home_t *, char **ss, 00218 msg_param_t **append_list, 00219 issize_t (*scanner)(char *s), 00220 int sep); 00221 00223 #define MSG_COMMALIST_E(b, end, params, compact) do { \ 00224 char const * const *p_; char const * c_ = ""; \ 00225 for (p_ = (params); p_ && *p_; p_++, c_ = (compact ? "," : ", ")) \ 00226 { MSG_STRING_E(b, (end), c_); MSG_STRING_E(b, (end), *p_); } \ 00227 } while(0) 00228 00229 /* Parameter lists */ 00230 00231 SOFIAPUBFUN int msg_header_update_params(msg_common_t *h, int clear); 00232 00234 #define MSG_PARAM_MATCH(v, s, name) \ 00235 (strncasecmp(s, name "=", sizeof(name)) == 0 ? (v = s + sizeof(name)) : NULL) 00236 00238 #define MSG_PARAM_MATCH_P(v, s, name) \ 00239 ((strncasecmp((s), name "", sizeof(name) - 1) == 0 && \ 00240 ((s)[sizeof(name) - 1] == '=' || (s)[sizeof(name) - 1] == '\0')) ? \ 00241 ((v) = 1) : 0) 00242 00244 #define MSG_PARAMS_NUM(n) (((n) + MSG_N_PARAMS - 1) & (size_t)(0 - MSG_N_PARAMS)) 00245 00247 SOFIAPUBFUN issize_t msg_avlist_d(su_home_t *, char **ss, 00248 msg_param_t const **return_params); 00249 00251 SOFIAPUBFUN issize_t msg_params_d(su_home_t *, char **ss, 00252 msg_param_t const **return_params); 00253 00255 SOFIAPUBFUN isize_t msg_params_e(char b[], isize_t bsiz, msg_param_t const pparams[]); 00256 00258 SOFIAPUBFUN issize_t msg_params_join(su_home_t *, 00259 msg_param_t **dst, 00260 msg_param_t const *src, 00261 unsigned prune, 00262 int dup); 00263 00265 #define MSG_PARAMS_E(b, end, params, flags) \ 00266 (b) += msg_params_e((b), (size_t)((b) < (end) ? (end) - (b) : 0), (params)) 00267 00269 #define MSG_PARAMS_SIZE(rv, params) (rv = msg_params_dup_xtra(params, rv)) 00270 00272 SOFIAPUBFUN char *msg_params_dup(msg_param_t const **d, msg_param_t const *s, 00273 char *b, isize_t xtra); 00274 00276 su_inline isize_t msg_params_count(msg_param_t const params[]) 00277 { 00278 if (params) { 00279 size_t n; 00280 for (n = 0; params[n]; n++) 00281 ; 00282 return n; 00283 } 00284 else { 00285 return 0; 00286 } 00287 } 00288 00290 su_inline isize_t msg_params_dup_xtra(msg_param_t const params[], isize_t offset) 00291 { 00292 isize_t n = msg_params_count(params); 00293 if (n) { 00294 MSG_STRUCT_SIZE_ALIGN(offset); 00295 offset += MSG_PARAMS_NUM(n + 1) * sizeof(msg_param_t); 00296 for (n = 0; params[n]; n++) 00297 offset += strlen(params[n]) + 1; 00298 } 00299 return offset; 00300 } 00301 00303 su_inline void *msg_header_data(msg_frg_t *h) 00304 { 00305 if (h) 00306 return (char *)h + h->h_class->hc_size; 00307 else 00308 return NULL; 00309 } 00310 00311 SOFIA_END_DECLS 00312 00313 #endif