1/* @(#) formatted printing into a buffer
2 *
3 * Copyright 2008-2011 Pavel V. Cherenkov (pcherenkov@gmail.com)
4 *
5 *  This file is part of udpxy.
6 *
7 *  udpxy is free software: you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation, either version 3 of the License, or
10 *  (at your option) any later version.
11 *
12 *  udpxy 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
15 *  GNU General Public License for more details.
16 *
17 *  You should have received a copy of the GNU General Public License
18 *  along with udpxy.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <sys/types.h>
22#include <stdarg.h>
23#include <stdio.h>
24#include <assert.h>
25#include <string.h>
26#include <stdlib.h>
27#include <errno.h>
28
29#include "prbuf.h"
30
31struct printbuf
32{
33    char*   buf;
34    size_t  len,
35            pos;
36};
37
38
39int
40prbuf_open( prbuf_t* pb, void* buf, size_t n )
41{
42    prbuf_t p = NULL;
43
44    assert( pb && buf && (n > (size_t)0) );
45
46    p = malloc( sizeof(struct printbuf) );
47    if( NULL == p ) return -1;
48
49    *pb = p;
50
51    p->buf = (char*)buf;
52    p->len = n;
53    p->pos = 0;
54
55    return 0;
56}
57
58
59void
60prbuf_rewind( prbuf_t pb )
61{
62    assert( pb );
63
64    pb->pos = 0;
65    pb->buf[0] = '\0';
66}
67
68
69
70int
71prbuf_close( prbuf_t pb )
72{
73    assert( pb );
74
75    free( pb );
76    return 0;
77}
78
79size_t
80prbuf_len( prbuf_t pb )
81{
82    assert( pb );
83    return pb->pos;
84}
85
86int
87prbuf_printf( prbuf_t pb, const char* format, ... )
88{
89    va_list ap;
90    char* p = NULL;
91    int n = -1;
92    size_t left;
93
94    assert( pb && format );
95
96    if( pb->pos >= pb->len ) return 0;
97
98    left = pb->len - pb->pos - 1;
99    p = pb->buf + pb->pos;
100
101    va_start( ap, format );
102    errno = 0;
103    n = vsnprintf( p, left, format, ap );
104    va_end( ap );
105
106    if( n < 0 ) return -1;
107
108    if( (size_t)n >= left ) {
109        n = left;
110    }
111
112    p[ n ] = '\0';
113    pb->pos += (size_t)n;
114    return n;
115}
116
117
118/* __EOF__ */
119
120