⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msg_parser_util.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 4 页
字号:
 */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 + -