⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 catalog.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
        return (NULL);    }#ifdef HAVE_STAT    size = info.st_size;#else    if (fseek(fd, 0, SEEK_END) || (size = ftell(fd)) == EOF || fseek(fd, 0, SEEK_SET)) {        /* File operations denied? ok, just close and return failure */        fclose(fd);        return (NULL);    }#endif    content = xmlMallocAtomic(size + 10);    if (content == NULL) {        xmlCatalogErrMemory("allocating catalog data");        return (NULL);    }#ifdef HAVE_STAT    len = read(fd, content, size);#else    len = fread(content, 1, size, fd);#endif    if (len < 0) {        xmlFree(content);        return (NULL);    }#ifdef HAVE_STAT    close(fd);#else    fclose(fd);#endif    content[len] = 0;    return(content);}/** * xmlCatalogNormalizePublic: * @pubID:  the public ID string * *  Normalizes the Public Identifier * * Implements 6.2. Public Identifier Normalization * from http://www.oasis-open.org/committees/entity/spec-2001-08-06.html * * Returns the new string or NULL, the string must be deallocated *         by the caller. */static xmlChar *xmlCatalogNormalizePublic(const xmlChar *pubID){    int ok = 1;    int white;    const xmlChar *p;    xmlChar *ret;    xmlChar *q;    if (pubID == NULL)        return(NULL);    white = 1;    for (p = pubID;*p != 0 && ok;p++) {        if (!xmlIsBlank_ch(*p))            white = 0;        else if (*p == 0x20 && !white)            white = 1;        else            ok = 0;    }    if (ok && !white)	/* is normalized */        return(NULL);    ret = xmlStrdup(pubID);    q = ret;    white = 0;    for (p = pubID;*p != 0;p++) {        if (xmlIsBlank_ch(*p)) {            if (q != ret)                white = 1;        } else {            if (white) {                *(q++) = 0x20;                white = 0;            }            *(q++) = *p;        }    }    *q = 0;    return(ret);}/************************************************************************ *									* *			The XML Catalog parser				* *									* ************************************************************************/static xmlCatalogEntryPtrxmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename);static voidxmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,	                   xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup);static xmlChar *xmlCatalogListXMLResolve(xmlCatalogEntryPtr catal, const xmlChar *pubID,	              const xmlChar *sysID);static xmlChar *xmlCatalogListXMLResolveURI(xmlCatalogEntryPtr catal, const xmlChar *URI);/** * xmlGetXMLCatalogEntryType: * @name:  the name * * lookup the internal type associated to an XML catalog entry name * * Returns the type associated with that name */static xmlCatalogEntryTypexmlGetXMLCatalogEntryType(const xmlChar *name) {    xmlCatalogEntryType type = XML_CATA_NONE;    if (xmlStrEqual(name, (const xmlChar *) "system"))	type = XML_CATA_SYSTEM;    else if (xmlStrEqual(name, (const xmlChar *) "public"))	type = XML_CATA_PUBLIC;    else if (xmlStrEqual(name, (const xmlChar *) "rewriteSystem"))	type = XML_CATA_REWRITE_SYSTEM;    else if (xmlStrEqual(name, (const xmlChar *) "delegatePublic"))	type = XML_CATA_DELEGATE_PUBLIC;    else if (xmlStrEqual(name, (const xmlChar *) "delegateSystem"))	type = XML_CATA_DELEGATE_SYSTEM;    else if (xmlStrEqual(name, (const xmlChar *) "uri"))	type = XML_CATA_URI;    else if (xmlStrEqual(name, (const xmlChar *) "rewriteURI"))	type = XML_CATA_REWRITE_URI;    else if (xmlStrEqual(name, (const xmlChar *) "delegateURI"))	type = XML_CATA_DELEGATE_URI;    else if (xmlStrEqual(name, (const xmlChar *) "nextCatalog"))	type = XML_CATA_NEXT_CATALOG;    else if (xmlStrEqual(name, (const xmlChar *) "catalog"))	type = XML_CATA_CATALOG;    return(type);}/** * xmlParseXMLCatalogOneNode: * @cur:  the XML node * @type:  the type of Catalog entry * @name:  the name of the node * @attrName:  the attribute holding the value * @uriAttrName:  the attribute holding the URI-Reference * @prefer:  the PUBLIC vs. SYSTEM current preference value * @cgroup:  the group which includes this node * * Finishes the examination of an XML tree node of a catalog and build * a Catalog entry from it. * * Returns the new Catalog entry node or NULL in case of error. */static xmlCatalogEntryPtrxmlParseXMLCatalogOneNode(xmlNodePtr cur, xmlCatalogEntryType type,			  const xmlChar *name, const xmlChar *attrName,			  const xmlChar *uriAttrName, xmlCatalogPrefer prefer,			  xmlCatalogEntryPtr cgroup) {    int ok = 1;    xmlChar *uriValue;    xmlChar *nameValue = NULL;    xmlChar *base = NULL;    xmlChar *URL = NULL;    xmlCatalogEntryPtr ret = NULL;    if (attrName != NULL) {	nameValue = xmlGetProp(cur, attrName);	if (nameValue == NULL) {	    xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,			  "%s entry lacks '%s'\n", name, attrName, NULL);	    ok = 0;	}    }    uriValue = xmlGetProp(cur, uriAttrName);    if (uriValue == NULL) {	xmlCatalogErr(ret, cur, XML_CATALOG_MISSING_ATTR,		"%s entry lacks '%s'\n", name, uriAttrName, NULL);	ok = 0;    }    if (!ok) {	if (nameValue != NULL)	    xmlFree(nameValue);	if (uriValue != NULL)	    xmlFree(uriValue);	return(NULL);    }    base = xmlNodeGetBase(cur->doc, cur);    URL = xmlBuildURI(uriValue, base);    if (URL != NULL) {	if (xmlDebugCatalogs > 1) {	    if (nameValue != NULL)		xmlGenericError(xmlGenericErrorContext,			"Found %s: '%s' '%s'\n", name, nameValue, URL);	    else		xmlGenericError(xmlGenericErrorContext,			"Found %s: '%s'\n", name, URL);	}	ret = xmlNewCatalogEntry(type, nameValue, uriValue, URL, prefer, cgroup);    } else {	xmlCatalogErr(ret, cur, XML_CATALOG_ENTRY_BROKEN,		"%s entry '%s' broken ?: %s\n", name, uriAttrName, uriValue);    }    if (nameValue != NULL)	xmlFree(nameValue);    if (uriValue != NULL)	xmlFree(uriValue);    if (base != NULL)	xmlFree(base);    if (URL != NULL)	xmlFree(URL);    return(ret);}/** * xmlParseXMLCatalogNode: * @cur:  the XML node * @prefer:  the PUBLIC vs. SYSTEM current preference value * @parent:  the parent Catalog entry * @cgroup:  the group which includes this node * * Examines an XML tree node of a catalog and build * a Catalog entry from it adding it to its parent. The examination can * be recursive. */static voidxmlParseXMLCatalogNode(xmlNodePtr cur, xmlCatalogPrefer prefer,	               xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup){    xmlChar *base = NULL;    xmlCatalogEntryPtr entry = NULL;    if (cur == NULL)        return;    if (xmlStrEqual(cur->name, BAD_CAST "group")) {        xmlChar *prop;	xmlCatalogPrefer pref = XML_CATA_PREFER_NONE;        prop = xmlGetProp(cur, BAD_CAST "prefer");        if (prop != NULL) {            if (xmlStrEqual(prop, BAD_CAST "system")) {                prefer = XML_CATA_PREFER_SYSTEM;            } else if (xmlStrEqual(prop, BAD_CAST "public")) {                prefer = XML_CATA_PREFER_PUBLIC;            } else {		xmlCatalogErr(parent, cur, XML_CATALOG_PREFER_VALUE,                              "Invalid value for prefer: '%s'\n",			      prop, NULL, NULL);            }            xmlFree(prop);	    pref = prefer;        }	prop = xmlGetProp(cur, BAD_CAST "id");	base = xmlGetNsProp(cur, BAD_CAST "base", XML_XML_NAMESPACE);	entry = xmlNewCatalogEntry(XML_CATA_GROUP, prop, base, NULL, pref, cgroup);	xmlFree(prop);    } else if (xmlStrEqual(cur->name, BAD_CAST "public")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_PUBLIC,		BAD_CAST "public", BAD_CAST "publicId", BAD_CAST "uri", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "system")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_SYSTEM,		BAD_CAST "system", BAD_CAST "systemId", BAD_CAST "uri", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteSystem")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_SYSTEM,		BAD_CAST "rewriteSystem", BAD_CAST "systemIdStartString",		BAD_CAST "rewritePrefix", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "delegatePublic")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_PUBLIC,		BAD_CAST "delegatePublic", BAD_CAST "publicIdStartString",		BAD_CAST "catalog", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateSystem")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_SYSTEM,		BAD_CAST "delegateSystem", BAD_CAST "systemIdStartString",		BAD_CAST "catalog", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "uri")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_URI,		BAD_CAST "uri", BAD_CAST "name",		BAD_CAST "uri", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "rewriteURI")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_REWRITE_URI,		BAD_CAST "rewriteURI", BAD_CAST "uriStartString",		BAD_CAST "rewritePrefix", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "delegateURI")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_DELEGATE_URI,		BAD_CAST "delegateURI", BAD_CAST "uriStartString",		BAD_CAST "catalog", prefer, cgroup);    } else if (xmlStrEqual(cur->name, BAD_CAST "nextCatalog")) {	entry = xmlParseXMLCatalogOneNode(cur, XML_CATA_NEXT_CATALOG,		BAD_CAST "nextCatalog", NULL,		BAD_CAST "catalog", prefer, cgroup);    }    if (entry != NULL) {        if (parent != NULL) {	    entry->parent = parent;	    if (parent->children == NULL)		parent->children = entry;	    else {		xmlCatalogEntryPtr prev;		prev = parent->children;		while (prev->next != NULL)		    prev = prev->next;		prev->next = entry;	    }	}	if (entry->type == XML_CATA_GROUP) {	    /*	     * Recurse to propagate prefer to the subtree	     * (xml:base handling is automated)	     */            xmlParseXMLCatalogNodeList(cur->children, prefer, parent, entry);	}    }    if (base != NULL)	xmlFree(base);}/** * xmlParseXMLCatalogNodeList: * @cur:  the XML node list of siblings * @prefer:  the PUBLIC vs. SYSTEM current preference value * @parent:  the parent Catalog entry * @cgroup:  the group which includes this list * * Examines a list of XML sibling nodes of a catalog and build * a list of Catalog entry from it adding it to the parent. * The examination will recurse to examine node subtrees. */static voidxmlParseXMLCatalogNodeList(xmlNodePtr cur, xmlCatalogPrefer prefer,	                   xmlCatalogEntryPtr parent, xmlCatalogEntryPtr cgroup) {    while (cur != NULL) {	if ((cur->ns != NULL) && (cur->ns->href != NULL) &&	    (xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {	    xmlParseXMLCatalogNode(cur, prefer, parent, cgroup);	}	cur = cur->next;    }    /* TODO: sort the list according to REWRITE lengths and prefer value */}/** * xmlParseXMLCatalogFile: * @prefer:  the PUBLIC vs. SYSTEM current preference value * @filename:  the filename for the catalog * * Parses the catalog file to extract the XML tree and then analyze the * tree to build a list of Catalog entries corresponding to this catalog *  * Returns the resulting Catalog entries list */static xmlCatalogEntryPtrxmlParseXMLCatalogFile(xmlCatalogPrefer prefer, const xmlChar *filename) {    xmlDocPtr doc;    xmlNodePtr cur;    xmlChar *prop;    xmlCatalogEntryPtr parent = NULL;    if (filename == NULL)        return(NULL);    doc = xmlParseCatalogFile((const char *) filename);    if (doc == NULL) {	if (xmlDebugCatalogs)	    xmlGenericError(xmlGenericErrorContext,		    "Failed to parse catalog %s\n", filename);	return(NULL);    }    if (xmlDebugCatalogs)	xmlGenericError(xmlGenericErrorContext,		"%d Parsing catalog %s\n", xmlGetThreadId(), filename);    cur = xmlDocGetRootElement(doc);    if ((cur != NULL) && (xmlStrEqual(cur->name, BAD_CAST "catalog")) &&	(cur->ns != NULL) && (cur->ns->href != NULL) &&	(xmlStrEqual(cur->ns->href, XML_CATALOGS_NAMESPACE))) {	parent = xmlNewCatalogEntry(XML_CATA_CATALOG, NULL,				    (const xmlChar *)filename, NULL, prefer, NULL);        if (parent == NULL) {	    xmlFreeDoc(doc);	    return(NULL);	}	prop = xmlGetProp(cur, BAD_CAST "prefer");	if (prop != NULL) {	    if (xmlStrEqual(prop, BAD_CAST "system")) {		prefer = XML_CATA_PREFER_SYSTEM;	    } else if (xmlStrEqual(prop, BAD_CAST "public")) {		prefer = XML_CATA_PREFER_PUBLIC;	    } else {		xmlCatalogErr(NULL, cur, XML_CATALOG_PREFER_VALUE,			      "Invalid value for prefer: '%s'\n",			      prop, NULL, NULL);	    }	    xmlFree(prop);	}	cur = cur->children;	xmlParseXMLCatalogNodeList(cur, prefer, parent, NULL);    } else {	xmlCatalogErr(NULL, (xmlNodePtr) doc, XML_CATALOG_NOT_CATALOG,		      "File %s is not an XML Catalog\n",		      filename, NULL, NULL);	xmlFreeDoc(doc);	return(NULL);    }    xmlFreeDoc(doc);    return(parent);}/** * xmlFetchXMLCatalogFile: * @catal:  an existing but incomplete catalog entry * * Fetch and parse the subcatalog referenced by an entry *  * Returns 0 in case of success, -1 otherwise */static intxmlFetchXMLCatalogFile(xmlCatalogEntryPtr catal) {    xmlCatalogEntryPtr doc;    if (catal == NULL) 	return(-1);    if (catal->URL == NULL)	return(-1);    if (catal->children != NULL)	return(-1);    /*     * lock the whole catalog for modification     */    xmlRMutexLock(xmlCatalogMutex);    if (catal->children != NULL) {	/* Okay someone else did it in the meantime */	xmlRMutexUnlock(xmlCatalogMutex);	return(0);    }    if (xmlCatalogXMLFiles != NULL) {	doc = (xmlCatalogEntryPtr)	    xmlHashLookup(xmlCatalogXMLFiles, catal->URL);	if (doc != NULL) {	    if (xmlDebugCatalogs)		xmlGenericError(xmlGenericErrorContext,		    "Found %s in file hash\n", catal->URL);	    if (catal->type == XML_CATA_CATALOG)		catal->children = doc->children;	    else		catal->children = doc;	    catal->dealloc = 0;	    xmlRMutexUnlock(xmlCatalogMutex);	    return(0);	}	if (xmlDebugCatalogs)	    xmlGenericError(xmlGenericErrorContext,		"%s not found in file hash\n", catal->URL);    }    /*     * Fetch and parse. Note that xmlParseXMLCatalogFile does not     * use the existing catalog, there is no recursion allowed at     * that level.     */    doc = xmlParseXMLCatalogFile(catal->prefer, catal->URL);    if (doc == NULL) {	catal->type = XML_CATA_BROKEN_CATALOG;	xmlRMutexUnlock(xmlCatalogMutex);	return(-1);    }    if (catal->type == XML_CATA_CATALOG)	catal->children = doc->children;    else	catal->children = doc;    doc->dealloc = 1;    if (xmlCatalogXMLFiles == NULL)	xmlCatalogXMLFiles = xmlHashCreate(10);    if (xmlCatalogXMLFiles != NULL) {	if (xmlDebugCatalogs)	    xmlGenericError(xmlGenericErrorContext,		"%s added to file hash\n", catal->URL);	xmlHashAddEntry(xmlCatalogXMLFiles, catal->URL, doc);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -