From 5eb71daeacda95d4f93ecb0f3966cf69b09b8553 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Sat, 16 May 2015 15:53:16 +0200 Subject: xml: allow to read from fd or string buffer + minor code style. --- xml.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++------------------- xml.h | 11 +++++++--- 2 files changed, 60 insertions(+), 24 deletions(-) diff --git a/xml.c b/xml.c index 0e91cad..9f88792 100644 --- a/xml.c +++ b/xml.c @@ -1,28 +1,51 @@ #include +#include #include #include #include +#include #include "xml.h" -static __inline__ int /* like getc(), but do some smart buffering */ -xmlparser_getnext(XMLParser *x) +static int +xmlparser_string_getnext(XMLParser *x) { - int c; - if(ferror(x->fp)) + if (!*(x->str)) return EOF; - if(feof(x->fp)) + return (int)*(x->str++); +} + +static int /* like getc(), but do some smart buffering */ +xmlparser_fd_getnext(XMLParser *x) +{ + ssize_t r; + + /* previous read error was set */ + if(x->readerrno) return EOF; - c = fgetc(x->fp); - return c; -#if 0 + if(x->readoffset >= x->readlastbytes) { x->readoffset = 0; - if(!(x->readlastbytes = fread(x->readbuf, 1, sizeof(x->readbuf), x->fp))) - return EOF; /* 0 bytes read, assume EOF */ +again: + r = read(x->fd, x->readbuf, sizeof(x->readbuf)); + if(r == -1) { + if(errno == EINTR) + goto again; + x->readerrno = errno; + x->readlastbytes = 0; + return EOF; + } else if(!r) { + return EOF; + } + x->readlastbytes = r; } return (int)x->readbuf[x->readoffset++]; -#endif +} + +static int +xmlparser_getnext(XMLParser *x) +{ + return x->getnext(x); } static __inline__ void @@ -108,8 +131,9 @@ xmlparser_parseattrs(XMLParser *x) } namelen = 0; endname = 0; - } else if(namelen < sizeof(x->name) - 1) + } else if(namelen < sizeof(x->name) - 1) { x->name[namelen++] = c; + } if(c == '>') { break; } else if(c == '/') { @@ -204,14 +228,7 @@ xmlparser_parsecdata(XMLParser *x) } } -void -xmlparser_init(XMLParser *x, FILE *fp) -{ - memset(x, 0, sizeof(XMLParser)); - x->fp = fp; -} - -void +static void xmlparser_parse(XMLParser *x) { int c, ispi; @@ -239,7 +256,7 @@ xmlparser_parse(XMLParser *x) if(tagdatalen == strlen("[CDATA[") && x->data[1] == 'C' && x->data[2] == 'D' && x->data[3] == 'A' && x->data[4] == 'T' && - x->data[5] == 'A' && x->data[6] == '[') { /* cdata */ + x->data[5] == 'A' && x->data[6] == '[') { /* CDATA */ xmlparser_parsecdata(x); break; #if 0 @@ -337,3 +354,17 @@ xmlparser_parse(XMLParser *x) } } } + +void +xmlparser_parse_string(XMLParser *x, const char *s) +{ + x->str = s; + x->getnext = xmlparser_string_getnext; +} + +void +xmlparser_parse_fd(XMLParser *x, int fd) +{ + x->fd = fd; + x->getnext = xmlparser_fd_getnext; +} diff --git a/xml.h b/xml.h index 5f72494..ee69e15 100644 --- a/xml.h +++ b/xml.h @@ -27,7 +27,12 @@ typedef struct xmlparser { void (*xmlcomment)(struct xmlparser *, const char *, size_t); void (*xmlcommentend)(struct xmlparser *); - FILE *fp; /* file stream to read from */ + int (*getnext)(struct xmlparser *); + + int readerrno; /* errno set from read(). */ + int fd; /* fd to read from */ + + const char *str; /* "read" from string */ /* private; internal state */ char tag[1024]; /* current tag */ @@ -41,5 +46,5 @@ typedef struct xmlparser { unsigned char readbuf[BUFSIZ]; } XMLParser; -void xmlparser_init(XMLParser *, FILE *); -void xmlparser_parse(XMLParser *); +void xmlparser_parse_fd(XMLParser *, int); +void xmlparser_parse_string(XMLParser *, const char *); -- cgit v1.2.3