]> git.evergreen-ils.org Git - working/Evergreen.git/blob - OpenSRF/src/libjson/printbuf.c
68c425c87be522260d6a542730523705eebdb998
[working/Evergreen.git] / OpenSRF / src / libjson / printbuf.c
1 /*
2  * $Id$
3  *
4  * Copyright Metaparadigm Pte. Ltd. 2004.
5  * Michael Clark <michael@metaparadigm.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public (LGPL)
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details: http://www.gnu.org/
16  *
17  */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <stdarg.h>
22 #include <string.h>
23
24 #include "bits.h"
25 #include "debug.h"
26 #include "printbuf.h"
27
28
29 struct printbuf* printbuf_new()
30 {
31   struct printbuf *p;
32
33   if(!(p = calloc(1, sizeof(struct printbuf)))) return NULL;
34   p->size = 32;
35   p->bpos = 0;
36   if(!(p->buf = malloc(p->size))) {
37     free(p);
38     return NULL;
39   }
40   return p;
41 }
42
43
44 int printbuf_memappend(struct printbuf *p, char *buf, int size)
45 {
46   char *t;
47   if(p->size - p->bpos <= size) {
48     int new_size = max(p->size * 2, p->bpos + size + 8);
49 #if 0
50     mc_debug("printbuf_memappend: realloc "
51              "bpos=%d wrsize=%d old_size=%d new_size=%d\n",
52              p->bpos, size, p->size, new_size);
53 #endif
54     if(!(t = realloc(p->buf, new_size))) return -1;
55     p->size = new_size;
56     p->buf = t;
57   }
58   memcpy(p->buf + p->bpos, buf, size);
59   p->bpos += size;
60   p->buf[p->bpos]= '\0';
61   return size;
62 }
63
64
65 int sprintbuf(struct printbuf *p, const char *msg, ...)
66 {
67   va_list ap;
68   char *t;
69   int size;
70   char buf[128];
71
72   /* user stack buffer first */
73   va_start(ap, msg);
74   size = vsnprintf(buf, 128, msg, ap);
75   va_end(ap);
76   /* if string is greater than stack buffer, then use dynamic string
77      with vasprintf.  Note: some implementation of vsnprintf return -1
78      if output is truncated whereas some return the number of bytes that
79      would have been writeen - this code handles both cases. */
80   if(size == -1 || size > 127) {
81     int ret;
82     va_start(ap, msg);
83     if((size = vasprintf(&t, msg, ap)) == -1) return -1;
84     va_end(ap);
85     ret = printbuf_memappend(p, t, size);
86     free(t);
87     return ret;
88   } else {
89     return printbuf_memappend(p, buf, size);
90   }
91 }
92
93
94 void printbuf_reset(struct printbuf *p)
95 {
96   p->buf[0] = '\0';
97   p->bpos = 0;
98 }
99
100 void printbuf_free(struct printbuf *p)
101 {
102   if(p) {
103     free(p->buf);
104     free(p);
105   }
106 }