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