varbuf.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * libdpkg - Debian packaging suite library routines
  3. * varbuf.c - variable length expandable buffer handling
  4. *
  5. * Copyright © 1994,1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
  6. * Copyright © 2008-2015 Guillem Jover <guillem@debian.org>
  7. *
  8. * This is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. */
  21. #include <config.h>
  22. #include <compat.h>
  23. #include <string.h>
  24. #include <stdlib.h>
  25. #include <stdio.h>
  26. #include <dpkg/i18n.h>
  27. #include <dpkg/dpkg.h>
  28. #include <dpkg/dpkg-db.h>
  29. void
  30. varbuf_add_char(struct varbuf *v, int c)
  31. {
  32. varbuf_grow(v, 1);
  33. v->buf[v->used++]= c;
  34. }
  35. void
  36. varbuf_dup_char(struct varbuf *v, int c, size_t n)
  37. {
  38. varbuf_grow(v, n);
  39. memset(v->buf + v->used, c, n);
  40. v->used += n;
  41. }
  42. void
  43. varbuf_map_char(struct varbuf *v, int c_src, int c_dst)
  44. {
  45. size_t i;
  46. for (i = 0; i < v->used; i++)
  47. if (v->buf[i] == c_src)
  48. v->buf[i] = c_dst;
  49. }
  50. int
  51. varbuf_printf(struct varbuf *v, const char *fmt, ...)
  52. {
  53. int r;
  54. va_list args;
  55. va_start(args, fmt);
  56. r = varbuf_vprintf(v, fmt, args);
  57. va_end(args);
  58. return r;
  59. }
  60. int
  61. varbuf_vprintf(struct varbuf *v, const char *fmt, va_list args)
  62. {
  63. va_list args_copy;
  64. int needed, r;
  65. va_copy(args_copy, args);
  66. needed = vsnprintf(NULL, 0, fmt, args_copy);
  67. va_end(args_copy);
  68. if (needed < 0)
  69. ohshite(_("error formatting string into varbuf variable"));
  70. varbuf_grow(v, needed + 1);
  71. r = vsnprintf(v->buf + v->used, needed + 1, fmt, args);
  72. if (r < 0)
  73. ohshite(_("error formatting string into varbuf variable"));
  74. v->used += r;
  75. return r;
  76. }
  77. void
  78. varbuf_add_buf(struct varbuf *v, const void *s, size_t size)
  79. {
  80. varbuf_grow(v, size);
  81. memcpy(v->buf + v->used, s, size);
  82. v->used += size;
  83. }
  84. void
  85. varbuf_end_str(struct varbuf *v)
  86. {
  87. varbuf_grow(v, 1);
  88. v->buf[v->used] = '\0';
  89. }
  90. const char *
  91. varbuf_get_str(struct varbuf *v)
  92. {
  93. varbuf_end_str(v);
  94. return v->buf;
  95. }
  96. void
  97. varbuf_init(struct varbuf *v, size_t size)
  98. {
  99. v->used = 0;
  100. v->size = size;
  101. if (size)
  102. v->buf = m_malloc(size);
  103. else
  104. v->buf = NULL;
  105. }
  106. void
  107. varbuf_reset(struct varbuf *v)
  108. {
  109. v->used= 0;
  110. }
  111. void
  112. varbuf_grow(struct varbuf *v, size_t need_size)
  113. {
  114. /* Make sure the varbuf is in a sane state. */
  115. if (v->size < v->used)
  116. internerr("varbuf used(%zu) > size(%zu)", v->used, v->size);
  117. /* Check if we already have enough room. */
  118. if ((v->size - v->used) >= need_size)
  119. return;
  120. v->size = (v->size + need_size) * 2;
  121. v->buf = m_realloc(v->buf, v->size);
  122. }
  123. void
  124. varbuf_trunc(struct varbuf *v, size_t used_size)
  125. {
  126. /* Make sure the caller does not claim more than available. */
  127. if (v->size < used_size)
  128. internerr("varbuf new_used(%zu) > size(%zu)", used_size, v->size);
  129. v->used = used_size;
  130. }
  131. void
  132. varbuf_snapshot(struct varbuf *v, struct varbuf_state *vs)
  133. {
  134. vs->used = v->used;
  135. }
  136. void
  137. varbuf_rollback(struct varbuf *v, struct varbuf_state *vs)
  138. {
  139. varbuf_trunc(v, vs->used);
  140. }
  141. char *
  142. varbuf_detach(struct varbuf *v)
  143. {
  144. char *buf = v->buf;
  145. v->buf = NULL;
  146. v->size = 0;
  147. v->used = 0;
  148. return buf;
  149. }
  150. void
  151. varbuf_destroy(struct varbuf *v)
  152. {
  153. free(v->buf); v->buf=NULL; v->size=0; v->used=0;
  154. }