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

📄 msg_parser_util.c

📁 Internet Phone, Chat, Conferencing
💻 C
📖 第 1 页 / 共 3 页
字号:
      if (strncasecmp(maybe, param, n) == 0) {	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){  int 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 lenght of a parameter list */size_t msg_params_length(msg_param_t 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){  int 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){  int 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 * The function @c msg_params_join() returns 0 if successful, or a negative * value upon an error. */int msg_params_join(su_home_t *home,		    msg_param_t **dst,		    msg_param_t const *src,		    unsigned prune,		    int dup){  int 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;    }    if (dup)      d[n++] = su_strdup(home, src[m]);	/* XXX */    else      d[n++] = src[m];  }    d[n] = NULL;  return 0;}/**Compare parameter lists. *  * Compares parameter lists. * * @param a pointer to a parameter list * @param b pointer to a parameter list * * @retval an integer less than zero if @a is less than @a b * @retval an integer zero if @a match with @a b * @retval an integer greater than zero if @a is greater than @a b */int msg_params_cmp(msg_param_t const a[], msg_param_t const b[]){  int c;  int nlen;  if (a == NULL || b == NULL)    return (a != NULL) - (b != NULL);  for (;;) {    if (*a == NULL || *b == NULL)      return (*a != NULL) - (*b != NULL);    nlen = strcspn(*a, "=");    if ((c = strncasecmp(*a, *b, nlen)))      return c;    if ((c = strcmp(*a + nlen, *b + nlen)))      return c;    a++, b++;  }}/** Unquote string  * * Duplicates the string @a q in unquoted form. */char *msg_unquote_dup(su_home_t *home, char const *q){  char *d;  int total, n, m;  /* First, easy case */  if (q[0] == '"')    q++;  n = strcspn(q, "\"\\");  if (q[n] == '\0' || q[n] == '"')    return su_strndup(home, q, n);  /* Hairy case - backslash-escaped chars */  total = n;  for (;;) {    if (q[n] == '\0' || q[n] == '"' || q[n + 1] == '\0')      break;    m = strcspn(q + n + 2, "\"\\");    total += m + 1;    n += m + 2;   }  if (!(d = su_alloc(home, total + 1)))    return NULL;  for (n = 0;;) {    m = strcspn(q, "\"\\");    memcpy(d + n, q, m);     n += m, q += m;    if (q[0] == '\0' || q[0] == '"' || q[1] == '\0')      break;    d[n++] = q[1];     q += 2;  }  assert(total == n);  d[n] = '\0';    return d;}/** Unquote string */char *msg_unquote(char *dst, char const *s){  int copy = dst != NULL;  char *d = dst;  if (*s++ != '"')    return NULL;  for (;;) {    int n = strcspn(s, "\"\\");    if (copy)      memmove(d, s, n);    s += n;    d += n;    if (*s == '\0')      return NULL;    else if (*s == '"') {      if (copy) *d = '\0';      return dst;    }    else {      /* Copy quoted char */      if ((copy ? (*d++ = *++s) : *++s) == '\0')	return NULL;      s++;    }  }}/** Quote string */int msg_unquoted_e(char *b, int bsiz, char const *s){  char *begin = b;  char *end = b + bsiz;  if (b && b + 1 < end)    *b = '"';  b++;    for (;*s;) {    int n = strcspn(s, "\"\\");    if (n == 0) {      if (b && b + 2 < end)	b[0] = '\\', b[1] = s[0];      b += 2;      s++;    }    else {      if (b && b + n < end)	memcpy(b, s, n);      b += n;      s += n;    }  }  if (b && b + 1 < end)    *b = '"';  b++;  return b - begin;}/** Calculate a simple hash over a string. */unsigned long msg_hash_string(char const *id){  unsigned long hash = 0;  if (id)    for (; *id; id++) {      hash += (unsigned)*id;      hash *= 38501U;    }  else    hash *= 38501U;  if (hash == 0)    hash = (unsigned long)-1;    return hash;}/** Calculate the size of a duplicate of a header structure. */int msg_header_size(msg_header_t const *h){  if (h == NULL || h == MSG_HEADER_NONE)    return 0;  else    return h->sh_class->hc_dxtra(h, h->sh_class->hc_size);}/** Encode a message to the buffer.  * * The function msg_encode_e encodes a message to a given buffer. * It returns the length of the message to be encoded, even if the * buffer is too small (just like snprintf() is supposed to do). * * @param b        buffer (may be NULL) * @param size     size of buffer  * @param mo       public message structure (#sip_t, #http_t) * @param flags    see # */int msg_object_e(char b[], int size, msg_pub_t const *mo, int flags){  int rv = 0, n;  msg_header_t const *h;  if (mo->msg_request)    h = mo->msg_request;  else    h = mo->msg_status;  for (; h; h = h->sh_succ) {    n = msg_header_e(b, size, h, flags);    if ((unsigned)n < (unsigned)size)      b += n, size -= n;    else      b = NULL, size = 0;    rv += n;  }  return rv;}/** Encode header contents. */int msg_header_field_e(char b[], int bsiz, msg_header_t const *h, int flags){  assert(h); assert(h->sh_class);   return h->sh_class->hc_print(b, bsiz, h, flags);}/** Get offset of header @a h from structure @a mo. */msg_header_t **msg_header_offset(msg_t const *msg, msg_pub_t const *mo, msg_header_t const *h){  if (h == NULL || h->sh_class == NULL)     return NULL;  return msg_hclass_offset(msg->m_class, mo, h->sh_class);}/**Get a header from the public message structure. * * Gets a pointer to header from a message structure. * * @param pub public message structure from which header is obtained * @param hc  header class */msg_header_t *msg_header_access(msg_pub_t const *pub, msg_hclass_t *hc){  msg_header_t * const * hh;  if (pub == NULL || hc == NULL)    return NULL;  hh = msg_hclass_offset((void *)pub->msg_ident, (msg_pub_t *)pub, hc);  if (hh)    return *hh;  else     return NULL;}#include <sofia-sip/su_uniqueid.h>/** Generates a random token. * */int msg_random_token(char token[], int tlen, 		     void const *rmemp, int rsize){  uint32_t random = 0, rword;  uint8_t rbyte;  uint8_t const *rmem = rmemp;  int i, n;  static char const token_chars[32] =     /* Create aesthetically pleasing raNDom capS LooK */    "aBcDeFgHjKmNpQrStUvXyZ0123456789";  if (rmem == NULL && rsize == 0)    rsize = UINT_MAX;  if (rsize == 0) {    if (token && tlen > 0)      strcpy(token, "+");    return 1;  }  if (token == NULL) {    if (rsize >= tlen * 5 / 8)      return tlen;    else      return rsize / 5 * 8;  }      for (i = 0, n = 0; i < tlen;) {    if (n < 5) {      if (rsize == 0)	;      else if (rmem) {	rbyte = *rmem++, rsize--;	random = random | (rbyte << n);	n += 8;      } else {	rword = su_randint(0, UINT_MAX);	random = (rword >> 13) & 31;	n = 6;      }    }    token[i] = token_chars[random & 31];    random >>= 5;    i++, n -= 5;    if (n < 0 || (n == 0 && rsize == 0))      break;  }    token[i] = 0;  return i;}

⌨️ 快捷键说明

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