summaryrefslogtreecommitdiff
path: root/line_reader.c
blob: 48c83552862cbcbd80c32b9ce665f0ffb91199c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
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);
}