📄 msg_parser_util.c
字号:
*/int msg_header_replace_param(su_home_t *home, msg_common_t *h, char const *param){ return msg_header_param_modify(home, h, param, 0 /* case-insensitive name=value */, 0 /* replace */);}/** Remove a parameter from header. * * The parameter name is given as token optionally followed by "=" sign and * value. The "=" and value after it are ignored when selecting a parameter * to remove. * * The possible shortcuts to parameter values are updated. For example, the * "received" parameter in @Via header has shortcut in structure #sip_via_t, * the @ref sip_via_s::v_received "v_received" field. The shortcut to * removed parameter would be set to NULL. * * @param h pointer to a header * @param name name of parameter to be removed * * @retval 1 if a parameter was removed * @retval 0 if no parameter was not removed * @retval -1 upon an error * * @sa msg_header_add_param(), msg_header_replace_param(), * msg_header_update_params(), * #msg_common_t, #msg_header_t, * #msg_hclass_t, msg_hclass_t::hc_params, msg_hclass_t::hc_update */int msg_header_remove_param(msg_common_t *h, char const *name){ return msg_header_param_modify(NULL, h, name, 0 /* case-insensitive name=value */, -1 /* remove */);}/** Update shortcuts to parameter values. * * Update the shortcuts to parameter values in parameter list. For example, * the "received" parameter in @Via header has shortcut in structure * #sip_via_t, the @ref sip_via_s::v_received "v_received" field. The * shortcut is usully a pointer to the parameter value. If the parameter was * "received=127.0.0.1" the @ref sip_via_s::v_received "v_received" field * would be a pointer to "127.0.0.1". If the parameter was "received=" or * "received", the shortcut would be a pointer to an empty string, "". * * @retval 0 when successful * @retval -1 upon an error * * @sa msg_header_add_param(), msg_header_replace_param(), * msg_header_update_params(), * #msg_common_t, #msg_header_t, * #msg_hclass_t, msg_hclass_t::hc_params, msg_hclass_t::hc_update */int msg_header_update_params(msg_common_t *h, int clear){ msg_hclass_t *hc; unsigned char offset; msg_update_f *update; int retval; msg_param_t const *params; size_t n; char const *p, *v; if (h == NULL) return errno = EFAULT, -1; hc = h->h_class; offset = hc->hc_params; update = hc->hc_update; if (offset == 0 || update == NULL) return 0; if (clear) update(h, NULL, 0, NULL); params = *(msg_param_t **)((char *)h + offset); if (params == NULL) return 0; retval = 0; for (p = *params; p; p = *++params) { n = strcspn(p, "="); v = p + n + (p[n] == '='); if (update(h, p, n, v) < 0) retval = -1; } return retval;}/** Find a header item. * * Searches for given item @a name from the header. If item is found, the * function returns a non-NULL pointer to the item. * * @param h pointer to header structure * @param item item * * @return * A pointer to item, or NULL if it was not found. * * @since New in @VERSION_1_12_4 * * @sa msg_header_replace_item(), msg_header_remove_item(), * @Allow, @AllowEvents */char const *msg_header_find_item(msg_common_t const *h, char const *item){ if (h && h->h_class->hc_params) { char const * const * items = *(char const * const * const *) ((char *)h + h->h_class->hc_params); if (items) for (; *items; items++) { if (strcmp(item, *items) == 0) { return *items; } } } return NULL;}/**Add an item to a header. * * This function treats a #msg_header_t as set of C strings. The @a item is * a C string. If no identical string is found from the list, it is added to * the list. * * The shortcuts, if any, to item values are updated accordingly. * * @param home memory home used to re-allocate list in header * @param h pointer to a header * @param item item to be removed * * @retval 0 if item was added * @retval 1 if item was replaced * @retval -1 upon an error * * @since New in @VERSION_1_12_4. * * @sa msg_header_remove_item(), @Allow, @AllowEvents, * msg_header_replace_param(), msg_header_remove_param(), * #msg_common_t, #msg_header_t, #msg_list_t * #msg_hclass_t, msg_hclass_t::hc_params */int msg_header_replace_item(su_home_t *home, msg_common_t *h, char const *item){ return msg_header_param_modify(home, h, item, 1 /* string item */, 0 /* replace */);}/**Remove an item from a header. * * This function treats a #msg_header_t as set of C strings. The @a item is a * C string. If identical string is found from the list, it is removed. * * The shortcuts, if any, to item values are updated accordingly. * * @param h pointer to a header * @param name item to be removed * * @retval 0 if item was added * @retval 1 if item was replaced * @retval -1 upon an error * * @since New in @VERSION_1_12_4. * * @sa msg_header_replace_item(), @Allow, @AllowEvents, * msg_header_replace_param(), msg_header_remove_param(), * #msg_common_t, #msg_header_t, #msg_list_t * #msg_hclass_t, msg_hclass_t::hc_params */int msg_header_remove_item(msg_common_t *h, char const *name){ return msg_header_param_modify(NULL, h, name, 1 /* item */, -1 /* remove */);}/** Find a parameter from a parameter list. * * Searches for given parameter @a token from the parameter list. If * parameter is found, it returns a non-NULL pointer to the parameter value. * If there is no value for the parameter (the parameter is of form "name" * or "name="), the returned pointer points to a NUL character. * * @param params list (or vector) of parameters * @param token parameter name (with or without "=" sign) * * @return * A pointer to parameter value, or NULL if parameter was not found. */msg_param_t msg_params_find(msg_param_t const params[], msg_param_t token){ if (params && token) { size_t i, n = strcspn(token, "="); assert(n > 0); for (i = 0; params[i]; i++) { msg_param_t param = params[i]; if (strncasecmp(param, token, n) == 0) { if (param[n] == '=') return param + n + 1; else if (param[n] == 0) return param + n; } } } return NULL;}/** Find a slot for parameter from a parameter list. * * Searches for given parameter @a token from the parameter list. If * parameter is found, it returns a non-NULL pointer to the item containing * the parameter. * * @param params list (or vector) of parameters * @param token parameter name (with or without "=" sign) * * @return * A pointer to parameter slot, or NULL if parameter was not found. */msg_param_t *msg_params_find_slot(msg_param_t params[], msg_param_t token){ if (params && token) { int i; size_t n = strlen(token); assert(n > 0); for (i = 0; params[i]; i++) { msg_param_t param = params[i]; if (strncasecmp(param, token, n) == 0) { if (param[n] == '=') return params + i; else if (param[n] == 0 || token[n - 1] == '=') return params + i; } } } return NULL;}/** Replace or add a parameter from a list. * * A non-NULL parameter list must have been created by msg_params_d() * or by msg_params_dup(). * * @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 replaced or added * * @retval 0 if parameter was added * @retval 1 if parameter was replaced * @retval -1 upon an error */int msg_params_replace(su_home_t *home, msg_param_t **inout_params, msg_param_t param){ msg_param_t *params; size_t i, n; assert(inout_params); if (param == NULL || param[0] == '=' || param[0] == '\0') return -1; params = *inout_params; n = strcspn(param, "="); if (params) { /* Existing list, try to replace or remove */ for (i = 0; params[i]; i++) { msg_param_t maybe = params[i]; if (!(strncasecmp(maybe, param, n))) { 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){ size_t 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){ size_t 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){ size_t 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 * @retval >= 0 when successful * @retval -1 upon an error */issize_t msg_params_join(su_home_t *home, msg_param_t **dst, msg_param_t const *src, unsigned prune, int dup){ size_t 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -