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

📄 uri.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
    if ((ref->authority != NULL) || (ref->server != NULL)) {	if (ref->authority != NULL)	    res->authority = xmlMemStrdup(ref->authority);	else {	    res->server = xmlMemStrdup(ref->server);	    if (ref->user != NULL)		res->user = xmlMemStrdup(ref->user);            res->port = ref->port;			}	if (ref->path != NULL)	    res->path = xmlMemStrdup(ref->path);	goto step_7;    }    if (bas->authority != NULL)	res->authority = xmlMemStrdup(bas->authority);    else if (bas->server != NULL) {	res->server = xmlMemStrdup(bas->server);	if (bas->user != NULL)	    res->user = xmlMemStrdup(bas->user);	res->port = bas->port;		    }    /*     * 5) If the path component begins with a slash character ("/"), then     *    the reference is an absolute-path and we skip to step 7.     */    if ((ref->path != NULL) && (ref->path[0] == '/')) {	res->path = xmlMemStrdup(ref->path);	goto step_7;    }    /*     * 6) If this step is reached, then we are resolving a relative-path     *    reference.  The relative path needs to be merged with the base     *    URI's path.  Although there are many ways to do this, we will     *    describe a simple method using a separate string buffer.     *     * Allocate a buffer large enough for the result string.     */    len = 2; /* extra / and 0 */    if (ref->path != NULL)	len += strlen(ref->path);    if (bas->path != NULL)	len += strlen(bas->path);    res->path = (char *) xmlMallocAtomic(len);    if (res->path == NULL) {	xmlGenericError(xmlGenericErrorContext,		"xmlBuildURI: out of memory\n");	goto done;    }    res->path[0] = 0;    /*     * a) All but the last segment of the base URI's path component is     *    copied to the buffer.  In other words, any characters after the     *    last (right-most) slash character, if any, are excluded.     */    cur = 0;    out = 0;    if (bas->path != NULL) {	while (bas->path[cur] != 0) {	    while ((bas->path[cur] != 0) && (bas->path[cur] != '/'))		cur++;	    if (bas->path[cur] == 0)		break;	    cur++;	    while (out < cur) {		res->path[out] = bas->path[out];		out++;	    }	}    }    res->path[out] = 0;    /*     * b) The reference's path component is appended to the buffer     *    string.     */    if (ref->path != NULL && ref->path[0] != 0) {	indx = 0;	/*	 * Ensure the path includes a '/'	 */	if ((out == 0) && (bas->server != NULL))	    res->path[out++] = '/';	while (ref->path[indx] != 0) {	    res->path[out++] = ref->path[indx++];	}    }    res->path[out] = 0;    /*     * Steps c) to h) are really path normalization steps     */    xmlNormalizeURIPath(res->path);step_7:    /*     * 7) The resulting URI components, including any inherited from the     *    base URI, are recombined to give the absolute form of the URI     *    reference.     */    val = xmlSaveUri(res);done:    if (ref != NULL)	xmlFreeURI(ref);    if (bas != NULL)	xmlFreeURI(bas);    if (res != NULL)	xmlFreeURI(res);    return(val);}/** * xmlBuildRelativeURI: * @URI:  the URI reference under consideration * @base:  the base value * * Expresses the URI of the reference in terms relative to the * base.  Some examples of this operation include: *     base = "http://site1.com/docs/book1.html" *        URI input                        URI returned *     docs/pic1.gif                    pic1.gif *     docs/img/pic1.gif                img/pic1.gif *     img/pic1.gif                     ../img/pic1.gif *     http://site1.com/docs/pic1.gif   pic1.gif *     http://site2.com/docs/pic1.gif   http://site2.com/docs/pic1.gif * *     base = "docs/book1.html" *        URI input                        URI returned *     docs/pic1.gif                    pic1.gif *     docs/img/pic1.gif                img/pic1.gif *     img/pic1.gif                     ../img/pic1.gif *     http://site1.com/docs/pic1.gif   http://site1.com/docs/pic1.gif * * * Note: if the URI reference is really wierd or complicated, it may be *       worthwhile to first convert it into a "nice" one by calling *       xmlBuildURI (using 'base') before calling this routine, *       since this routine (for reasonable efficiency) assumes URI has *       already been through some validation. * * Returns a new URI string (to be freed by the caller) or NULL in case * error. */xmlChar *xmlBuildRelativeURI (const xmlChar * URI, const xmlChar * base){    xmlChar *val = NULL;    int ret;    int ix;    int pos = 0;    int nbslash = 0;    int len;    xmlURIPtr ref = NULL;    xmlURIPtr bas = NULL;    xmlChar *bptr, *uptr, *vptr;    int remove_path = 0;    if ((URI == NULL) || (*URI == 0))	return NULL;    /*     * First parse URI into a standard form     */    ref = xmlCreateURI ();    if (ref == NULL)	return NULL;    /* If URI not already in "relative" form */    if (URI[0] != '.') {	ret = xmlParseURIReference (ref, (const char *) URI);	if (ret != 0)	    goto done;		/* Error in URI, return NULL */    } else	ref->path = (char *)xmlStrdup(URI);    /*     * Next parse base into the same standard form     */    if ((base == NULL) || (*base == 0)) {	val = xmlStrdup (URI);	goto done;    }    bas = xmlCreateURI ();    if (bas == NULL)	goto done;    if (base[0] != '.') {	ret = xmlParseURIReference (bas, (const char *) base);	if (ret != 0)	    goto done;		/* Error in base, return NULL */    } else	bas->path = (char *)xmlStrdup(base);    /*     * If the scheme / server on the URI differs from the base,     * just return the URI     */    if ((ref->scheme != NULL) &&	((bas->scheme == NULL) ||	 (xmlStrcmp ((xmlChar *)bas->scheme, (xmlChar *)ref->scheme)) ||	 (xmlStrcmp ((xmlChar *)bas->server, (xmlChar *)ref->server)))) {	val = xmlStrdup (URI);	goto done;    }    if (xmlStrEqual((xmlChar *)bas->path, (xmlChar *)ref->path)) {	val = xmlStrdup(BAD_CAST "");	goto done;    }    if (bas->path == NULL) {	val = xmlStrdup((xmlChar *)ref->path);	goto done;    }    if (ref->path == NULL) {        ref->path = (char *) "/";	remove_path = 1;    }    /*     * At this point (at last!) we can compare the two paths     *     * First we take care of the special case where either of the     * two path components may be missing (bug 316224)     */    if (bas->path == NULL) {	if (ref->path != NULL) {	    uptr = (xmlChar *) ref->path;	    if (*uptr == '/')		uptr++;	    val = xmlStrdup(uptr);	}	goto done;    }    bptr = (xmlChar *)bas->path;    if (ref->path == NULL) {	for (ix = 0; bptr[ix] != 0; ix++) {	    if (bptr[ix] == '/')		nbslash++;	}	uptr = NULL;	len = 1;	/* this is for a string terminator only */    } else {    /*     * Next we compare the two strings and find where they first differ     */	if ((ref->path[pos] == '.') && (ref->path[pos+1] == '/'))            pos += 2;	if ((*bptr == '.') && (bptr[1] == '/'))            bptr += 2;	else if ((*bptr == '/') && (ref->path[pos] != '/'))	    bptr++;	while ((bptr[pos] == ref->path[pos]) && (bptr[pos] != 0))	    pos++;	if (bptr[pos] == ref->path[pos]) {	    val = xmlStrdup(BAD_CAST "");	    goto done;		/* (I can't imagine why anyone would do this) */	}	/*	 * In URI, "back up" to the last '/' encountered.  This will be the	 * beginning of the "unique" suffix of URI	 */	ix = pos;	if ((ref->path[ix] == '/') && (ix > 0))	    ix--;	else if ((ref->path[ix] == 0) && (ix > 1) && (ref->path[ix - 1] == '/'))	    ix -= 2;	for (; ix > 0; ix--) {	    if (ref->path[ix] == '/')		break;	}	if (ix == 0) {	    uptr = (xmlChar *)ref->path;	} else {	    ix++;	    uptr = (xmlChar *)&ref->path[ix];	}	/*	 * In base, count the number of '/' from the differing point	 */	if (bptr[pos] != ref->path[pos]) {/* check for trivial URI == base */	    for (; bptr[ix] != 0; ix++) {		if (bptr[ix] == '/')		    nbslash++;	    }	}	len = xmlStrlen (uptr) + 1;    }        if (nbslash == 0) {	if (uptr != NULL)	    val = xmlStrdup (uptr);	goto done;    }    /*     * Allocate just enough space for the returned string -     * length of the remainder of the URI, plus enough space     * for the "../" groups, plus one for the terminator     */    val = (xmlChar *) xmlMalloc (len + 3 * nbslash);    if (val == NULL) {	xmlGenericError(xmlGenericErrorContext,		"xmlBuildRelativeURI: out of memory\n");	goto done;    }    vptr = val;    /*     * Put in as many "../" as needed     */    for (; nbslash>0; nbslash--) {	*vptr++ = '.';	*vptr++ = '.';	*vptr++ = '/';    }    /*     * Finish up with the end of the URI     */    if (uptr != NULL) {        if ((vptr > val) && (len > 0) &&	    (uptr[0] == '/') && (vptr[-1] == '/')) {	    memcpy (vptr, uptr + 1, len - 1);	    vptr[len - 2] = 0;	} else {	    memcpy (vptr, uptr, len);	    vptr[len - 1] = 0;	}    } else {	vptr[len - 1] = 0;    }done:    /*     * Free the working variables     */    if (remove_path != 0)        ref->path = NULL;    if (ref != NULL)	xmlFreeURI (ref);    if (bas != NULL)	xmlFreeURI (bas);    return val;}/** * xmlCanonicPath: * @path:  the resource locator in a filesystem notation * * Constructs a canonic path from the specified path.  * * Returns a new canonic path, or a duplicate of the path parameter if the  * construction fails. The caller is responsible for freeing the memory occupied * by the returned string. If there is insufficient memory available, or the  * argument is NULL, the function returns NULL. */#define IS_WINDOWS_PATH(p) 					\	((p != NULL) &&						\	 (((p[0] >= 'a') && (p[0] <= 'z')) ||			\	  ((p[0] >= 'A') && (p[0] <= 'Z'))) &&			\	 (p[1] == ':') && ((p[2] == '/') || (p[2] == '\\')))xmlChar *xmlCanonicPath(const xmlChar *path){/* * For Windows implementations, additional work needs to be done to * replace backslashes in pathnames with "forward slashes" */#if defined(_WIN32) && !defined(__CYGWIN__)        int len = 0;    int i = 0;    xmlChar *p = NULL;#endif    xmlURIPtr uri;    xmlChar *ret;    const xmlChar *absuri;    if (path == NULL)	return(NULL);    if ((uri = xmlParseURI((const char *) path)) != NULL) {	xmlFreeURI(uri);	return xmlStrdup(path);    }    /* Check if this is an "absolute uri" */    absuri = xmlStrstr(path, BAD_CAST "://");    if (absuri != NULL) {        int l, j;	unsigned char c;	xmlChar *escURI;        /*	 * this looks like an URI where some parts have not been	 * escaped leading to a parsing problem.  Check that the first	 * part matches a protocol.	 */	l = absuri - path;	/* Bypass if first part (part before the '://') is > 20 chars */	if ((l <= 0) || (l > 20))	    goto path_processing;	/* Bypass if any non-alpha characters are present in first part */	for (j = 0;j < l;j++) {	    c = path[j];	    if (!(((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))))	        goto path_processing;	}	/* Escape all except the characters specified in the supplied path */        escURI = xmlURIEscapeStr(path, BAD_CAST ":/?_.#&;=");	if (escURI != NULL) {	    /* Try parsing the escaped path */	    uri = xmlParseURI((const char *) escURI);	    /* If successful, return the escaped string */	    if (uri != NULL) {	        xmlFreeURI(uri);		return escURI;	    }	}    }path_processing:/* For Windows implementations, replace backslashes with 'forward slashes' */#if defined(_WIN32) && !defined(__CYGWIN__)        /*     * Create a URI structure     */    uri = xmlCreateURI();    if (uri == NULL) {		/* Guard against 'out of memory' */        return(NULL);    }    len = xmlStrlen(path);    if ((len > 2) && IS_WINDOWS_PATH(path)) {        /* make the scheme 'file' */	uri->scheme = xmlStrdup(BAD_CAST "file");	/* allocate space for leading '/' + path + string terminator */	uri->path = xmlMallocAtomic(len + 2);	if (uri->path == NULL) {	    xmlFreeURI(uri);	/* Guard agains 'out of memory' */	    return(NULL);	}	/* Put in leading '/' plus path */	uri->path[0] = '/';	p = uri->path + 1;	strncpy(p, path, len + 1);    } else {	uri->path = xmlStrdup(path);	if (uri->path == NULL) {	    xmlFreeURI(uri);	    return(NULL);	}	p = uri->path;    }    /* Now change all occurences of '\' to '/' */    while (*p != '\0') {	if (*p == '\\')	    *p = '/';	p++;    }    if (uri->scheme == NULL) {	ret = xmlStrdup((const xmlChar *) uri->path);    } else {	ret = xmlSaveUri(uri);    }    xmlFreeURI(uri);#else    ret = xmlStrdup((const xmlChar *) path);#endif    return(ret);}/** * xmlPathToURI: * @path:  the resource locator in a filesystem notation * * Constructs an URI expressing the existing path * * Returns a new URI, or a duplicate of the path parameter if the  * construction fails. The caller is responsible for freeing the memory * occupied by the returned string. If there is insufficient memory available, * or the argument is NULL, the function returns NULL. */xmlChar *xmlPathToURI(const xmlChar *path){    xmlURIPtr uri;    xmlURI temp;    xmlChar *ret, *cal;    if (path == NULL)        return(NULL);    if ((uri = xmlParseURI((const char *) path)) != NULL) {	xmlFreeURI(uri);	return xmlStrdup(path);    }    cal = xmlCanonicPath(path);    if (cal 

⌨️ 快捷键说明

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