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

📄 msg_parser_util.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@ingroup msg_parser * @CFILE msg_parser_util.c * * Text-message parser helper functions. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Tue Aug 28 16:26:34 2001 ppessi * */#include "config.h"#include <stddef.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <assert.h>#include <limits.h>#include <stdarg.h>#include <sofia-sip/su_tagarg.h>#include <sofia-sip/su.h>#include <sofia-sip/su_alloc.h>#include "msg_internal.h"#include "sofia-sip/msg_parser.h"#include "sofia-sip/bnf.h"#include "sofia-sip/url.h"static issize_t msg_comma_scanner(char *start);/** * Parse first line. * * Splits the first line from a message into three whitespace-separated * parts. */int msg_firstline_d(char *s, char **return_part2, char **return_part3){  char *s1 = s, *s2, *s3;  size_t n;  /* Split line into three segments separated by whitespace */  if (s1[n = span_non_ws(s1)]) {    s1[n] = '\0';    s2 = s1 + n + 1;    while (IS_WS(*s2))      s2++;  }  else {    /* Hopeless - no WS in first line */    return -1;  }  n = span_non_ws(s2);  if (s2[n]) {    s2[n++] = '\0';    while (IS_WS(s2[n]))      n++;  }  s3 = s2 + n;  *return_part2 = s2;  *return_part3 = s3;  return 0;}/**Parse a token. * * Parses a token from string pointed by @a *ss. It stores the token value * in @a return_token, and updates the @a ss to the end of token and * possible whitespace. */issize_t msg_token_d(char **ss, char const **return_token) {  char *s = *ss;  size_t n = span_token(s);  if (n) {    for (; IS_LWS(s[n]); n++)      s[n] = '\0';    *return_token = s;    *ss = s + n;    return n;  }  else    return -1;}/** Parse a 32-bit unsigned int. * * The function msg_uint32_d() parses a 32-bit unsigned integer in string * pointed by @a *ss. It stores the value in @a return_token and updates the * @a ss to the end of integer and possible whitespace. * * @retval length of parsed integer, or -1 upon an error. */issize_t msg_uint32_d(char **ss, uint32_t *return_value){  char const *s = *ss, *s0 = s;  uint32_t value;  unsigned digit;  if (!IS_DIGIT(*s))	    return -1;  for (value = 0; IS_DIGIT(*s); s++) {    digit = *s - '0';    if (value > 429496729U)      return -1;    else if (value == 429496729U && digit > 5)      return -1;    value = 10 * value + digit;  }  if (*s) {    if (!IS_LWS(*s))      return (issize_t)-1;    skip_lws(&s);  }  *ss = (char *)s;  *return_value = value;  return s - s0;}/** Parse any list. * * Parses a list of items, separated by @a sep. 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. * * The parsed items are appended to the list @a *append_list. If there the * list in @a *append_list is NULL, allocate a new list and return it in @a * *append_list. Empty list items are ignored, and are not appended to the * list. * * The function @b must be passed a scanning function @a scanner. The * scanning function scans for a legitimate list item, for example, a token.  * It should also compact the list item, for instance, if the item consists * of @c name=value parameter definitions it should remove whitespace around * "=" sign. The scanning function returns the length of the scanned item, * including any linear whitespace after it. * * @param[in]     home    memory home for allocating list pointers  * @param[in,out] ss      pointer to pointer to string to be parsed  * @param[in,out] append_list  pointer to list *                             where parsed list items are appended * @param[in]     sep     separator character  * @param[in]     scanner pointer to function for scanning a single item *  * @retval 0  if successful. * @retval -1 upon an error. */issize_t msg_any_list_d(su_home_t *home, 			char **ss, 			msg_param_t **append_list,			issize_t (*scanner)(char *s), 			int sep){  char const *stack[MSG_N_PARAMS];  char const **list = stack, **re_list;  size_t N = MSG_N_PARAMS, n = 0;  issize_t tlen;  char *s = *ss;  char const **start;  if (!scanner)    return -1;  if (*append_list) {    list = *append_list;    while (list[n])      n++;    N = MSG_PARAMS_NUM(n + 1);  }  start = &list[n];  skip_lws(&s);  while (*s) {    tlen = scanner(s);    if (tlen < 0 || (s[tlen] && s[tlen] != sep && s[tlen] != ','))      goto error;    if (tlen > 0) {      if (n + 1 == N) {		/* Reallocate list? */	N = MSG_PARAMS_NUM(N + 1);	if (list == stack || list == *append_list) {	  re_list = su_alloc(home, N * sizeof(*list));	  if (re_list)	    memcpy(re_list, list, n * sizeof(*list));	}	else	  re_list = su_realloc(home, list, N * sizeof(*list));	if (!re_list)	  goto error;	list = re_list;      }            list[n++] = s;      s += tlen;    }    if (*s == sep) {      *s++ = '\0';      skip_lws(&s);    }     else if (*s)      break;  }  *ss = s;  if (n == 0) {    *append_list = NULL;    return 0;  }  if (list == stack) {    size_t size = sizeof(*list) * MSG_PARAMS_NUM(n + 1);    list = su_alloc(home, size);    if (!list) return -1;    memcpy((void *)list, stack, n * sizeof(*list));  }  list[n] = NULL;  *append_list = list;  return 0; error:  *start = NULL;  if (list != stack && list != *append_list)    su_free(home, list);  return -1;}/** Scan an attribute (name [= value]) pair. * * The attribute consists of name (a token) and optional value, separated by * equal sign. The value can be a token or quoted string. * * This function compacts the scanned value. It removes the * whitespace around equal sign "=" by moving the equal sign character and * value towards name. *  * If there is whitespace within the scanned value or after it,  * NUL-terminates the scanned attribute. * * @retval > 0 number of characters scanned,  *             including the whitespace within the value * @retval -1 upon an error */issize_t msg_attribute_value_scanner(char *s){  char *p = s;  size_t tlen;  skip_token(&s);  if (s == p)		/* invalid parameter name */    return -1;  tlen = s - p;  if (IS_LWS(*s)) { *s++ = '\0'; skip_lws(&s); }  if (*s == '=') {    char *v;    s++;    skip_lws(&s);    /* get value */    if (*s == '"') {      size_t qlen = span_quoted(s);      if (!qlen)	return -1;      v = s; s += qlen;    }    else {      v = s;       skip_param(&s);      if (s == v) 	return -1;    }    if (p + tlen + 1 != v) {      memmove(p + tlen + 1, v, s - v);      p[tlen] = '=';      p[tlen + 1 + (s - v)] = '\0';    }  }  if (IS_LWS(*s)) { *s++ = '\0'; skip_lws(&s); }  return s - p;}/**Parse an attribute-value list. * * Parses an attribute-value list, which has syntax as follows: * @code *  av-list = (av-pair *(";" av-pair) *  av-pair = token ["=" ( value / quoted-string) ]        ; optional value * @endcode * * @param[in]     home      pointer to a memory home  * @param[in,out] ss        pointer to string at the start of parameter list  * @param[in,out] append_list  pointer to list *                             where parsed list items are appended * * @retval >= 0 if successful * @retval -1 upon an error */issize_t msg_avlist_d(su_home_t *home, 		      char **ss, 		      msg_param_t const **append_list){  char const *stack[MSG_N_PARAMS];  char const **params;  size_t n = 0, N;  char *s = *ss;  if (!*s)    return -1;  if (*append_list) {    params = (char const **)*append_list;    for (n = 0; params[n]; n++)      ;    N = MSG_PARAMS_NUM(n + 1);  }  else {    params = stack;    N = MSG_PARAMS_NUM(1);  }    for (;;) {    char *p;    size_t tlen;    /* XXX - we should handle also quoted parameters */    skip_lws(&s);    p = s;    skip_token(&s);    tlen = s - p;    if (!tlen)		/* invalid parameter name */      goto error;    if (IS_LWS(*s)) { *s++ = '\0'; skip_lws(&s); }    if (*s == '=') {      char *v;      s++;      skip_lws(&s);      /* get value */      if (*s == '"') {	size_t qlen = span_quoted(s);	if (!qlen)	  goto error;	v = s; s += qlen;      }      else {	v = s; 	skip_param(&s);	if (s == v) 	  goto error;      }      if (p + tlen + 1 != v) {	p = memmove(v - tlen - 1, p, tlen);	p[tlen] = '=';      }    }    if (IS_LWS(*s)) { *s++ = '\0'; skip_lws(&s); }    if (n == N) {      /* Reallocate params */      char **nparams = su_alloc(home,				(N = MSG_PARAMS_NUM(N + 1)) * sizeof(*params));      if (!nparams) {	goto error;      }      params = memcpy(nparams, params, n * sizeof(*params));    }    params[n++] = p;    if (*s != ';')      break;    *s++ = '\0';  }  *ss = s;  if (params == stack) {    size_t size = sizeof(*params) * MSG_PARAMS_NUM(n + 1);    params = su_alloc(home, size);    if (!params) return -1;    memcpy((void *)params, stack, n * sizeof(*params));  }  else if (n == N) {    /* Reallocate params */    char **nparams = su_alloc(home, 			      (N = MSG_PARAMS_NUM(N + 1)) * sizeof(*params));    if (!nparams) {      goto error;    }    params = memcpy(nparams, params, n * sizeof(*params));  }  params[n] = NULL;  *append_list = params;  return 0; error:  if (params != stack)    su_free(home, params);  return -1;}/**Parse a semicolon-separated parameter list starting with semicolon. * * Parse a parameter list, which has syntax as follows: * @code *  *(";" token [ "=" (token | quoted-string)]). * @endcode * * @param[in]     home      pointer to a memory home  * @param[in,out] ss        pointer to string at the start of parameter list  * @param[in,out] append_list  pointer to list *                             where parsed list items are appended * * @retval >= 0 if successful * @retval -1 upon an error * * @sa msg_avlist_d() */issize_t msg_params_d(su_home_t *home, 		      char **ss, 		      msg_param_t const **append_list){  if (**ss == ';') {    *(*ss)++ = '\0';    *append_list = NULL;    return msg_avlist_d(home, ss, append_list);  }  if (IS_LWS(**ss)) {     *(*ss)++ = '\0'; skip_lws(ss);  }  return 0;}/** Encode a list of parameters */isize_t msg_params_e(char b[], isize_t bsiz, msg_param_t const pparams[]){  int i;

⌨️ 快捷键说明

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