summaryrefslogtreecommitdiff
path: root/line_reader.c
diff options
context:
space:
mode:
Diffstat (limited to 'line_reader.c')
-rw-r--r--line_reader.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/line_reader.c b/line_reader.c
new file mode 100644
index 0000000..48c8355
--- /dev/null
+++ b/line_reader.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <string.h>
+#include "line_reader.h"
+
+
+struct line_reader {
+ int fd;
+ i64 bufcap,buflen;
+ char *buffer;
+};
+
+struct line_reader* line_reader_init(int fd){
+ struct line_reader *r=malloc(1,struct line_reader);
+ r->fd=fd;
+ r->bufcap=1024;
+ r->buflen=0;
+ r->buffer=malloc(r->bufcap,char);
+ return r;
+}
+
+void line_reader_supply_data(struct line_reader *r,const char *data,i64 len){
+ bool do_realloc=false;
+ while(r->buflen+len>r->bufcap){
+ if(r->bufcap*2>LARGENUM){
+ fprintf(stderr,"Data too large in line_reader_supply_data!\n");
+ return;
+ }
+ r->bufcap*=2;
+ do_realloc=true;
+ }
+ if(do_realloc){
+ r->buffer=realloc(r->buffer,r->bufcap,char);
+ }
+ memcpy(r->buffer+r->buflen,data,len);
+ r->buflen+=len;
+}
+
+char* line_reader_get_line(struct line_reader *r,bool include_lf){
+ char *p;
+ p=memchr(r->buffer,'\n',r->buflen);
+ if(p==NULL)return NULL;
+ i64 idx=p-r->buffer;
+ char *str=malloc(idx+include_lf+1,char);
+ memcpy(str,r->buffer,idx+include_lf);
+ str[idx+include_lf]='\0';
+ memmove(r->buffer,r->buffer+idx+1,r->buflen-idx-1);
+ r->buflen-=idx+1;
+ return str;
+}
+
+void line_reader_destroy(struct line_reader *r){
+ free(r->buffer);
+ free(r);
+}