X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/f9d2225be8ff0f3e01792f6b5550d9e051e077b4..d1d1bb6de0bb56ed35f02c311e27f54b13e247c9:/lib/base/nxml.cpp diff --git a/lib/base/nxml.cpp b/lib/base/nxml.cpp deleted file mode 100644 index f32880a6..00000000 --- a/lib/base/nxml.cpp +++ /dev/null @@ -1,339 +0,0 @@ -#include -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef HAVE_TIME_H -#include -#endif - -#ifdef HAVE_LIBXML2 -#include -#include -#include -#else -#define xmlChar char -#endif /* HAVE_LIBXML2 */ - -#define DE(x) ((struct nc_de_s *) (data+(x))) -#define IDE(x, y) (DE(((unsigned *) (data+(x)->offset))[(y)])) -#define XML_DE ((const xmlChar *) "dirEntry") -#define XML_NS ((const xmlChar *) "http://hq.alert.sk/projects/nconfig") -#define XML_ROOT ((const xmlChar *) "NConfigExport") - -static char *encodeXml(const char *what) -{ - unsigned p = 0, size = 6*strlen(what)+1; - char *ret = (char *)malloc(size); - for (; *what; what++) { - switch (*what) { - case '"': - ret[p++] = '&'; - ret[p++] = 'q'; - ret[p++] = 'u'; - ret[p++] = 'o'; - ret[p++] = 't'; - ret[p++] = ';'; - continue; - case '>': - ret[p++] = '&'; - ret[p++] = 'q'; - ret[p++] = 't'; - ret[p++] = ';'; - continue; - case '<': - ret[p++] = '&'; - ret[p++] = 'l'; - ret[p++] = 't'; - ret[p++] = ';'; - continue; - case '&': - ret[p++] = '&'; - ret[p++] = 'a'; - ret[p++] = 'm'; - ret[p++] = 'p'; - ret[p++] = ';'; - continue; - } - if (*what >= 0x20 || *what == '\n' || *what == '\r' || *what == '\t') - ret[p++] = *what; - else - p += sprintf(ret+p, "&#%d;", *what); - } - ret[p] = '\0'; - return ret; -} - -void NConfig::store(nc_de_s *de, FILE *f) -{ - struct nc_de_s *cc; - for (unsigned i=0; ipages; i++) - if ((cc = IDE(de, i))->type) { - char *encname = encodeXml(data+cc->name); - fprintf(f, "type); - free(encname); - switch (cc->type) { - case NC_DIR: - fprintf(f, "%u\">\n", cc->pages); - store(cc, f); - fprintf(f, "\n", XML_DE); - break; - case NC_STRING: - fprintf(f, "%s\"/>\n", encname = encodeXml(data+cc->offset)); - free(encname); - break; - case NC_INT: - fprintf(f, "%lld\"/>\n", *((signed long long *) (data+cc->offset))); - break; - case NC_UINT: - fprintf(f, "%llu\"/>\n", *((unsigned long long *) (data+cc->offset))); - break; - case NC_DOUBLE: - fprintf(f, "%La\"/>\n", *((long double *) (data+cc->offset))); - break; - case NC_RAW: - { - const char *raw = data+cc->offset; - for (unsigned j=0; jpages; j++) - fprintf(f, "%d%d%d", raw[j] / 100, (raw[j] % 100) / 10, raw[j] % 10); - fprintf(f, "\"/>\n"); - } - } - } -} - -int NConfig::toXML(const char *filename) -{ - if (fd < 0) - return NC_ERR_NFILE; - - FILE *f = fopen(filename, "w"); - if (!f) - return NC_ERR_PERM; - - fprintf(f, "%s", "\n"); - fprintf(f, "\n"); - lockFile(NC_L_RO); - - store(rdir, f); - - unLockFile(); - fprintf(f, "\n", XML_ROOT); - fclose(f); - return NC_ERR_OK; -} - -#ifdef HAVE_LIBXML2 -static xmlSAXHandler sh; -enum stateEnum {noRoot = 0, inRoot, inDir, inEnt, unknown}; - -struct ncParseState { - stateEnum state, pState; - xmlChar *ns; - unsigned depth; - unsigned unDepth; - unsigned force; - NConfig *which; -}; - -static int ncXmlSAXParseFile(xmlSAXHandlerPtr sax, void *user_data, const char *filename) -{ - int ret = 0; - xmlParserCtxtPtr ctxt = xmlCreateFileParserCtxt(filename); - if (!ctxt) - return -1; - ctxt->sax = sax; - ctxt->userData = user_data; - xmlParseDocument(ctxt); - ret = ctxt->wellFormed ? 0 : -1; - if (sax) - ctxt->sax = NULL; - xmlFreeParserCtxt(ctxt); - return ret; -} - -static xmlEntityPtr ncXmlGetEntity(void *user_data, const CHAR *name) -{ - return xmlGetPredefinedEntity(name); -} - -static void ncXmlStartElement(void *user_data, const CHAR *name, const CHAR **attrs) -{ - struct ncParseState *p = (struct ncParseState *)user_data; -#ifdef NC_DEBUG_XML - fprintf(stderr, "New element %s state=%d %s\n", name, p->state, p->ns); -#endif - if (p->state == unknown) { - p->unDepth++; - return; - } - if (p->state == noRoot) { - while (*attrs) { - if (!xmlStrncmp(*attrs, (const xmlChar *) "xmlns:", 6)) { - if (!xmlStrcmp(attrs[1], XML_NS)) { - p->ns = xmlStrdup((*attrs)+6); - break; - } - } - attrs += 2; - } - char *b = (char *) malloc(xmlStrlen(p->ns)+xmlStrlen(XML_ROOT)+2); - sprintf(b, "%s:%s", p->ns, XML_ROOT); - if (xmlStrcmp(name, (xmlChar *)b)) { -#ifdef NC_DEBUG_XML - fprintf(stderr, "NewElement, entering unknown %s\n", name); -#endif - p->pState = p->state; - p->state = unknown; - } else - p->state = inRoot; - free(b); - return; - } - if (p->state == inRoot || p->state == inDir) { - const xmlChar *value = NULL, *n = NULL; - int type = 0; - while (*attrs) { - if (!xmlStrcmp(*attrs, (const xmlChar *)"value")) - value = attrs[1]; - if (!xmlStrcmp(*attrs, (const xmlChar *)"name")) - n = attrs[1]; - if (!xmlStrcmp(*attrs, (const xmlChar *)"type")) - type = atoi(attrs[1]); - attrs += 2; - } -#ifdef NC_DEBUG_XML - fprintf(stderr, "%s %s %s %d %d\n", name, n, value, type, p->state); -#endif - char *b = (char *) malloc(xmlStrlen(p->ns)+xmlStrlen(XML_DE)+2); - sprintf(b, "%s:%s", p->ns, XML_DE); - if (xmlStrcmp(name, (xmlChar *)b) || !type || !value || !n) { -#ifdef NC_DEBUG_XML - fprintf(stderr, "NewElement, entering unknown on mismatch\n"); -#endif - p->pState = p->state; - p->state = unknown; - free(b); - return; - } - free(b); - if (p->force) - p->which->delKey((const char *)n); - - switch (type) { - case NC_DIR: - if (p->which->createDir((const char *)n, strtoul((const char *)value, NULL, 0)) != NC_ERR_OK) { - p->pState = p->state; - p->state = unknown; -#ifdef NC_DEBUG_XML - fprintf(stderr, "NewElement, entering unknown on failed mkdir\n"); -#endif - return; - } - p->which->chDir((const char *)n); - break; - case NC_STRING: - p->which->setKey((const char *)n, (const char *)value); - break; - case NC_INT: - p->which->setKey((const char *)n, strtoll((const char *)value, NULL, 0)); - break; - case NC_UINT: - p->which->setKey((const char *)n, strtoull((const char *)value, NULL, 0)); - break; - case NC_DOUBLE: - { - long double c; - sscanf((const char *)value, "%La", &c); - p->which->setKey((const char *)n, c); - } - break; - case NC_RAW: - { - unsigned size = xmlStrlen(value) / 3; - char *dec = NULL; - if (size) { - dec = (char *)malloc(size); - for (unsigned i=0, k=0; iwhich->setKey((const char *)n, dec, size); - free(dec); - } - } - if (type == NC_DIR) { - p->state = inDir; - p->depth++; - } else { - p->pState = p->state; - p->state = inEnt; - } - return; - } -} - -static void ncXmlEndElement(void *user_data, const CHAR *name) -{ - struct ncParseState *p = (struct ncParseState *)user_data; -#ifdef NC_DEBUG_XML - fprintf(stderr, "EndElement %s %s %d\n", name, p->ns, p->state); -#endif - if (p->state == inEnt) { - p->state = p->pState; - return; - } - if (p->state == unknown) { - if (p->unDepth) - p->unDepth--; - else - p->state = p->pState; - return; - } - if (p->state == inRoot) { - p->state = noRoot; - free(p->ns); - p->ns = NULL; - return; - } - if (p->state == inDir) { - p->depth--; - if (!p->depth) - p->state = inRoot; - p->which->chDir(".."); - } -} -#endif /* HAVE_LIBXML2 */ - -int NConfig::fromXML(const char *filename, int force) -{ - if (fd < 0) - return NC_ERR_NFILE; - if (omode != NC_O_RW) - return NC_ERR_PERM; -#ifndef HAVE_LIBXML2 - return NC_ERR_NOSUPPORT; -#else - struct ncParseState state = { noRoot, noRoot, NULL, 0, 0, force, this }; - sh.getEntity = ncXmlGetEntity; - sh.startElement = ncXmlStartElement; - sh.endElement = ncXmlEndElement; - - lockFile(NC_L_RW); - cdir = rdir; - int ret = ncXmlSAXParseFile(&sh, &state, filename); - cdir = rdir; - unLockFile(); - - return ret < 0 ? NC_ERR_NVAL : NC_ERR_OK; -#endif /* HAVE_LIBXML2 */ -} -