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

📄 msg_parser_util.c

📁 this is simple sip stack.
💻 C
📖 第 1 页 / 共 3 页
字号:
 * Parses a comma-separated list. The parsed string is passed in @a *ss, * which is updated to point to the first non-linear-whitespace character * after the list. The function modifies the string as it parses it. * * A pointer to the resulting list is returned in @a *retval. If there * already is a list in @a *retval, new items are appended. Empty list items * are ignored, and are not included in the list. * * The function can be passed an optional scanning function. The scanning * function scans for a legitimate list item, for example, a token. It also * compacts the list item, for instance, if the item consists of @c * name=value parameter definitions.  The scanning function returns the * length of the scanned item, including any linear whitespace after it. * * By default, the scanning function accepts tokens, quoted strings or * separators (except comma, of course). * * @param home    memory home used to allocate memory for list pointers [in] * @param ss      pointer to pointer to string to be parsed [in/out] * @param return_list  return-value parameter for parsed list [in/out] * @param scanner pointer to function scanning a single item (optional) [in] *  * @retval 0  if successful. * @retval -1 upon an error. */int msg_commalist_d(su_home_t *home, 		    char **ss, 		    msg_param_t **return_list,		    int (*scanner)(char *s)){  scanner = scanner ? scanner : msg_comma_scanner;  return msg_any_list_d(home, ss, return_list, scanner, ',');}/** Token scanner for msg_commalist_d() accepting also empty entries. */int msg_token_scan(char *start){  char *s = start;  skip_token(&s);  if (IS_LWS(*s))    *s++ = '\0';  skip_lws(&s);  return s - start;}/** Scan and compact a comma-separated item */staticint msg_comma_scanner(char *start){  int tlen;  char *s, *p;    s = p = start;  if (s[0] == ',')    return 0;  for (;;) {    /* Grab next section - token, quoted string, or separator character */    char c = *s;    if (IS_TOKEN(c))       tlen = span_token(s);    else if (c == '"')      tlen = span_quoted(s);    else /* if (IS_SEPARATOR(c)) */      tlen = 1;        if (tlen == 0)      return -1;    if (p != s)      memmove(p, s, tlen);	/* Move section to end of paramexter */    p += tlen; s += tlen;        skip_lws(&s);		/* Skip possible LWS */        if (*s == '\0' || *s == ',') {		/* Test for possible end */      if (p != s) *p = '\0';      return s - start;    }    if (IS_TOKEN(c) && IS_TOKEN(*s))      *p++ = ' ';		/* Two tokens must be separated by LWS */  }}/** Parse a comment. * * Parses a multilevel comment. The comment assigned to return-value * parameter @a return_comment is NUL-terminated. The string at return-value * parameter @a ss is updated to point to first non-linear-whitespace * character after the comment. */int msg_comment_d(char **ss, char const **return_comment){  /* skip comment */  int level = 1;  char *s = *ss;  assert(s[0] == '(');  if (*s != '(')    return -1;  *s++ = '\0';  if (return_comment)    *return_comment = s;        while (level) switch (*s++) {  case '(': level++; break;  case ')': level--; break;  case '\0': /* ERROR */ return -1;  }        assert(s[-1] == ')');        s[-1] = '\0';  skip_lws(&s);  *ss = s;  return 0;}/** Parse a quoted string */int msg_quoted_d(char **ss, char **return_quoted){  char *s = *ss;  int n = span_quoted(s);  if (n <= 0)    return -1;  *return_quoted = s;  s += n;  if (IS_LWS(*s)) {    *s++ = '\0';    skip_lws(&s);		/* skip linear whitespace */  }  *ss = s;  return 0;}#if 0/** Calculate length of string when quoted. */int msg_quoted_len(char const *u){  int rv;  if (!u)    return 0;  rv = span_token_lws(u);  if (u[rv]) {    /* We need to quote string */    int n;    int extra = 2; /* quote chars */    /* Find all characters to quote */    for (n = strcspn(u + rv, "\\\""); u[rv + n]; rv += n)      extra++;    rv += extra;  }  return rv;}#endif/**Parse @e host[":"port] pair. * * Parses a @e host[":"port] pair. The caller passes function a pointer to a * string via @a ss, and pointers to which parsed host and port are assigned * via @a hhost and @a pport, respectively. The value-result parameter @a * *pport must be initialized to default value (e.g., NULL). *  * @param ss    pointer to pointer to string to be parsed * @param return_host value-result parameter for @e host * @param return_port value-result parameter for @e port * @return  * Returns zero when successful, and a negative value upon an error. The * parsed values for host and port are assigned via @a return_host and @a * return_port, respectively. The function also updates the pointer @a *ss, * so if call is successful, the @a *ss points to first * non-linear-whitespace character after @e host[":"port] pair. * * @note * If there is no whitespace after @e port, the value in @a *pport may not be * NUL-terminated.  The calling function @b must NUL terminate the value by * setting the @a **ss to NUL after first examining its value. */int msg_hostport_d(char **ss, 		   char const **return_host, 		   char const **return_port){  char *host, *s = *ss;  char *port = NULL;  /* Host name */  host = s;   if (s[0] != '[') {    skip_token(&s); if (host == s) return -1;  }  else {    /* IPv6 */    int n = strspn(++s, HEX ":.");    if (s[n] != ']') return -1;    s += n + 1;  }  if (IS_LWS(*s)) { *s++ = '\0'; skip_lws(&s); }  if (s[0] == ':') {    unsigned long nport;    *s++ = '\0'; skip_lws(&s);    if (!IS_DIGIT(*s))      return -1;    port = s;    nport = strtoul(s, &s, 10);    if (nport > 65535)      return -1;    if (IS_LWS(*s)) {      *s++ = '\0';      skip_lws(&s);    }  }  *return_host = host;  *return_port = port;    *ss = s;  return 0;}/** Find a header parameter. * * Searches for given parameter @a name from the header. If parameter is * found, it returns a non-NULL pointer to the parameter value. If there is * no value for the name (in form "name" or "name=value"), the returned pointer * points to a NUL character. * * @param h     pointer to header structure * @param name  parameter name (with or without "=" sign) * * @return * A pointer to parameter value, or NULL if parameter was not found. */char const *msg_header_find_param(msg_common_t const *h, char const *name){  if (h && h->h_class->hc_params) {    msg_param_t const **params = (msg_param_t const **)      ((char *)h + h->h_class->hc_params);    return msg_params_find(*params, name);  }  return NULL;}/** Add a parameter to a header. *  * A header parameter @a param is a string of format name "=" value or just * name. The caller of msg_header_add_param() should have allocated it from * memory home associated with header @a h. * * @retval 0 if parameter was added * @retval -1 upon an error */int msg_header_add_param(su_home_t *home, msg_common_t *h, char const *param){  if (h && h->h_class->hc_params) {    int retval;    msg_param_t **params = (msg_param_t **)      ((char *)h + h->h_class->hc_params);    msg_fragment_clear(h);    retval = msg_params_add(home, params, param);    if (retval < 0)      return -1;    if (h->h_class->hc_update) {      size_t namelen;      char const *name, *value;      name = param;      namelen = strcspn(name, "=");      value = param + namelen + (name[namelen] == '=');      h->h_class->hc_update(h, name, namelen, value);    }    return retval;  }  return -1;}/** Replace or add a parameter to a header.  * * The shortcuts to parameter values are updated accordingly. * * @note This function @b does @b not duplicate @p param. * * @param home      memory home * @param h         pointer to a header * @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_header_replace_param(su_home_t *home, 			     msg_common_t *h, 			     char const *param){  if (h && h->h_class->hc_params) {    int retval;    msg_param_t **params = (msg_param_t **)      ((char *)h + h->h_class->hc_params);    msg_fragment_clear(h);    retval = msg_params_replace(home, params, param);    if (retval < 0)      return -1;    if (h->h_class->hc_update) {      size_t namelen;      char const *name, *value;      name = param;      namelen = strcspn(name, "=");      value = param + namelen + (name[namelen] == '=');      h->h_class->hc_update(h, name, namelen, value);    }    return retval;  }  return -1;}/** Remove a parameter from header. * * The parameter name is given as token optionally followed by "=" sign and * value. The "=" and value are ignored. * * @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 */int msg_header_remove_param(msg_common_t *h, char const *name){  if (h && h->h_class->hc_params) {    int retval;    msg_param_t **params = (msg_param_t **)      ((char *)h + h->h_class->hc_params);          retval = msg_params_remove(*params, name);    if (retval != 0)      msg_fragment_clear(h);    if (h->h_class->hc_update) {      size_t namelen;      namelen = strcspn(name, "=");      h->h_class->hc_update(h, name, namelen, NULL);    }    return retval;  }  return -1;}/** Update all parameters */int msg_header_update_params(msg_common_t *h, int clear){  int retval;  msg_param_t const *params;  size_t n;  char const *p, *v;  if (h == NULL)    return errno = EFAULT, -1;  if (h->h_class->hc_params == 0 ||      h->h_class->hc_update == NULL)    return 0;  if (clear)    h->h_class->hc_update(h, NULL, 0, NULL);  params = *(msg_param_t **)((char *)h + h->h_class->hc_params);  if (params == NULL)    return 0;  retval = 0;  for (p = *params; p; p = *++params) {    n = strcspn(p, "=");    v = p + n + (p[n] == '=');    if (h->h_class->hc_update(h, p, n, v) < 0)      retval = -1;  }  return retval;}/** 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) {    int 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, 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.  * * The parameter 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 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;  int i, n;  assert(inout_params);  if (param == NULL || param[0] == '=' || param[0] == '\0')    return -1;  params = *inout_params;  n = strcspn(param, "=");  assert(n > 0);  if (params) {    /* Existing list, try to replace or remove  */    for (i = 0; params[i]; i++) {      msg_param_t maybe = params[i];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -