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

📄 su_taglist.c

📁 this is simple sip stack.
💻 C
📖 第 1 页 / 共 2 页
字号:
}/** 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];  int size;  va_copy(aq, ap);  size = tl_vllen(tag, value, aq);  va_end(aq);  t = rv = malloc(size);  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 {    *return_value = (tag_value_t)0;    return 0;  }}/* ====================================================================== *//* 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);/* ====================================================================== *//* 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){  if (!src)    return dst;  else 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 any_tag_class[1] =   {{    sizeof(any_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_any_filter,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};tag_typedef_t tag_any = TAG_TYPEDEF(tag_any, any);/* ====================================================================== *//* ns tag - match to any tag with same namespace when filtering */statictagi_t *t_ns_filter(tagi_t *dst,		    tagi_t const filter[], 		    tagi_t const *src, 		    void **bb){  char const *match, *ns;  if (!src)    return dst;  assert(filter);  match = TAG_TYPE_OF(filter)->tt_ns;  ns = TAG_TYPE_OF(src)->tt_ns;  if (match == NULL)    /* everything matches with this */;  else if (match == ns)    /* namespaces matche */;  else if (ns == NULL)    /* no match */    return dst;  else if (strcmp(match, ns))    /* no match */    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 ns_tag_class[1] =   {{    sizeof(any_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_ns_filter,    /* tc_ref_set */  NULL,    /* tc_scan */     NULL,  }};/* ====================================================================== *//* int tag - pass integer value */int t_int_snprintf(tagi_t const *t, char b[], size_t size){  return snprintf(b, size, "%i", (int)t->t_value);}int t_int_ref_set(tag_type_t tt, void *ref, tagi_t const value[]){  *(int *)ref = (int)value->t_value;  return 1;}int t_int_scan(tag_type_t tt, su_home_t *home, 	       char const *s, 	       tag_value_t *return_value){  int value;  char *rest;  value = strtol(s, &rest, 0);    if (s != rest) {    *return_value = (tag_value_t)value;    return 1;  }  else {    *return_value = (tag_value_t)0;    return -1;  }}tag_class_t int_tag_class[1] =   {{    sizeof(int_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 */ t_int_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_int_ref_set,    /* tc_scan */     t_int_scan,  }};/* ====================================================================== *//* uint tag - pass unsigned integer value */int t_uint_snprintf(tagi_t const *t, char b[], size_t size){  return snprintf(b, size, "%u", (unsigned)t->t_value);}int t_uint_ref_set(tag_type_t tt, void *ref, tagi_t const value[]){  *(unsigned *)ref = (unsigned)value->t_value;  return 1;}int t_uint_scan(tag_type_t tt, su_home_t *home, 	       char const *s, 	       tag_value_t *return_value){  unsigned value;  char *rest;  value = strtoul(s, &rest, 0);    if (s != rest) {    *return_value = (tag_value_t)value;    return 1;  }  else {    *return_value = (tag_value_t)0;    return -1;  }}tag_class_t uint_tag_class[1] =   {{    sizeof(int_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 */ t_uint_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_uint_ref_set,    /* tc_scan */     t_uint_scan,  }};/* ====================================================================== *//* bool tag - pass boolean value */int t_bool_snprintf(tagi_t const *t, char b[], size_t size){  return snprintf(b, size, "%s", t->t_value ? "true" : "false");}int t_bool_ref_set(tag_type_t tt, void *ref, tagi_t const value[]){  *(int *)ref = (value->t_value != 0);  return 1;}int t_bool_scan(tag_type_t tt, su_home_t *home, 	       char const *s, 	       tag_value_t *return_value){  int retval;  int value = 0;  if (strncasecmp(s, "true", 4) == 0       && strlen(s + 4) == strspn(s + 4, " \t\r\n")) {    value = 1, retval = 1;  } else if (strncasecmp(s, "false", 5) == 0 	     && strlen(s + 5) == strspn(s + 5, " \t\r\n")) {    value = 0, retval = 1;  } else {    retval = t_int_scan(tt, home, s, return_value);    value = *return_value != 0;  }  if (retval == 1)    *return_value = (tag_value_t)value;  else    *return_value = (tag_value_t)0;    return retval;}tag_class_t bool_tag_class[1] =   {{    sizeof(bool_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 */ t_bool_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_bool_ref_set,    /* tc_scan */     t_bool_scan,  }};/* ====================================================================== *//* ptr tag - pass pointer value */int t_ptr_snprintf(tagi_t const *t, char b[], size_t size){  return snprintf(b, size, "%p", (void *)t->t_value);}int t_ptr_ref_set(tag_type_t tt, void *ref, tagi_t const value[]){  *(void **)ref = (void *)value->t_value;  return 1;}/* This is not usually very safe, so it is not used */int t_ptr_scan(tag_type_t tt, su_home_t *home, 	       char const *s, 	       tag_value_t *return_value){  int retval;  void *ptr;  retval = sscanf(s, "%p", &ptr);  if (retval == 1)    *return_value = (tag_value_t)ptr;  else    *return_value = (tag_value_t)NULL;    return retval;}tag_class_t ptr_tag_class[1] =   {{    sizeof(ptr_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 */ t_ptr_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_ptr_ref_set,    /* tc_scan */     NULL,  }};/* ====================================================================== *//* str tag - pass string value */int t_str_snprintf(tagi_t const *t, char b[], size_t size){  if (t->t_value)     return snprintf(b, size, "\"%s\"", (char const *)t->t_value);  else    return snprintf(b, size, "<null>");}int t_str_scan(tag_type_t tt, su_home_t *home, 	       char const *s, 	       tag_value_t *return_value){  int retval;  s = su_strdup(home, s);      if (s)    *return_value = (tag_value_t)s, retval = 1;  else    *return_value = (tag_value_t)NULL, retval = -1;    return retval;}tagi_t *t_str_dup(tagi_t *dst, tagi_t const *src, void **bb){  dst->t_tag = src->t_tag;  if (src->t_value) {    char const *s = (char const *)src->t_value;    int len = strlen(s) + 1;    dst->t_value = (tag_value_t)strcpy(*bb, s);     *bb = (char *)*bb + len;  }  else     dst->t_value = (tag_value_t)0;  return dst + 1;}size_t t_str_xtra(tagi_t const *t, size_t offset){  return t->t_value ? strlen((char *)t->t_value) + 1 : 0;}tag_class_t str_tag_class[1] =   {{    sizeof(str_tag_class),    /* tc_next */     NULL,    /* tc_len */      NULL,    /* tc_move */     NULL,    /* tc_xtra */     t_str_xtra,    /* tc_dup */      t_str_dup,    /* tc_free */     NULL,    /* tc_find */     NULL,    /* tc_snprintf */ t_str_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_ptr_ref_set,    /* tc_scan */     t_str_scan,  }};/* ====================================================================== *//* cstr tag - pass constant string value (no need to dup) *//** Tag class for constant strings */tag_class_t cstr_tag_class[1] =   {{    sizeof(cstr_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 */ t_str_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_ptr_ref_set,    /* tc_scan */     t_str_scan,  }};/* ====================================================================== *//* ref tag - pass reference */tag_class_t ref_tag_class[1] =   {{    sizeof(ref_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 */ t_ptr_snprintf,    /* tc_filter */   NULL,    /* tc_ref_set */  t_ptr_ref_set,    /* tc_scan */     NULL,  }};

⌨️ 快捷键说明

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