📄 msg_parser_util.c
字号:
if (strncasecmp(maybe, param, n) == 0) { if (maybe[n] == '=' || maybe[n] == 0) { params[i] = param; return 1; } } } } /* Not found on list */ return msg_params_add(home, inout_params, param);}/** Remove a parameter from a list. * * @retval 1 if parameter was removed * @retval 0 if parameter was not found * @retval -1 upon an error */int msg_params_remove(msg_param_t *params, msg_param_t param){ int i, n; if (!params || !param || !param[0]) return -1; n = strcspn(param, "="); assert(n > 0); for (i = 0; params[i]; i++) { msg_param_t maybe = params[i]; if (strncasecmp(maybe, param, n) == 0) { if (maybe[n] == '=' || maybe[n] == 0) { /* Remove */ do { params[i] = params[i + 1]; } while (params[i++]); return 1; } } } return 0;}/** Calculate number of parameters in a parameter list */size_t msg_params_length(char const * const * params){ size_t len; if (!params) return 0; for (len = 0; params[len]; len++) ; return len;}/** * Add a parameter to a list. * * Add a parameter to the list; the list must have been created by @c * msg_params_d() or by @c msg_params_dup() (or it may contain only @c * NULL). * * @note This function does not duplicate @p param. * * @param home memory home * @param inout_params pointer to pointer to parameter list * @param param parameter to be added * * @retval 0 if parameter was added * @retval -1 upon an error */int msg_params_add(su_home_t *home, msg_param_t **inout_params, msg_param_t param){ int n, m_before, m_after; msg_param_t *p = *inout_params; if (param == NULL) return -1; /* Count number of parameters */ for (n = 0; p && p[n]; n++) ; m_before = MSG_PARAMS_NUM(n + 1); m_after = MSG_PARAMS_NUM(n + 2); if (m_before != m_after || !p) { p = su_alloc(home, m_after * sizeof(*p)); assert(p); if (!p) return -1; if (n) memcpy(p, *inout_params, n * sizeof(*p)); *inout_params = p; } p[n] = param; p[n + 1] = NULL; return 0;}static int msg_param_prune(msg_param_t const d[], msg_param_t p, unsigned prune){ int i, nlen; if (prune == 1) nlen = strcspn(p, "="); else nlen = 0; for (i = 0; d[i]; i++) { if ((prune == 1 && strncasecmp(p, d[i], nlen) == 0 && (d[i][nlen] == '=' || d[i][nlen] == '\0')) || (prune == 2 && strcasecmp(p, d[i]) == 0) || (prune == 3 && strcmp(p, d[i]) == 0)) return 1; } return 0;}/**Join two parameter lists. * * The function @c msg_params_join() joins two parameter lists; the * first list must have been created by @c msg_params_d() or by @c * msg_params_dup() (or it may contain only @c NULL). * * @param home memory home * @param dst pointer to pointer to destination parameter list * @param src source list * @param prune prune duplicates * @param dup duplicate parameters in src list * * @par Pruning * <table> * <tr><td>0<td>do not prune</tr> * <tr><td>1<td>prune parameters with identical names</tr> * <tr><td>2<td>case-insensitive values</tr> * <tr><td>3<td>case-sensitive values</tr> * </table> * * @return * The function @c msg_params_join() returns 0 if successful, or a negative * value upon an error. */int msg_params_join(su_home_t *home, msg_param_t **dst, msg_param_t const *src, unsigned prune, int dup){ int n, m, n_before, n_after, pruned, total = 0; msg_param_t *d = *dst; if (prune > 3) return -1; if (src == NULL || *src == NULL) return 0; /* Count number of parameters */ for (n = 0; d && d[n]; n++) ; n_before = MSG_PARAMS_NUM(n + 1); for (m = 0, pruned = 0; src[m]; m++) { if (n > 0 && prune > 0 && msg_param_prune(d, src[m], prune)) { pruned++; if (prune > 1) continue; } if (dup) total += strlen(src[m]) + 1; } n_after = MSG_PARAMS_NUM(n + m - pruned + 1); if (n_before != n_after || !d) { d = su_alloc(home, n_after * sizeof(*d)); assert(d); if (!d) return -1; if (n) memcpy(d, *dst, n * sizeof(*d)); *dst = d; } for (m = 0; src[m]; m++) { if (pruned && msg_param_prune(d, src[m], prune)) { pruned--; if (prune > 1) continue; } if (dup) d[n++] = su_strdup(home, src[m]); /* XXX */ else d[n++] = src[m]; } d[n] = NULL; return 0;}/**Compare parameter lists. * * Compares parameter lists. * * @param a pointer to a parameter list * @param b pointer to a parameter list * * @retval an integer less than zero if @a is less than @a b * @retval an integer zero if @a match with @a b * @retval an integer greater than zero if @a is greater than @a b */int msg_params_cmp(char const * const a[], char const * const b[]){ int c; int nlen; if (a == NULL || b == NULL) return (a != NULL) - (b != NULL); for (;;) { if (*a == NULL || *b == NULL) return (*a != NULL) - (*b != NULL); nlen = strcspn(*a, "="); if ((c = strncasecmp(*a, *b, nlen))) return c; if ((c = strcmp(*a + nlen, *b + nlen))) return c; a++, b++; }}/** Unquote string * * Duplicates the string @a q in unquoted form. */char *msg_unquote_dup(su_home_t *home, char const *q){ char *d; int total, n, m; /* First, easy case */ if (q[0] == '"') q++; n = strcspn(q, "\"\\"); if (q[n] == '\0' || q[n] == '"') return su_strndup(home, q, n); /* Hairy case - backslash-escaped chars */ total = n; for (;;) { if (q[n] == '\0' || q[n] == '"' || q[n + 1] == '\0') break; m = strcspn(q + n + 2, "\"\\"); total += m + 1; n += m + 2; } if (!(d = su_alloc(home, total + 1))) return NULL; for (n = 0;;) { m = strcspn(q, "\"\\"); memcpy(d + n, q, m); n += m, q += m; if (q[0] == '\0' || q[0] == '"' || q[1] == '\0') break; d[n++] = q[1]; q += 2; } assert(total == n); d[n] = '\0'; return d;}/** Unquote string */char *msg_unquote(char *dst, char const *s){ int copy = dst != NULL; char *d = dst; if (*s++ != '"') return NULL; for (;;) { int n = strcspn(s, "\"\\"); if (copy) memmove(d, s, n); s += n; d += n; if (*s == '\0') return NULL; else if (*s == '"') { if (copy) *d = '\0'; return dst; } else { /* Copy quoted char */ if ((copy ? (*d++ = *++s) : *++s) == '\0') return NULL; s++; } }}/** Quote string */int msg_unquoted_e(char *b, int bsiz, char const *s){ char *begin = b; char *end = b + bsiz; if (b && b + 1 < end) *b = '"'; b++; for (;*s;) { int n = strcspn(s, "\"\\"); if (n == 0) { if (b && b + 2 < end) b[0] = '\\', b[1] = s[0]; b += 2; s++; } else { if (b && b + n < end) memcpy(b, s, n); b += n; s += n; } } if (b && b + 1 < end) *b = '"'; b++; return b - begin;}/** Calculate a simple hash over a string. */unsigned long msg_hash_string(char const *id){ unsigned long hash = 0; if (id) for (; *id; id++) { hash += (unsigned)*id; hash *= 38501U; } else hash *= 38501U; if (hash == 0) hash = (unsigned long)-1; return hash;}/** Calculate the size of a duplicate of a header structure. */int msg_header_size(msg_header_t const *h){ if (h == NULL || h == MSG_HEADER_NONE) return 0; else return h->sh_class->hc_dxtra(h, h->sh_class->hc_size);}/** Encode a message to the buffer. * * The function msg_encode_e encodes a message to a given buffer. * It returns the length of the message to be encoded, even if the * buffer is too small (just like snprintf() is supposed to do). * * @param b buffer (may be NULL) * @param size size of buffer * @param mo public message structure (#sip_t, #http_t) * @param flags see # */int msg_object_e(char b[], int size, msg_pub_t const *mo, int flags){ int rv = 0, n; msg_header_t const *h; if (mo->msg_request) h = mo->msg_request; else h = mo->msg_status; for (; h; h = h->sh_succ) { n = msg_header_e(b, size, h, flags); if ((unsigned)n < (unsigned)size) b += n, size -= n; else b = NULL, size = 0; rv += n; } return rv;}/** Encode header contents. */int msg_header_field_e(char b[], int bsiz, msg_header_t const *h, int flags){ assert(h); assert(h->sh_class); return h->sh_class->hc_print(b, bsiz, h, flags);}/** Get offset of header @a h from structure @a mo. */msg_header_t **msg_header_offset(msg_t const *msg, msg_pub_t const *mo, msg_header_t const *h){ if (h == NULL || h->sh_class == NULL) return NULL; return msg_hclass_offset(msg->m_class, mo, h->sh_class);}/**Get a header from the public message structure. * * Gets a pointer to header from a message structure. * * @param pub public message structure from which header is obtained * @param hc header class */msg_header_t *msg_header_access(msg_pub_t const *pub, msg_hclass_t *hc){ msg_header_t * const * hh; if (pub == NULL || hc == NULL) return NULL; hh = msg_hclass_offset((void *)pub->msg_ident, (msg_pub_t *)pub, hc); if (hh) return *hh; else return NULL;}#include <sofia-sip/su_uniqueid.h>/** Generates a random token. * */int msg_random_token(char token[], int tlen, void const *rmemp, int rsize){ uint32_t random = 0, rword; uint8_t rbyte; uint8_t const *rmem = rmemp; int i, n; static char const token_chars[32] = /* Create aesthetically pleasing raNDom capS LooK */ "aBcDeFgHjKmNpQrStUvXyZ0123456789"; if (rmem == NULL && rsize == 0) rsize = UINT_MAX; if (rsize == 0) { if (token && tlen > 0) strcpy(token, "+"); return 1; } if (token == NULL) { if (rsize >= tlen * 5 / 8) return tlen; else return rsize / 5 * 8; } for (i = 0, n = 0; i < tlen;) { if (n < 5) { if (rsize == 0) ; else if (rmem) { rbyte = *rmem++, rsize--; random = random | (rbyte << n); n += 8; } else { rword = su_randint(0, UINT_MAX); random = (rword >> 13) & 31; n = 6; } } token[i] = token_chars[random & 31]; random >>= 5; i++, n -= 5; if (n < 0 || (n == 0 && rsize == 0)) break; } token[i] = 0; return i;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -