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

📄 msg_parser_util.c

📁 Internet Phone, Chat, Conferencing
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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 int 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;  int 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. */int msg_token_d(char **ss, char const **return_token) {  char *s = *ss;  int n = span_token(s);  if (n) {    for (; IS_LWS(s[n]); n++)      s[n] = '\0';    *return_token = s;    *ss = s + n;    return 0;  }  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. */int 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 -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. * * A pointer to the resulting list is returned in the return-value parameter * @a return_list. If there already is a list in @a return_list, new items * are appended. Empty list items are ignored, and are not included in the * list. * * The function 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. The scanning function returns the * length of the scanned item, including any linear whitespace after it. * * @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 sep     separator character [IN] * @param scanner pointer to function scanning a single item (optional) [IN] *  * @retval 0  if successful. * @retval -1 upon an error. */int msg_any_list_d(su_home_t *home, 		   char **ss, 		   msg_param_t **return_list,		   int (*scanner)(char *s), 		   int sep){  char const *auto_list[MSG_N_PARAMS];  char const **list = auto_list, **re_list;  int N = MSG_N_PARAMS, n = 0, tlen;  char *s = *ss;  char const **start;  if (!scanner)    return -1;  if (*return_list) {    list = *return_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 == auto_list || list == *return_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 && list == auto_list) {    int size = sizeof(*list) * MSG_PARAMS_NUM(n + 1);    list = su_alloc(home, size);    if (!list) return -1;    memcpy((void *)list, auto_list, n * sizeof(*list));  }  list[n] = NULL;  if (n == 0)    list = NULL;  *return_list = list;  return 0; error:  *start = NULL;  if (list != auto_list && list != *return_list)    su_free(home, list);  return -1;}/** Scan an attribute [= value] pair  */int msg_attribute_value_scanner(char *s){  char *p = s;  unsigned 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 == '"') {      int 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 home      pointer to a memory home [IN] * @param ss        pointer to string at the start of parameter list [IN/OUT] * @param return_list return-value parameter for parsed list [IN/OUT] * * @retval 0 if successful * @retval -1 upon an error */int msg_avlist_d(su_home_t *home, 		 char **ss, 		 msg_param_t const **return_list){  char const *stack[MSG_N_PARAMS];  int N;  char const **params;  int n = 0;  char *s = *ss;  if (!*s)    return -1;  if (*return_list) {    params = (char const **)*return_list;    for (n = 0; params[n]; n++)      ;    N = MSG_PARAMS_NUM(n + 1);  } else {    params = stack;    N = MSG_PARAMS_NUM(1);  }    for (;;) {    char *p; int 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 == '"') {	int 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) {    int 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;  *return_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 home      pointer to a memory home [IN] * @param ss        pointer to string at the start of parameter list [IN/OUT] * @param return_list   return-value parameter for the parsed list [IN/OUT] * * @retval 0 if successful * @retval -1 upon an error * * @sa msg_avlist_d() */int msg_params_d(su_home_t *home, 		 char **ss, 		 msg_param_t const **return_list){  if (**ss == ';') {    *(*ss)++ = '\0';    *return_list = NULL;    return msg_avlist_d(home, ss, return_list);  }  if (IS_LWS(**ss)) {     *(*ss)++ = '\0'; skip_lws(ss);  }  return 0;}/** Encode a list of parameters */int msg_params_e(char b[], int bsiz, msg_param_t const pparams[]){  int i;  char *end = b + bsiz, *b0 = b;  msg_param_t p;  if (pparams)     for (i = 0; (p = pparams[i]); i++) {      if (p[0]) {	MSG_CHAR_E(b, end, ';');	MSG_STRING_E(b, end, p);      }    }  return b - b0;}/** Duplicate a parameter list */char *msg_params_dup(msg_param_t const **d, msg_param_t const s[],		     char *b, int xtra){  char *end = b + xtra;  char **pp;  int i, n;  n = msg_params_count(s);  if (n == 0) {    *d = NULL;    return b;  }  MSG_STRUCT_ALIGN(b);  pp = (char **)b;  b += sizeof(*pp) * MSG_PARAMS_NUM(n + 1);  for (i = 0; s[i]; i++) {    MSG_STRING_DUP(b, pp[i], s[i]);  }  pp[i] = NULL;   assert(b <= end);   *d = (msg_param_t const *)pp;  return b;} /** Parse a comma-separated list. *

⌨️ 快捷键说明

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