1 #include <stdio.h> // For definition of EOF
2 #include "input/byte_readers.h"
3 #include "lib/mlr_globals.h"
4 #include "lib/mlrutil.h"
5 
6 typedef struct _string_byte_reader_state_t {
7 	char* backing;
8 	char* p;
9 	char* pend;
10 } string_byte_reader_state_t;
11 
12 static int  string_byte_reader_open_func(struct _byte_reader_t* pbr, char* prepipe, char* backing);
13 static int  string_byte_reader_read_func(struct _byte_reader_t* pbr);
14 static void string_byte_reader_close_func(struct _byte_reader_t* pbr, char* prepipe);
15 
16 // ----------------------------------------------------------------
string_byte_reader_alloc()17 byte_reader_t* string_byte_reader_alloc() {
18 	byte_reader_t* pbr = mlr_malloc_or_die(sizeof(byte_reader_t));
19 
20 	pbr->pvstate     = NULL;
21 	pbr->popen_func  = string_byte_reader_open_func;
22 	pbr->pread_func  = string_byte_reader_read_func;
23 	pbr->pclose_func = string_byte_reader_close_func;
24 
25 	return pbr;
26 }
27 
string_byte_reader_free(byte_reader_t * pbr)28 void string_byte_reader_free(byte_reader_t* pbr) {
29 	free(pbr);
30 }
31 
32 // ----------------------------------------------------------------
string_byte_reader_open_func(struct _byte_reader_t * pbr,char * prepipe,char * backing)33 static int string_byte_reader_open_func(struct _byte_reader_t* pbr, char* prepipe, char* backing) {
34 	// popen is a stdio construct, not an mmap construct, and it can't be supported here.
35 	if (prepipe != NULL) {
36 		fprintf(stderr, "%s: coding error detected in file %s at line %d.\n",
37 			MLR_GLOBALS.bargv0, __FILE__, __LINE__);
38 		exit(1);
39 	}
40 
41 	string_byte_reader_state_t* pstate = mlr_malloc_or_die(sizeof(string_byte_reader_state_t));
42 	pstate->backing = backing;
43 	pstate->p       = pstate->backing;
44 	pstate->pend    = pstate->backing + strlen(pstate->backing);
45 	pbr->pvstate    = pstate;
46 	return TRUE;
47 }
48 
string_byte_reader_read_func(struct _byte_reader_t * pbr)49 static int string_byte_reader_read_func(struct _byte_reader_t* pbr) {
50 	string_byte_reader_state_t* pstate = pbr->pvstate;
51 	if (pstate->p < pstate->pend) {
52 		return *(pstate->p++);
53 	} else {
54 		return EOF;
55 	}
56 }
57 
string_byte_reader_close_func(struct _byte_reader_t * pbr,char * prepipe)58 static void string_byte_reader_close_func(struct _byte_reader_t* pbr, char* prepipe) {
59 	pbr->pvstate = NULL;
60 }
61