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

📄 su_taglist.c

📁 Sofia SIP is an open-source SIP User-Agent library, compliant with the IETF RFC3261 specification.
💻 C
📖 第 1 页 / 共 3 页
字号:
/**Filter a tag list.  *  * The function tl_afilter() will build a tag list containing tags specified * in @a filter and extracted from @a src.  It will allocate the memory used by * tag list via the specified memory @a home, which may be also @c NULL. * * @sa tl_afilter(), tl_tfilter(), tl_filtered_tlist(),  * TAG_FILTER(), TAG_ANY(), #ns_tag_class */tagi_t *tl_afilter(su_home_t *home, tagi_t const filter[], tagi_t const src[]){  tagi_t *dst, *d, *t_end = NULL;  void *b, *end = NULL;  size_t len;  /* Calculate length of the result */  t_end = tl_filter(NULL, filter, src, &end);  len = ((char *)t_end - (char *)NULL) + ((char *)end - (char*)NULL);  if (len == 0)    return NULL;  /* Allocate the result */  if (!(dst = su_alloc(home, len)))    return NULL;  /* Build the result */  b = (dst + (t_end - (tagi_t *)NULL));  d = tl_filter(dst, filter, src, (void **)&b);  /* Ensure that everything is consistent */  assert(d == dst + (t_end - (tagi_t *)NULL));  assert(b == (char *)dst + len);  return dst;}/** Filter tag list @a src with given tags. *  * @sa tl_afilter(), tl_filtered_tlist(), TAG_FILTER(), TAG_ANY(), #ns_tag_class */tagi_t *tl_tfilter(su_home_t *home, tagi_t const src[], 		   tag_type_t tag, tag_value_t value, ...){  tagi_t *tl;  ta_list ta;  ta_start(ta, tag, value);  tl = tl_afilter(home, ta_args(ta), src);  ta_end(ta);  return tl;}/** Create a filtered tag list. * * @sa tl_afilter(), tl_tfilter(), TAG_FILTER(), TAG_ANY(), #ns_tag_class */tagi_t *tl_filtered_tlist(su_home_t *home, tagi_t const filter[], 			  tag_type_t tag, tag_value_t value, ...){  tagi_t *tl;  ta_list ta;  ta_start(ta, tag, value);  tl = tl_afilter(home, filter, ta_args(ta));  ta_end(ta);  return tl;}/** Remove listed tags from the list @a lst. */int tl_tremove(tagi_t lst[], tag_type_t tag, tag_value_t value, ...){  tagi_t *l, *l_next;  int retval = 0;  ta_list ta;  ta_start(ta, tag, value);  for (l = lst; l; l = l_next) {    if ((l_next = (tagi_t *)t_next(l))) {      if (tl_find(ta_args(ta), l->t_tag))	l->t_tag = tag_skip;      else	retval++;    }  }  ta_end(ta);  return retval;}/** Calculate length of a tag list with a @c va_list. */size_t tl_vlen(va_list ap){  size_t len = 0;  tagi_t tagi[2] = {{ NULL }};  do {    tagi->t_tag = va_arg(ap, tag_type_t );    tagi->t_value = va_arg(ap, tag_value_t);    len += sizeof(tagi_t);  } while (!t_end(tagi));  return len;}/** Convert va_list to tag list */tagi_t *tl_vlist(va_list ap){  tagi_t *t, *rv;  va_list aq;  va_copy(aq, ap);  rv = malloc(tl_vlen(aq));  va_end(aq);  for (t = rv; t; t++) {    t->t_tag = va_arg(ap, tag_type_t);    t->t_value = va_arg(ap, tag_value_t);    if (t_end(t))      break;  }  return rv;}tagi_t *tl_vlist2(tag_type_t tag, tag_value_t value, va_list ap){  tagi_t *t, *rv;  tagi_t tagi[1];  size_t size;  tagi->t_tag = tag, tagi->t_value = value;  if (!t_end(tagi)) {    va_list aq;    va_copy(aq, ap);    size = sizeof(tagi) + tl_vlen(aq);    va_end(aq);  }  else    size = sizeof(tagi);  t = rv = malloc(size);  for (;t;) {    *t++ = *tagi;    if (t_end(tagi))       break;    tagi->t_tag = va_arg(ap, tag_type_t);    tagi->t_value = va_arg(ap, tag_value_t);  }    assert((char *)rv + size == (char *)t);  return rv;}/** Make a tag list until TAG_NEXT() or TAG_END() */tagi_t *tl_list(tag_type_t tag, tag_value_t value, ...){  va_list ap;    tagi_t *t;  va_start(ap, value);  t = tl_vlist2(tag, value, ap);  va_end(ap);  return t;}/** Calculate length of a linear tag list. */size_t tl_vllen(tag_type_t tag, tag_value_t value, va_list ap){  size_t len = sizeof(tagi_t);  tagi_t const *next;  tagi_t tagi[3];  tagi[0].t_tag = tag;  tagi[0].t_value = value;  tagi[1].t_tag = tag_any;  tagi[1].t_value = 0;  for (;;) {    next = tl_next(tagi);    if (next != tagi + 1)      break;        if (tagi->t_tag != tag_skip)      len += sizeof(tagi_t);    tagi->t_tag = va_arg(ap, tag_type_t);    tagi->t_value = va_arg(ap, tag_value_t);  }  for (; next; next = tl_next(next))    len += sizeof(tagi_t);  return len;}/** Make a linear tag list. */tagi_t *tl_vllist(tag_type_t tag, tag_value_t value, va_list ap){  va_list aq;  tagi_t *t, *rv;  tagi_t const *next;  tagi_t tagi[2];  size_t size;  va_copy(aq, ap);  size = tl_vllen(tag, value, aq);  va_end(aq);  t = rv = malloc(size);  if (rv == NULL)    return rv;  tagi[0].t_tag = tag;  tagi[0].t_value = value;  tagi[1].t_tag = tag_any;  tagi[1].t_value = 0;  for (;;) {    next = tl_next(tagi);    if (next != tagi + 1)      break;    if (tagi->t_tag != tag_skip)      *t++ = *tagi;    tagi->t_tag = va_arg(ap, tag_type_t);    tagi->t_value = va_arg(ap, tag_value_t);  }  for (; next; next = tl_next(next))    *t++ = *next;  t->t_tag = NULL; t->t_value = 0; t++;  assert((char *)rv + size == (char *)t);  return rv;}/** Make a linear tag list until TAG_END(). * */tagi_t *tl_llist(tag_type_t tag, tag_value_t value, ...){  va_list ap;    tagi_t *t;  va_start(ap, value);  t = tl_vllist(tag, value, ap);  va_end(ap);  return t;}/** Free a tag list allocated by tl_list(), tl_llist() or tl_vlist(). */void tl_vfree(tagi_t *t){  if (t)    free(t);}/** Convert a string to the a value of a tag. */int t_scan(tag_type_t tt, su_home_t *home, char const *s, 	   tag_value_t *return_value){  if (tt == NULL || s == NULL || return_value == NULL)    return -1;  if (tt->tt_class->tc_scan) {    return tt->tt_class->tc_scan(tt, home, s, return_value);  }  else {			/* Not implemented */    *return_value = (tag_value_t)0;    return -2;  }}/* ====================================================================== *//* null tag */tagi_t const *t_null_next(tagi_t const *t){  return NULL;}tagi_t *t_null_move(tagi_t *dst, tagi_t const *src){  memset(dst, 0, sizeof(*dst));  return dst + 1;}tagi_t *t_null_dup(tagi_t *dst, tagi_t const *src, void **bb){  memset(dst, 0, sizeof(*dst));  return dst + 1;}tagi_t *t_null_copy(tagi_t *dst, tagi_t const *src, void **bb){  memset(dst, 0, sizeof(*dst));  return dst + 1;}tagi_t const * t_null_find(tag_type_t tt, tagi_t const lst[]){  return NULL;}tagi_t *t_null_filter(tagi_t *dst, 		      tagi_t const filter[], 		      tagi_t const *src, 		      void **bb){  if (TAG_TYPE_OF(src) == tag_null) {    if (dst) {      dst->t_tag = NULL;      dst->t_value = 0;    }    return dst + 1;  }  return dst;}tag_class_t null_tag_class[1] =   {{     sizeof(null_tag_class),     /* tc_next */     t_null_next,    /* tc_len */      NULL,    /* tc_move */     t_null_move,    /* tc_xtra */     NULL,    /* tc_dup */      t_null_dup,    /* tc_free */     NULL,    /* tc_find */     t_null_find,    /* tc_snprintf */ NULL,    /* tc_filter */   t_null_filter,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};tag_typedef_t tag_null = TAG_TYPEDEF(tag_null, null);/* ====================================================================== *//* end tag */tagi_t *t_end_filter(tagi_t *dst,		     tagi_t const filter[],		     tagi_t const *src,		     void **bb){  return dst;}tag_class_t end_tag_class[1] =  {{    sizeof(end_tag_class),    /* tc_next */     NULL,    /* tc_len */      NULL,    /* tc_move */     NULL,    /* tc_xtra */     NULL,    /* tc_dup */      NULL,    /* tc_free */     NULL,    /* tc_find */     NULL,    /* tc_snprintf */ NULL,    /* tc_filter */   t_end_filter,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};/* ====================================================================== *//* skip tag - placeholder in tag list */tagi_t const *t_skip_next(tagi_t const *t){  return t + 1;}tagi_t *t_skip_move(tagi_t *dst, tagi_t const *src){  return dst;}size_t t_skip_len(tagi_t const *t){  return 0;}tagi_t *t_skip_dup(tagi_t *dst, tagi_t const *src, void **bb){  return dst;}tagi_t *t_skip_filter(tagi_t *dst, 		    tagi_t const filter[], 		    tagi_t const *src, 		    void **bb){  return dst;}tag_class_t skip_tag_class[1] =   {{    sizeof(skip_tag_class),    /* tc_next */     t_skip_next,    /* tc_len */      t_skip_len,    /* tc_move */     t_skip_move,    /* tc_xtra */     NULL,    /* tc_dup */      t_skip_dup,    /* tc_free */     NULL,    /* tc_find */     t_null_find,    /* tc_snprintf */ NULL,    /* tc_filter */   t_skip_filter,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};tag_typedef_t tag_skip = TAG_TYPEDEF(tag_skip, skip);/* ====================================================================== *//* next tag - jump to next tag list */tagi_t const *t_next_next(tagi_t const *t){  return (tagi_t *)(t->t_value);}tagi_t *t_next_move(tagi_t *dst, tagi_t const *src){  if (!src->t_value)    return t_null_move(dst, src);  return dst;}size_t t_next_len(tagi_t const *t){  if (!t->t_value)    return sizeof(*t);  return 0;}tagi_t *t_next_dup(tagi_t *dst, tagi_t const *src, void **bb){  if (!src->t_value)    return t_null_dup(dst, src, bb);  return dst;}tagi_t *t_next_filter(tagi_t *dst, 		    tagi_t const filter[], 		    tagi_t const *src, 		    void **bb){  return dst;}tag_class_t next_tag_class[1] =   {{    sizeof(next_tag_class),    /* tc_next */     t_next_next,    /* tc_len */      t_next_len,    /* tc_move */     t_next_move,    /* tc_xtra */     NULL,    /* tc_dup */      t_next_dup,    /* tc_free */     NULL,    /* tc_find */     t_null_find,    /* tc_snprintf */ NULL,    /* tc_filter */   t_next_filter,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};tag_typedef_t tag_next = TAG_TYPEDEF(tag_next, next);/* ====================================================================== *//* filter tag  - use function to filter tag */tagi_t *t_filter_with(tagi_t *dst,		      tagi_t const *t, 		      tagi_t const *src, 		      void **bb){  tag_filter_f *function;  if (!src || !t)    return dst;  function = (tag_filter_f *)t->t_value;  if (!function || !function(t, src))    return dst;  if (dst) {    return t_dup(dst, src, bb);   }  else {    dst = (tagi_t *)((char *)dst + t_len(src));    *bb = (char *)*bb + t_xtra(src, (size_t)*bb);    return dst;  }}		   tag_class_t filter_tag_class[1] =   {{    sizeof(filter_tag_class),    /* tc_next */     NULL,    /* tc_len */      NULL,    /* tc_move */     NULL,    /* tc_xtra */     NULL,    /* tc_dup */      NULL,    /* tc_free */     NULL,    /* tc_find */     NULL,    /* tc_snprintf */ NULL,    /* tc_filter */   t_filter_with,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};/** Filter tag - apply function in order to filter tag. */tag_typedef_t tag_filter = TAG_TYPEDEF(tag_filter, filter);/* ====================================================================== *//* any tag - match to any tag when filtering */tagi_t *t_any_filter(tagi_t *dst,		     tagi_t const filter[], 		     tagi_t const *src, 		     void **bb)

⌨️ 快捷键说明

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