📄 msg_mime.c
字号:
return msg_payload_e(b, bsiz, h, flags);}/** Calculate extra size of a multipart */int msg_multipart_dup_xtra(msg_header_t const *h, int offset){ msg_multipart_t const *mp = (msg_multipart_t *)h; msg_header_t const **hh; offset = msg_payload_dup_xtra(h, offset); for (hh = (msg_header_t const **)&mp->mp_content_type; hh <= (msg_header_t const **)&mp->mp_close_delim; hh++) { for (h = *hh; h; h = h->sh_next) { MSG_STRUCT_SIZE_ALIGN(offset); offset = h->sh_class->hc_dxtra(h, offset + h->sh_class->hc_size); } } return offset;}/** Duplicate one msg_multipart_t object */char *msg_multipart_dup_one(msg_header_t *dst, msg_header_t const *src, char *b, int xtra){ msg_multipart_t const *mp = (msg_multipart_t *)src; msg_header_t *h, **hh; char *end = b + xtra; b = msg_payload_dup_one(dst, src, b, xtra); for (hh = (msg_header_t **)&mp->mp_content_type; hh <= (msg_header_t **)&mp->mp_close_delim; hh++) { for (h = *hh; h; h = h->sh_next) { MSG_STRUCT_ALIGN(b); dst = (msg_header_t *)b; memset(dst, 0, sizeof dst->sh_common); dst->sh_class = h->sh_class; b = h->sh_class->hc_dup_one(dst, h, b + h->sh_class->hc_size, end - b); if (h->sh_class->hc_update) msg_header_update_params(h->sh_common, 0); assert(b <= end); } } return b;}#if 0msg_hclass_t msg_multipart_class[] =MSG_HEADER_CLASS(msg_, multipart, NULL, "", mp_common, append, msg_multipart);#endif/**Calculate Q value. * * The function msg_q_value() converts q-value string @a q to numeric value * in range (0..1000). Q values are used, for instance, to describe * relative priorities of registered contacts. * * @param q q-value string ("1" | "." 1,3DIGIT) * * @return * The function msg_q_value() returns an integer in range 0 .. 1000. */unsigned msg_q_value(char const *q){ unsigned value = 0; if (!q) return 500; if (q[0] != '0' && q[0] != '.' && q[0] != '1') return 500; while (q[0] == '0') q++; if (q[0] >= '1' && q[0] <= '9') return 1000; if (q[0] == '\0') return 0; if (q[0] != '.') /* Garbage... */ return 500; if (q[1] >= '0' && q[1] <= '9') { value = (q[1] - '0') * 100; if (q[2] >= '0' && q[2] <= '9') { value += (q[2] - '0') * 10; if (q[3] >= '0' && q[3] <= '9') { value += (q[3] - '0'); if (q[4] > '5' && q[4] <= '9') /* Round upwards */ value += 1; else if (q[4] == '5') value += value & 1; /* Round to even */ } } } return value;}/** Parse media type (type/subtype). * * The function msg_mediatype_d() parses a mediatype string. * * @param ss string to be parsed [IN/OUT] * @param type value result for media type [OUT] * * @retval 0 when successful, * @retval -1 upon an error. */int msg_mediatype_d(char **ss, char const **type){ char *s = *ss; char const *result = s; int l1 = 0, l2 = 0, n; /* Media type consists of two tokens, separated by / */ l1 = span_token(s); for (n = l1; IS_LWS(s[n]); n++); if (s[n] == '/') { for (n++; IS_LWS(s[n]); n++); l2 = span_token(s + n); n += l2; } if (l1 == 0 || l2 == 0) return -1; /* If there is extra ws between tokens, compact version */ if (n > l1 + 1 + l2) { s[l1] = '/'; memmove(s + l1 + 1, s + n - l2, l2); s[l1 + 1 + l2] = 0; } s += n; while (IS_WS(*s)) *s++ = '\0'; *ss = s; if (type) *type = result; return 0;}/* ====================================================================== *//**@ingroup msg_mime * @defgroup msg_accept Accept Header * * The @b Accept request-header field can be used to specify certain media * types which are acceptable for the response. Its syntax is defined in * [H14.1, S20.1] as follows: * * @code * Accept = "Accept" ":" #( media-range [ accept-params ] ) * * media-range = ( "*" "/" "*" * | ( type "/" "*" ) * | ( type "/" subtype ) ) *( ";" parameter ) * * accept-params = ";" "q" "=" qvalue *( accept-extension ) * * accept-extension = ";" token [ "=" ( token | quoted-string ) ] * @endcode * *//**@ingroup msg_accept * @typedef typedef struct msg_accept_s msg_accept_t; * * The structure msg_accept_t contains representation of an @b Accept * header. * * The msg_accept_t is defined as follows: * @code * typedef struct msg_accept_s { * msg_common_t ac_common[1]; // Common fragment info * msg_accept_t *ac_next; // Pointer to next Accept header * char const *ac_type; // Pointer to type/subtype * char const *ac_subtype; // Points after first slash in type * msg_param_t const *ac_params; // List of parameters * msg_param_t ac_q; // Value of q parameter * } msg_accept_t; * @endcode */msg_hclass_t msg_accept_class[] =MSG_HEADER_CLASS(msg_, accept, "Accept", "", ac_params, apndlist, msg_accept, msg_accept);int msg_accept_d(su_home_t *home, msg_header_t *h, char *s, int slen){ msg_header_t **hh = &h->sh_succ, *h0 = h; msg_accept_t *ac = (msg_accept_t *)h; assert(h); assert(sizeof(*h)); for (;*s;) { /* Ignore empty entries (comma-whitespace) */ if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; } if (!h) { /* Allocate next header structure */ if (!(h = msg_header_alloc(home, h0->sh_class, 0))) break; *hh = h; h->sh_prev = hh; hh = &h->sh_succ; ac = ac->ac_next = (msg_accept_t*)h; } /* "Accept:" #(type/subtyp ; *(parameters))) */ if (msg_mediatype_d(&s, &ac->ac_type) == -1) return -1; if (!(ac->ac_subtype = strchr(ac->ac_type, '/'))) return -1; ac->ac_subtype++; if (*s == ';' && msg_params_d(home, &s, &ac->ac_params) == -1) return -1; if (*s != '\0' && *s != ',') return -1; if (ac->ac_params) msg_header_update_params(ac->ac_common, 0); h = NULL; } /* Note: empty Accept list is not an error */ if (h) { msg_accept_t *ac = (msg_accept_t *)h; ac->ac_type = ac->ac_subtype = ""; } return 0;}int msg_accept_e(char b[], int bsiz, msg_header_t const *h, int flags){ char *b0 = b, *end = b + bsiz; msg_accept_t const *ac = (msg_accept_t *)h; assert(msg_is_accept(h)); if (ac->ac_type) { MSG_STRING_E(b, end, ac->ac_type); MSG_PARAMS_E(b, end, ac->ac_params, flags); } MSG_TERM_E(b, end); return b - b0;}int msg_accept_dup_xtra(msg_header_t const *h, int offset){ int rv = offset; msg_accept_t const *ac = (msg_accept_t *)h; if (ac->ac_type) { MSG_PARAMS_SIZE(rv, ac->ac_params); rv += MSG_STRING_SIZE(ac->ac_type); } return rv;}/** Duplicate one msg_accept_t object */char *msg_accept_dup_one(msg_header_t *dst, msg_header_t const *src, char *b, int xtra){ msg_accept_t *ac = (msg_accept_t *)dst; msg_accept_t const *o = (msg_accept_t *)src; char *end = b + xtra; if (o->ac_type) { b = msg_params_dup(&ac->ac_params, o->ac_params, b, xtra); MSG_STRING_DUP(b, ac->ac_type, o->ac_type); if ((ac->ac_subtype = strchr(ac->ac_type, '/'))) ac->ac_subtype++; } assert(b <= end); return b;}/** Update parameter(s) for Accept header. */ int msg_accept_update(msg_common_t *h, char const *name, int namelen, char const *value){ msg_accept_t *ac = (msg_accept_t *)h; if (name == NULL) { ac->ac_q = NULL; } else if (namelen == 1 && strncasecmp(name, "q", 1) == 0) { /* XXX - check for invalid value? */ ac->ac_q = value; } return 0;}/* ====================================================================== *//** Decode an Accept-* header. */int msg_accept_any_d(su_home_t *home, msg_header_t *h, char *s, int slen){ /** @relates msg_accept_any_s */ msg_header_t **hh = &h->sh_succ, *h0 = h; msg_accept_any_t *aa = (msg_accept_any_t *)h; assert(h); assert(h->sh_class); for (;*s;) { /* Ignore empty entries (comma-whitespace) */ if (*s == ',') { *s++ = '\0'; skip_lws(&s); continue; } if (!h) { /* Allocate next header structure */ if (!(h = msg_header_alloc(home, h0->sh_class, 0))) break; /* Append to sh_succ and aa_next */ *hh = h, h->sh_prev = hh, hh = &h->sh_succ; aa = aa->aa_next = (msg_accept_any_t *)h; } /* "Accept-*:" 1#(token *(SEMI accept-param)) */ if (msg_token_d(&s, &aa->aa_value) == -1) return -1; if (*s == ';' && msg_params_d(home, &s, &aa->aa_params) == -1) return -1; if (*s != '\0' && *s != ',') return -1; if (aa->aa_params) msg_header_update_params(aa->aa_common, 0); h = NULL; } if (h) return -2; return 0;}/** Encode an Accept-* header. */int msg_accept_any_e(char b[], int bsiz, msg_header_t const *h, int f){ /** @relates msg_accept_any_s */ char *b0 = b, *end = b + bsiz; msg_accept_any_t const *aa = (msg_accept_any_t *)h; MSG_STRING_E(b, end, aa->aa_value); MSG_PARAMS_E(b, end, aa->aa_params, flags); MSG_TERM_E(b, end); return b - b0;}/** Calculate extra memory used by accept-* headers. */int msg_accept_any_dup_xtra(msg_header_t const *h, int offset){ /** @relates msg_accept_any_s */ int rv = offset; msg_accept_any_t const *aa = (msg_accept_any_t *)h; MSG_PARAMS_SIZE(rv, aa->aa_params); rv += MSG_STRING_SIZE(aa->aa_value); return rv;}/** Duplicate one msg_accept_any_t object. */char *msg_accept_any_dup_one(msg_header_t *dst, msg_header_t const *src, char *b, int xtra){ /** @relates msg_accept_any_s */ msg_accept_any_t *aa = (msg_accept_any_t *)dst; msg_accept_any_t const *o = (msg_accept_any_t *)src; char *end = b + xtra; b = msg_params_dup(&aa->aa_params, o->aa_params, b, xtra); MSG_STRING_DUP(b, aa->aa_value, o->aa_value); assert(b <= end); return b;}/** Update parameter(s) for Accept-* header. */ int msg_accept_any_update(msg_common_t *h, char const *name, int namelen, char const *value){ msg_accept_any_t *aa = (msg_accept_any_t *)h; if (name == NULL) { aa->aa_q = NULL; } else if (namelen == 1 && strncasecmp(name, "q", 1) == 0) { aa->aa_q = value; } return 0;}/* ====================================================================== *//**@ingroup msg_mime * @defgroup msg_accept_charset Accept-Charset Header * * The Accept-Charset header is similar to Accept, but restricts the * character set that are acceptable in the response. Its syntax is * defined in [H14.2] as follows: * * @code * Accept-Charset = "Accept-Charset" ":" * 1#( ( charset | "*" )[ ";" "q" "=" qvalue ] ) * @endcode * *//**@ingroup msg_accept_charset * @typedef typedef struct msg_accept_charset_s msg_accept_charset_t; * * The structure msg_accept_encoding_t contains representation of @b * Accept-Charset header. * * The msg_accept_charset_t is defined as follows: * @code * typedef struct { * msg_common_t aa_common[1]; // Common fragment info * msg_accept_any_t *aa_next; // Pointer to next Accept-Charset * char const *aa_value; // Charset * msg_param_t const *aa_params; // Parameter list * char const *aa_q; // Q-value * } msg_accept_charset_t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -