/* * sbuf.c * * A string buffer library. * * Author: Dario Rodriguez dario@softhome.net * This library is licensed on the terms of the GNU LGPL v2+ */ #include <stdlib.h> #include <unistd.h> #include <string.h> #include "sbuf.h" /* sbuf, high level api */ sbuf * sbuf_init(long bufsize) { sbuf *buf; if(bufsize<=0 || (buf=malloc(sizeof(sbuf)))==NULL) return(NULL); memset(buf,0,sizeof(sbuf)); if((buf->buf=malloc(bufsize))==NULL) { free(buf),buf=NULL; return(NULL); } buf->size=bufsize; return(buf); } sbuf * sbuf_staticinit(sbuf *uninitsbuf, long bufsize, char *buf) { if(uninitsbuf==NULL || buf==NULL || bufsize<=0) return(NULL); memset(uninitsbuf,0,sizeof(sbuf)); uninitsbuf->buf=buf; uninitsbuf->size=bufsize; return(uninitsbuf); } void sbuf_free(sbuf *buf) { if(buf==NULL) return; if(buf->buf!=NULL) free(buf->buf),buf->buf=NULL; buf->size=0; free(buf); } void sbuf_staticfree(sbuf *buf) { if(buf==NULL) return; memset(buf,0,sizeof(sbuf)); } int sbuf_fill(sbuf *buf, int fd, long numbytes) { long n; int nread; if(buf==NULL || fd==-1 || numbytes<0) return(-1); n=(numbytes>(buf->size-buf->used))?buf->size-buf->used:numbytes; nread=read(fd,buf->buf+buf->used,n); if(nread>=0) buf->used+=nread; return(nread); } char * sbuf_getline(sbuf *buf) { char *start,*end; if(buf==NULL) return(NULL); start=buf->buf+buf->got; if((end=memchr(start,'\n',buf->used-buf->got))==NULL) return(NULL); *end='\0'; /* we accept lines both with "\n" and "\r\n"; strip the leading \r if necessary */ if(end>start && end[-1]=='\r') end[-1]='\0'; buf->got+=(end-start+1); return(start); } void sbuf_discard(sbuf *buf) { if(buf==NULL || buf->got==0) return; memmove(buf->buf,buf->buf+buf->got,buf->used-buf->got); buf->used-=buf->got; buf->got=0; } void sbuf_wipe(sbuf *buf) { buf->used=buf->got=0; } /* sbuf, addutional functionality */ char * sbuf_getbytes(sbuf *buf, long numbytes) { char *res; if(buf==NULL || numbytes>(buf->used-buf->got)) return(NULL); res=buf->buf+buf->got; buf->got+=numbytes; return(res); } long sbuf_count(sbuf *buf) { if(buf==NULL) return(0); return(buf->used-buf->got); } char * sbuf_ptr(sbuf *buf) { return(buf->buf+buf->got); } long sbuf_add(sbuf *buf, const char *data, long datasize) { long added; if(buf==NULL || data==NULL || buf->used==buf->size) return(0); added=(datasize>(buf->size-buf->used))?(buf->size-buf->used):datasize; memcpy(buf->buf+buf->used,data,added); buf->used+=added; return(added); } long sbuf_addstr(sbuf *buf, const char *str) { if(buf==NULL || str==NULL) return(0); return(sbuf_add(buf,str,strlen(str))); } long sbuf_unused(sbuf *buf) { if(buf==NULL) return(0); return(buf->size-buf->used); } char * sbuf_ptrunused(sbuf *buf) { if(buf==NULL) return(NULL); return(buf->buf+buf->used); } long sbuf_addfromunused(sbuf *buf, long numbytes) { int added; if(buf==NULL || numbytes<=0) return(0); added=(numbytes>(buf->size-buf->used))?(buf->size-buf->used):numbytes; buf->used+=added; return(added); } long sbuf_send(sbuf *buf, int fd, long numbytes) { int n; int written; if(buf==NULL || fd==-1 || numbytes<=0) return(0); n=(numbytes>(buf->used-buf->got))?(buf->used-buf->got):numbytes; written=write(fd,buf->buf+buf->got,n); if(written>0) buf->got+=written; return(written); }