reg_avps_db.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #include "reg_avps.h"
  2. #include "dlist.h"
  3. #include "ul_mod.h"
  4. #include "../../ut.h"
  5. #include "../../sr_module.h"
  6. #define TYPE_STRING 's'
  7. #define TYPE_NUM 'n'
  8. /* int use_serialized_reg_avps = 0; */
  9. /*** table columns ***/
  10. char *avp_column = NULL;
  11. /* FIXME - ugly */
  12. extern avp_t *create_avp (avp_flags_t flags, avp_name_t name, avp_value_t val);
  13. static inline int num_digits(int i)
  14. {
  15. int digits = 1;
  16. while (i > 9) {
  17. i = i / 10;
  18. digits++;
  19. }
  20. /* better will be to use logarithms, but can I use math routines
  21. * here (is it linked with libm)? */
  22. return digits;
  23. }
  24. void get_avp_value_ex(avp_t *avp, str *dst, int *type) {
  25. avp_value_t val;
  26. /* Warning! it uses static buffer from int2str !!! */
  27. get_avp_val(avp, &val);
  28. if (avp->flags & AVP_VAL_STR) {
  29. *dst = val.s;
  30. *type = AVP_VAL_STR;
  31. }
  32. else { /* probably (!) number */
  33. dst->s = int2str(val.n, &dst->len);
  34. *type = 0;
  35. }
  36. }
  37. /* returns length of serialized avp */
  38. int serialize_avp(avp_t *avp, char *buf)
  39. {
  40. int len = 0;
  41. str name = STR_NULL;
  42. str val;
  43. str *s;
  44. int type;
  45. char c;
  46. get_avp_value_ex(avp, &val, &type);
  47. s = get_avp_name(avp);
  48. if (s) name = *s;
  49. len = name.len + val.len + 3 /* : */ + 1 /* type */ +
  50. num_digits(name.len) + num_digits(val.len) +
  51. num_digits(avp->flags);
  52. if (buf) {
  53. /* can't use int2str because of static buf */
  54. if (type == AVP_VAL_STR) c = TYPE_STRING;
  55. else c = TYPE_NUM;
  56. sprintf(buf, "%c%d:%d:%d:%.*s%.*s", c, name.len, val.len, avp->flags,
  57. name.len, ZSW(name.s),
  58. val.len, ZSW(val.s)); /* not effective but simple */
  59. }
  60. return len;
  61. }
  62. static inline char *get_separator(char *buf) /* returns position after the number */
  63. {
  64. /* find next ':' */
  65. int i;
  66. for (i = 0; buf[i] != ':'; i++);
  67. return buf + i;
  68. }
  69. static char *get_nums(char *buf, int *_name_len, int *_value_len, int *_flags)
  70. {
  71. str name_len, value_len, flags;
  72. char *last;
  73. name_len.s = buf + 1; /* skip type */
  74. value_len.s = get_separator(name_len.s) + 1;
  75. flags.s = get_separator(value_len.s) + 1;
  76. last = get_separator(flags.s);
  77. flags.len = last - flags.s;
  78. value_len.len = flags.s - value_len.s - 1;
  79. name_len.len = value_len.s - name_len.s - 1;
  80. /* INFO("I read: name_len=%.*s, value_len=%.*s, flags=%.*s\n",
  81. name_len.len, name_len.s,
  82. value_len.len, value_len.s,
  83. flags.len, flags.s);*/
  84. str2int(&name_len, (unsigned int*)_name_len);
  85. str2int(&value_len, (unsigned int*)_value_len);
  86. str2int(&flags, (unsigned int*)_flags);
  87. return last + 1;
  88. }
  89. avp_t *deserialize_avps(str *serialized_avps)
  90. {
  91. avp_t *first, *last, *avp;
  92. int i, flags;
  93. str value;
  94. avp_value_t val;
  95. avp_name_t name;
  96. if (!serialized_avps) return NULL;
  97. if ((serialized_avps->len < 1) || (!serialized_avps->s)) return NULL;
  98. first = NULL; last = NULL;
  99. i = 0;
  100. while (i < serialized_avps->len) {
  101. name.s.s = get_nums(serialized_avps->s + i, &name.s.len, &value.len, &flags);
  102. value.s = name.s.s + name.s.len;
  103. switch (serialized_avps->s[i]) {
  104. case TYPE_NUM: str2int(&value, (unsigned int*)&val.n); break;
  105. case TYPE_STRING: val.s = value; break;
  106. }
  107. /* INFO("I read: name=%.*s, value=%.*s, flags=%d\n",
  108. name.s.len, name.s.s,
  109. value.len, value.s,
  110. flags);*/
  111. avp = create_avp(flags, name, val);
  112. if (last) last->next = avp;
  113. else first = avp;
  114. last = avp;
  115. i += value.s + value.len - serialized_avps->s;
  116. }
  117. return first;
  118. }
  119. int serialize_avps(avp_t *first, str *dst)
  120. {
  121. avp_t *avp;
  122. int len = 0;
  123. avp = first;
  124. while (avp) {
  125. len += serialize_avp(avp, NULL);
  126. avp = avp->next;
  127. }
  128. dst->len = len;
  129. if (len < 1) {
  130. dst->s = NULL;
  131. return 0;
  132. }
  133. dst->s = (char*)pkg_malloc(len + 1); /* hack: +1 due to \0 from sprintf */
  134. if (!dst->s) {
  135. dst->len = 0;
  136. ERR("no pkg mem (%d)\n", len);
  137. return -1;
  138. }
  139. avp = first;
  140. len = 0;
  141. while (avp) {
  142. len += serialize_avp(avp, dst->s + len);
  143. avp = avp->next;
  144. }
  145. return 0;
  146. }