summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Haszlakiewicz <erh+git@nimenees.com>2012-04-02 15:39:55 -0500
committerEric Haszlakiewicz <erh+git@nimenees.com>2012-04-02 15:39:55 -0500
commit2d48543f2ef8caadcbdbd9b3b779664038bf6a2b (patch)
treeafe71c9e3126edb49313edfe1ea3d699d2f67a48
parent781798ccdfbe56abd5046d3978e29adf10c74c23 (diff)
downloadjson-c-2d48543f2ef8caadcbdbd9b3b779664038bf6a2b.tar.gz
Add a printbuf_memset() function to provide an effecient way to set and append things like whitespace indentation.
-rw-r--r--printbuf.c55
-rw-r--r--printbuf.h13
2 files changed, 58 insertions, 10 deletions
diff --git a/printbuf.c b/printbuf.c
index e8902c8..b4f7955 100644
--- a/printbuf.c
+++ b/printbuf.c
@@ -29,6 +29,8 @@
#include "debug.h"
#include "printbuf.h"
+static int printbuf_extend(struct printbuf *p, int min_size);
+
struct printbuf* printbuf_new(void)
{
struct printbuf *p;
@@ -45,19 +47,32 @@ struct printbuf* printbuf_new(void)
}
-int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+static int printbuf_extend(struct printbuf *p, int min_size)
{
- char *t;
- if(p->size - p->bpos <= size) {
- int new_size = json_max(p->size * 2, p->bpos + size + 8);
+ char *t;
+ int new_size;
+
+ if (p->size >= min_size)
+ return 0;
+
+ new_size = json_max(p->size * 2, p->bpos + min_size + 8);
#ifdef PRINTBUF_DEBUG
- MC_DEBUG("printbuf_memappend: realloc "
- "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
- p->bpos, size, p->size, new_size);
+ MC_DEBUG("printbuf_memappend: realloc "
+ "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
+ p->bpos, size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */
- if(!(t = (char*)realloc(p->buf, new_size))) return -1;
- p->size = new_size;
- p->buf = t;
+ if(!(t = (char*)realloc(p->buf, new_size)))
+ return -1;
+ p->size = new_size;
+ p->buf = t;
+ return 0;
+}
+
+int printbuf_memappend(struct printbuf *p, const char *buf, int size)
+{
+ if(p->size - p->bpos <= size) {
+ if (printbuf_extend(p, size) < 0)
+ return -1;
}
memcpy(p->buf + p->bpos, buf, size);
p->bpos += size;
@@ -65,6 +80,26 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
return size;
}
+int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
+{
+ int size_needed;
+
+ if (offset == -1)
+ offset = pb->bpos;
+ size_needed = offset + len;
+ if(pb->size - pb->bpos <= size_needed)
+ {
+ if (printbuf_extend(pb, size_needed) < 0)
+ return -1;
+ }
+
+ memset(pb->buf + offset, charvalue, len);
+ if (pb->bpos < size_needed)
+ pb->bpos = size_needed;
+
+ return 0;
+}
+
#if !HAVE_VSNPRINTF && defined(_MSC_VER)
# define vsnprintf _vsnprintf
#elif !HAVE_VSNPRINTF /* !HAVE_VSNPRINTF */
diff --git a/printbuf.h b/printbuf.h
index 5d4963f..fc8ac61 100644
--- a/printbuf.h
+++ b/printbuf.h
@@ -50,6 +50,19 @@ do { \
} else { printbuf_memappend(p, (bufptr), bufsize); } \
} while (0)
+#define printbuf_length(p) ((p)->bpos)
+
+/**
+ * Set len bytes of the buffer to charvalue, starting at offset offset.
+ * Similar to calling memset(x, charvalue, len);
+ *
+ * The memory allocated for the buffer is extended as necessary.
+ *
+ * If offset is -1, this starts at the end of the current data in the buffer.
+ */
+extern int
+printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len);
+
extern int
sprintbuf(struct printbuf *p, const char *msg, ...);