diff options
author | Tor Andersson <tor@ghostscript.com> | 2005-05-24 06:15:44 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2005-05-24 06:15:44 +0200 |
commit | d759c948debd9e2dd79eb220b10682681c446e3e (patch) | |
tree | 06d21862dfb9f576c1a04e55a910abe9a2733df4 | |
parent | 8bebcc1c8187906736e3f82b99ee07cb06df0326 (diff) | |
download | mupdf-d759c948debd9e2dd79eb220b10682681c446e3e.tar.xz |
put infernal parser api on top of mini-dom to hide it
-rw-r--r-- | TODO | 7 | ||||
-rw-r--r-- | apps/samxml.c | 16 | ||||
-rw-r--r-- | include/samus/xml.h | 32 | ||||
-rw-r--r-- | samus/sa_xml.c | 214 |
4 files changed, 165 insertions, 104 deletions
@@ -25,6 +25,13 @@ fix the shading code: reuse more code in the parsing error cleanup +think about rewriting file stream api (as the ultimate STDIO replacement): + use function pointers? + dont use pipeline filter? + memoryfile + diskfile + filterfile -> (filters data from another file) + --- immediate plan: diff --git a/apps/samxml.c b/apps/samxml.c index ab5a82e1..c42d8036 100644 --- a/apps/samxml.c +++ b/apps/samxml.c @@ -5,21 +5,23 @@ int main(int argc, char **argv) { fz_error *error; fz_file *file; - sa_xmlnode *xml; + sa_xmlparser *parser; + sa_xmlitem *item; error = fz_openfile(&file, argv[1], FZ_READ); if (error) fz_abort(error); - error = sa_parsexml(&xml, file, 0); + error = sa_openxml(&parser, file, 0); if (error) fz_abort(error); - - fz_closefile(file); - - sa_debugxml(xml, 0); - sa_dropxml(xml); + item = sa_xmlnext(parser); + if (item) + sa_debugxml(item, 0); + + sa_closexml(parser); + fz_closefile(file); return 0; } diff --git a/include/samus/xml.h b/include/samus/xml.h index 04308b66..fa798cd3 100644 --- a/include/samus/xml.h +++ b/include/samus/xml.h @@ -1,22 +1,26 @@ /* - * XML mini-dom based on Inferno's XML parser API. - * This one uses expat and in-memory objects though... :( + * A simple XML parsing API based on Inferno's. + * Under the surface this one uses expat and in-memory objects, + * but that should not be visible through the API. */ -typedef struct sa_xmlnode_s sa_xmlnode; +typedef struct sa_xmlparser_s sa_xmlparser; +typedef struct sa_xmlitem_s sa_xmlitem; -fz_error *sa_parsexml(sa_xmlnode **nodep, fz_file *file, int ns); -void sa_debugxml(sa_xmlnode *node, int level); -void sa_dropxml(sa_xmlnode *node); +fz_error *sa_openxml(sa_xmlparser **spp, fz_file *file, int ns); +void sa_debugxml(sa_xmlitem *item, int level); +void sa_closexml(sa_xmlparser *sp); -sa_xmlnode *sa_xmlup(sa_xmlnode *node); -sa_xmlnode *sa_xmlnext(sa_xmlnode *node); -sa_xmlnode *sa_xmldown(sa_xmlnode *node); +sa_xmlitem *sa_xmlnext(sa_xmlparser *sp); +void sa_xmldown(sa_xmlparser *sp); +void sa_xmlup(sa_xmlparser *sp); -int sa_isxmltext(sa_xmlnode *node); -int sa_isxmltag(sa_xmlnode *node); +int sa_isxmlerror(sa_xmlitem *item); +int sa_isxmltext(sa_xmlitem *item); +int sa_isxmltag(sa_xmlitem *item); -char *sa_getxmlname(sa_xmlnode *node); -char *sa_getxmlatt(sa_xmlnode *node, char *att); -char *sa_getxmltext(sa_xmlnode *node); +char *sa_getxmlerror(sa_xmlitem *item); +char *sa_getxmlname(sa_xmlitem *item); +char *sa_getxmlatt(sa_xmlitem *item, char *att); +char *sa_getxmltext(sa_xmlitem *item); diff --git a/samus/sa_xml.c b/samus/sa_xml.c index a9b88de0..3dd4f02e 100644 --- a/samus/sa_xml.c +++ b/samus/sa_xml.c @@ -5,27 +5,41 @@ #define XMLBUFLEN 4096 -struct sa_xmlnode_s +struct sa_xmlitem_s { char *name; char **atts; - sa_xmlnode *up; - sa_xmlnode *down; - sa_xmlnode *next; + sa_xmlitem *up; + sa_xmlitem *down; + sa_xmlitem *next; }; struct sa_xmlparser_s { fz_error *error; - sa_xmlnode *root; - sa_xmlnode *head; + sa_xmlitem *root; + sa_xmlitem *head; + int downed; }; +static void dropitem(sa_xmlitem *item) +{ + sa_xmlitem *next; + while (item) + { + next = item->next; + if (item->down) + dropitem(item->down); + fz_free(item); + item = next; + } +} + static void onopentag(void *zp, const char *name, const char **atts) { struct sa_xmlparser_s *sp = zp; - sa_xmlnode *node; - sa_xmlnode *tail; + sa_xmlitem *item; + sa_xmlitem *tail; int namelen; int attslen; int textlen; @@ -46,8 +60,8 @@ static void onopentag(void *zp, const char *name, const char **atts) textlen += strlen(atts[i]) + 1; } - node = fz_malloc(sizeof(sa_xmlnode) + attslen + namelen + textlen); - if (!node) + item = fz_malloc(sizeof(sa_xmlitem) + attslen + namelen + textlen); + if (!item) { sp->error = fz_outofmem; return; @@ -55,45 +69,45 @@ static void onopentag(void *zp, const char *name, const char **atts) /* copy strings to new memory */ - node->atts = (char**) (((char*)node) + sizeof(sa_xmlnode)); - node->name = ((char*)node) + sizeof(sa_xmlnode) + attslen; - p = ((char*)node) + sizeof(sa_xmlnode) + attslen + namelen; + item->atts = (char**) (((char*)item) + sizeof(sa_xmlitem)); + item->name = ((char*)item) + sizeof(sa_xmlitem) + attslen; + p = ((char*)item) + sizeof(sa_xmlitem) + attslen + namelen; - strcpy(node->name, name); + strcpy(item->name, name); for (i = 0; atts[i]; i++) { - node->atts[i] = p; - strcpy(node->atts[i], atts[i]); + item->atts[i] = p; + strcpy(item->atts[i], atts[i]); p += strlen(p) + 1; } - node->atts[i] = 0; + item->atts[i] = 0; - /* link node into tree */ + /* link item into tree */ - node->up = sp->head; - node->down = nil; - node->next = nil; + item->up = sp->head; + item->down = nil; + item->next = nil; if (!sp->head) { - sp->root = node; - sp->head = node; + sp->root = item; + sp->head = item; return; } if (!sp->head->down) { - sp->head->down = node; - sp->head = node; + sp->head->down = item; + sp->head = item; return; } tail = sp->head->down; while (tail->next) tail = tail->next; - tail->next = node; - sp->head = node; + tail->next = item; + sp->head = item; } static void onclosetag(void *zp, const char *name) @@ -142,26 +156,34 @@ static void ontext(void *zp, const char *buf, int len) } fz_error * -sa_parsexml(sa_xmlnode **nodep, fz_file *file, int ns) +sa_openxml(sa_xmlparser **spp, fz_file *file, int ns) { fz_error *error = nil; - struct sa_xmlparser_s sp; + sa_xmlparser *sp; XML_Parser xp; char *buf; int len; - sp.error = nil; - sp.root = nil; - sp.head = nil; + sp = fz_malloc(sizeof(sa_xmlparser)); + if (!sp) + return fz_outofmem; + + sp->error = nil; + sp->root = nil; + sp->head = nil; + sp->downed = 0; if (ns) xp = XML_ParserCreateNS(nil, ns); else xp = XML_ParserCreate(nil); if (!xp) + { + fz_free(sp); return fz_outofmem; + } - XML_SetUserData(xp, &sp); + XML_SetUserData(xp, sp); XML_SetParamEntityParsing(xp, XML_PARAM_ENTITY_PARSING_NEVER); XML_SetStartElementHandler(xp, onopentag); @@ -186,9 +208,10 @@ sa_parsexml(sa_xmlnode **nodep, fz_file *file, int ns) goto cleanup; } - if (sp.error) + if (sp->error) { - error = sp.error; + error = sp->error; + sp->error = nil; goto cleanup; } @@ -196,28 +219,24 @@ sa_parsexml(sa_xmlnode **nodep, fz_file *file, int ns) break; } - *nodep = sp.root; + sp->head = nil; + *spp = sp; return nil; cleanup: - if (sp.root) - sa_dropxml(sp.root); + if (sp->root) + dropitem(sp->root); + fz_free(sp); XML_ParserFree(xp); return error; } void -sa_dropxml(sa_xmlnode *node) +sa_closexml(sa_xmlparser *sp) { - sa_xmlnode *next; - while (node) - { - next = node->next; - if (node->down) - sa_dropxml(node->down); - fz_free(node); - node = next; - } + if (sp->root) + dropitem(sp->root); + fz_free(sp); } static void indent(int n) @@ -227,92 +246,121 @@ static void indent(int n) } void -sa_debugxml(sa_xmlnode *node, int level) +sa_debugxml(sa_xmlitem *item, int level) { int i; - while (node) + while (item) { indent(level); - if (sa_isxmltext(node)) - printf("%s\n", sa_getxmltext(node)); + if (sa_isxmltext(item)) + printf("%s\n", sa_getxmltext(item)); else { - printf("<%s", node->name); + printf("<%s", item->name); - for (i = 0; node->atts[i]; i += 2) - printf(" %s=\"%s\"", node->atts[i], node->atts[i+1]); + for (i = 0; item->atts[i]; i += 2) + printf(" %s=\"%s\"", item->atts[i], item->atts[i+1]); - if (node->down) + if (item->down) { printf(">\n"); - sa_debugxml(node->down, level + 1); + sa_debugxml(item->down, level + 1); indent(level); - printf("</%s>\n", node->name); + printf("</%s>\n", item->name); } else printf(" />\n"); } - node = node->next; + item = item->next; + } +} + +sa_xmlitem * +sa_xmlnext(sa_xmlparser *sp) +{ + if (sp->downed) + return nil; + + if (!sp->head) + { + sp->head = sp->root; + return sp->head; + } + + if (sp->head->next) + { + sp->head = sp->head->next; + return sp->head; } + + return nil; } -sa_xmlnode * -sa_xmlup(sa_xmlnode *node) +void +sa_xmldown(sa_xmlparser *sp) { - return node->up; + if (!sp->downed && sp->head && sp->head->down) + sp->head = sp->head->down; + else + sp->downed ++; } -sa_xmlnode * -sa_xmlnext(sa_xmlnode *node) +void +sa_xmlup(sa_xmlparser *sp) { - return node->next; + if (!sp->downed && sp->head && sp->head->up) + sp->head = sp->head->up; + else + sp->downed --; } -sa_xmlnode * -sa_xmldown(sa_xmlnode *node) +int +sa_isxmlerror(sa_xmlitem *item) { - return node->down; + return item->name[0] == '!'; } int -sa_isxmltext(sa_xmlnode *node) +sa_isxmltext(sa_xmlitem *item) { - return node->name[0] == 0; + return item->name[0] == '\0'; } int -sa_isxmltag(sa_xmlnode *node) +sa_isxmltag(sa_xmlitem *item) { - return node->name[0] != 0; + return item->name[0] != '\0' && item->name[0] != '!'; } char * -sa_getxmlname(sa_xmlnode *node) +sa_getxmlname(sa_xmlitem *item) { - if (sa_isxmltag(node)) - return node->name; + if (sa_isxmltag(item)) + return item->name; return nil; } char * -sa_getxmlatt(sa_xmlnode *node, char *att) +sa_getxmlatt(sa_xmlitem *item, char *att) { int i; - for (i = 0; node->atts[i]; i += 2) - if (!strcmp(node->atts[i], att)) - return node->atts[i + 1]; + if (sa_isxmltag(item)) + { + for (i = 0; item->atts[i]; i += 2) + if (!strcmp(item->atts[i], att)) + return item->atts[i + 1]; + } return nil; } char * -sa_getxmltext(sa_xmlnode *node) +sa_getxmltext(sa_xmlitem *item) { - if (sa_isxmltext(node)) - return node->atts[1]; + if (sa_isxmltext(item)) + return item->atts[1]; return nil; } - |