Install json_object_private.h file
[platform/upstream/json-c.git] / printbuf.c
1 /*
2  * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
3  *
4  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5  * Michael Clark <michael@metaparadigm.com>
6  *
7  * This library is free software; you can redistribute it and/or modify
8  * it under the terms of the MIT license. See COPYING for details.
9  *
10  *
11  * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
12  * The copyrights to the contents of this file are licensed under the MIT License
13  * (http://www.opensource.org/licenses/mit-license.php)
14  */
15
16 #include "config.h"
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21
22 #ifdef HAVE_STDARG_H
23 # include <stdarg.h>
24 #else /* !HAVE_STDARG_H */
25 # error Not enough var arg support!
26 #endif /* HAVE_STDARG_H */
27
28 #include "debug.h"
29 #include "printbuf.h"
30 #include "snprintf_compat.h"
31 #include "vasprintf_compat.h"
32
33 static int printbuf_extend(struct printbuf *p, int min_size);
34
35 struct printbuf* printbuf_new(void)
36 {
37   struct printbuf *p;
38
39   p = (struct printbuf*)calloc(1, sizeof(struct printbuf));
40   if(!p) return NULL;
41   p->size = 32;
42   p->bpos = 0;
43   if(!(p->buf = (char*)malloc(p->size))) {
44     free(p);
45     return NULL;
46   }
47   p->buf[0]= '\0';
48   return p;
49 }
50
51
52 /**
53  * Extend the buffer p so it has a size of at least min_size.
54  *
55  * If the current size is large enough, nothing is changed.
56  *
57  * Note: this does not check the available space!  The caller
58  *  is responsible for performing those calculations.
59  */
60 static int printbuf_extend(struct printbuf *p, int min_size)
61 {
62         char *t;
63         int new_size;
64
65         if (p->size >= min_size)
66                 return 0;
67
68         new_size = p->size * 2;
69         if (new_size < min_size + 8)
70                 new_size =  min_size + 8;
71 #ifdef PRINTBUF_DEBUG
72         MC_DEBUG("printbuf_memappend: realloc "
73           "bpos=%d min_size=%d old_size=%d new_size=%d\n",
74           p->bpos, min_size, p->size, new_size);
75 #endif /* PRINTBUF_DEBUG */
76         if(!(t = (char*)realloc(p->buf, new_size)))
77                 return -1;
78         p->size = new_size;
79         p->buf = t;
80         return 0;
81 }
82
83 int printbuf_memappend(struct printbuf *p, const char *buf, int size)
84 {
85   if (p->size <= p->bpos + size + 1) {
86     if (printbuf_extend(p, p->bpos + size + 1) < 0)
87       return -1;
88   }
89   memcpy(p->buf + p->bpos, buf, size);
90   p->bpos += size;
91   p->buf[p->bpos]= '\0';
92   return size;
93 }
94
95 int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
96 {
97         int size_needed;
98
99         if (offset == -1)
100                 offset = pb->bpos;
101         size_needed = offset + len;
102         if (pb->size < size_needed)
103         {
104                 if (printbuf_extend(pb, size_needed) < 0)
105                         return -1;
106         }
107
108         memset(pb->buf + offset, charvalue, len);
109         if (pb->bpos < size_needed)
110                 pb->bpos = size_needed;
111
112         return 0;
113 }
114
115 int sprintbuf(struct printbuf *p, const char *msg, ...)
116 {
117   va_list ap;
118   char *t;
119   int size;
120   char buf[128];
121
122   /* user stack buffer first */
123   va_start(ap, msg);
124   size = vsnprintf(buf, 128, msg, ap);
125   va_end(ap);
126   /* if string is greater than stack buffer, then use dynamic string
127      with vasprintf.  Note: some implementation of vsnprintf return -1
128      if output is truncated whereas some return the number of bytes that
129      would have been written - this code handles both cases. */
130   if(size == -1 || size > 127) {
131     va_start(ap, msg);
132     if((size = vasprintf(&t, msg, ap)) < 0) { va_end(ap); return -1; }
133     va_end(ap);
134     printbuf_memappend(p, t, size);
135     free(t);
136     return size;
137   } else {
138     printbuf_memappend(p, buf, size);
139     return size;
140   }
141 }
142
143 void printbuf_reset(struct printbuf *p)
144 {
145   p->buf[0] = '\0';
146   p->bpos = 0;
147 }
148
149 void printbuf_free(struct printbuf *p)
150 {
151   if(p) {
152     free(p->buf);
153     free(p);
154   }
155 }