Bläddra i källkod

libdpkg: Add new varbuf_grow function

Guillem Jover 17 år sedan
förälder
incheckning
23e191ad73
3 ändrade filer med 51 tillägg och 0 borttagningar
  1. 34 0
      lib/dpkg/test/t-varbuf.c
  2. 16 0
      lib/dpkg/varbuf.c
  3. 1 0
      lib/dpkg/varbuf.h

+ 34 - 0
lib/dpkg/test/t-varbuf.c

@@ -54,6 +54,39 @@ test_varbuf_prealloc(void)
 	test_pass(vb.buf == NULL);
 }
 
+static void
+test_varbuf_grow(void)
+{
+	struct varbuf vb;
+	size_t old_size;
+	int i;
+
+	varbufinit(&vb, 10);
+
+	/* Test that we grow when needed. */
+	varbuf_grow(&vb, 100);
+	test_pass(vb.used == 0);
+	test_pass(vb.size >= 100);
+
+	old_size = vb.size;
+
+	/* Test that we are not leaking. */
+	for (i = 0; i < 10; i++) {
+		varbuf_grow(&vb, 100);
+		test_pass(vb.used == 0);
+		test_pass(vb.size >= 100);
+		test_pass(vb.size == old_size);
+	}
+
+	/* Test that we grow when needed, with used space. */
+	vb.used = 10;
+	varbuf_grow(&vb, 100);
+	test_pass(vb.used == 10);
+	test_pass(vb.size >= 110);
+
+	varbuffree(&vb);
+}
+
 static void
 test_varbuf_addbuf(void)
 {
@@ -167,6 +200,7 @@ test(void)
 {
 	test_varbuf_init();
 	test_varbuf_prealloc();
+	test_varbuf_grow();
 	test_varbuf_addbuf();
 	test_varbuf_addc();
 	test_varbuf_dupc();

+ 16 - 0
lib/dpkg/varbuf.c

@@ -3,6 +3,7 @@
  * varbuf.c - variable length expandable buffer handling
  *
  * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk>
+ * Copyright © 2008, 2009 Guillem Jover <guillem@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as
@@ -111,6 +112,21 @@ void varbufreset(struct varbuf *v) {
   v->used= 0;
 }
 
+void
+varbuf_grow(struct varbuf *v, size_t need_size)
+{
+  /* Make sure the varbuf is in a sane state. */
+  if (v->size < v->used)
+    internerr("inconsistent varbuf: size(%d) < used(%d)", v->size, v->used);
+
+  /* Check if we already have enough room. */
+  if ((v->size - v->used) >= need_size)
+    return;
+
+  v->size = (v->size + need_size) * 2;
+  v->buf = m_realloc(v->buf, v->size);
+}
+
 void varbufextend(struct varbuf *v) {
   int newsize;
   char *newbuf;

+ 1 - 0
lib/dpkg/varbuf.h

@@ -66,6 +66,7 @@ struct varbuf {
 #define VARBUF_INIT { 0, 0, NULL }
 
 void varbufinit(struct varbuf *v, size_t size);
+void varbuf_grow(struct varbuf *v, size_t need_size);
 void varbufextend(struct varbuf *v);
 void varbufreset(struct varbuf *v);
 void varbuffree(struct varbuf *v);