]> mj.ucw.cz Git - libucw.git/blob - ucw/ff-printf.c
903508cfa10c8d43e7de569d16adbc4dfacf01be
[libucw.git] / ucw / ff-printf.c
1 /*
2  *      UCW Library -- Printf on Fastbuf Streams
3  *
4  *      (c) 2002--2013 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include <ucw/lib.h>
11 #include <ucw/fastbuf.h>
12
13 #include <stdio.h>
14 #include <stdbool.h>
15 #include <alloca.h>
16
17 int
18 vbprintf(struct fastbuf *b, const char *msg, va_list args)
19 {
20   byte *buf;
21   int remains, len;
22   va_list args2;
23
24   va_copy(args2, args);
25   remains = bdirect_write_prepare(b, &buf);
26   len = vsnprintf(buf, remains, msg, args2);
27   va_end(args2);
28
29   if (len <= remains)
30     {
31       bdirect_write_commit(b, buf + len);
32       return len;
33     }
34
35   int bufsize = len + 1;
36   bool need_free = 0;
37   if (bufsize <= 256)
38     buf = alloca(bufsize);
39   else
40     {
41       buf = xmalloc(bufsize);
42       need_free = 1;
43     }
44
45   vsnprintf(buf, bufsize, msg, args);
46   bwrite(b, buf, len);
47
48   if (need_free)
49     xfree(buf);
50   return len;
51 }
52
53 int
54 bprintf(struct fastbuf *b, const char *msg, ...)
55 {
56   va_list args;
57   int res;
58
59   va_start(args, msg);
60   res = vbprintf(b, msg, args);
61   va_end(args);
62   return res;
63 }
64
65 #ifdef TEST
66
67 int main(void)
68 {
69   struct fastbuf *b = bfdopen_shared(1, 65536);
70   for (int i=0; i<10000; i++)
71     bprintf(b, "13=%d str=<%s> msg=%m\n", 13, "str");
72   bclose(b);
73   return 0;
74 }
75
76 #endif