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

📄 msg_parser_util.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (dup)      d[n++] = su_strdup(home, src[m]);	/* XXX */    else      d[n++] = src[m];  }    d[n] = NULL;  return 0;}/**Join header item lists. * * Join items from a source header to the destination header. The item are * compared with the existing ones. If a match is found, it is not added to * the list. If @a duplicate is true, the entries are duplicated while they * are added to the list. * * @param home       memory home * @param dst        destination header * @param src        source header * @param duplicate  if true, allocate and copy items that are added * * @return * @retval >= 0 when successful * @retval -1 upon an error * * @NEW_1_12_5. */int msg_header_join_items(su_home_t *home,			  msg_common_t *dst,			  msg_common_t const *src,			  int duplicate){  size_t N, m, M, i, n_before, n_after, total;  char *dup = NULL;  msg_param_t *d, **dd, *s;  msg_param_t t, *temp, temp0[16];  size_t *len, len0[(sizeof temp0)/(sizeof temp0[0])];  msg_update_f *update = NULL;  if (dst == NULL || dst->h_class->hc_params == 0 ||      src == NULL || src->h_class->hc_params == 0)    return -1;  s = *(msg_param_t **)((char *)src + src->h_class->hc_params);  if (s == NULL)    return 0;  for (M = 0; s[M]; M++);  if (M == 0)    return 0;  if (M <= (sizeof temp0) / (sizeof temp0[0])) {    temp = temp0, len = len0;  }  else {    temp = malloc(M * (sizeof *temp) + M * (sizeof *len));    if (!temp) return -1;    len = (void *)(temp + M);  }  dd = (msg_param_t **)((char *)dst + dst->h_class->hc_params);  d = *dd;  for (N = 0; d && d[N]; N++);  for (m = 0, M = 0, total = 0; s[m]; m++) {    t = s[m];    for (i = 0; i < N; i++)      if (strcmp(t, d[i]) == 0)	break;    if (i < N)      continue;    for (i = 0; i < M; i++)      if (strcmp(t, temp[i]) == 0)	break;    if (i < M)      continue;    temp[M] = t;    len[M] = strlen(t);    total += len[M++] + 1;  }  if (M == 0)    goto success;  dup = su_alloc(home, total); if (!dup) goto error;  n_before = MSG_PARAMS_NUM(N + 1);  n_after = MSG_PARAMS_NUM(N + M + 1);  if (d == NULL || n_before != n_after) {    d = su_alloc(home, n_after * sizeof(*d)); if (!d) goto error;    if (N)      memcpy(d, *dd, N * sizeof(*d));    *dd = d;  }  update = dst->h_class->hc_update;  for (m = 0; m < M; m++) {    d[N++] = memcpy(dup, temp[m], len[m] + 1);        if (update)      update(dst, dup, len[m], dup + len[m]);    dup += len[m] + 1;  }    d[N] = NULL; success:  if (temp != temp0)    free(temp);  return 0; error:  if (temp != temp0)    free(temp);  su_free(home, dup);  return -1;}/**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(char const * const a[], char const * const b[]){  int c;  size_t 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;  size_t 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 (;;) {    size_t 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 */issize_t msg_unquoted_e(char *b, isize_t bsiz, char const *s){  char *begin = b;  char *end = b + bsiz;  if (b && b + 1 < end)    *b = '"';  b++;    for (;*s;) {    size_t 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. */isize_t 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 # */issize_t msg_object_e(char b[], isize_t size, msg_pub_t const *mo, int flags){  size_t rv = 0;  ssize_t 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 (n < 0)      return -1;    if ((size_t)n < size)      b += n, size -= n;    else      b = NULL, size = 0;    rv += n;  }  return rv;}/** Encode header contents. */issize_t msg_header_field_e(char b[], isize_t 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. * */issize_t msg_random_token(char token[], isize_t tlen, 			  void const *rmemp, isize_t rsize){  uint32_t random = 0, rword;  uint8_t rbyte;  uint8_t const *rmem = rmemp;  size_t i;  ssize_t n;  static char const token_chars[33] =     /* 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_random();	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;}/** Parse a message. * * Parse a text message with parser @a mc. The @a data is copied and it is * not modified or referenced by the parsed message. * * @par Example * Parse a SIP message fragment (e.g., payload of NOTIFY sent in response to * REFER): * @code * msg_t *m = msg_make(sip_default_mclass(), 0, pl->pl_data, pl->pl_len); * sip_t *frag = sip_object(m); * @endcode * * @param mc message class (parser table) * @param flags message flags (see #msg_flg_user) * @param data message text * @param len size of message text (if -1, use strlen(data)) *  * @retval A pointer to a freshly allocated and parsed message. * * Upon parsing error, the header structure may be left incomplete. The * #MSG_FLG_ERROR is set in @a msg_object(msg)->msg_flags. * * @since New in @VERSION_1_12_4 * * @sa msg_as_string(), msg_extract() */msg_t *msg_make(msg_mclass_t const *mc, int flags,		void const *data, ssize_t len){  msg_t *msg;  msg_iovec_t iovec[2];  if (len == -1)    len = strlen(data);  if (len == 0)     return NULL;  msg = msg_create(mc, flags);  if (msg == NULL)    return NULL;  su_home_preload(msg_home(msg), 1, len + 1024);  if (msg_recv_iovec(msg, iovec, 2, len, 1) < 0) {    perror("msg_recv_iovec");  }  assert((ssize_t)iovec->mv_len == len);  memcpy(iovec->mv_base, data, len);  msg_recv_commit(msg, len, 1);  if (msg_extract(msg) < 0)    msg->m_object->msg_flags |= MSG_FLG_ERROR;  return msg;}

⌨️ 快捷键说明

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