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

📄 uri.c

📁 xml开源解析代码.版本为libxml2-2.6.29,可支持GB3212.网络消息发送XML时很有用.
💻 C
📖 第 1 页 / 共 5 页
字号:
	    }	}    }    if (uri->fragment != NULL) {	if (len + 3 >= max) {	    max *= 2;	    ret = (xmlChar *) xmlRealloc(ret,		    (max + 1) * sizeof(xmlChar));	    if (ret == NULL) {		xmlGenericError(xmlGenericErrorContext,			"xmlSaveUri: out of memory\n");		return(NULL);	    }	}	ret[len++] = '#';	p = uri->fragment;	while (*p != 0) {	    if (len + 3 >= max) {		max *= 2;		ret = (xmlChar *) xmlRealloc(ret,			(max + 1) * sizeof(xmlChar));		if (ret == NULL) {		    xmlGenericError(xmlGenericErrorContext,			    "xmlSaveUri: out of memory\n");		    return(NULL);		}	    }	    if ((IS_UNRESERVED(*(p))) || (IS_RESERVED(*(p)))) 		ret[len++] = *p++;	    else {		int val = *(unsigned char *)p++;		int hi = val / 0x10, lo = val % 0x10;		ret[len++] = '%';		ret[len++] = hi + (hi > 9? 'A'-10 : '0');		ret[len++] = lo + (lo > 9? 'A'-10 : '0');	    }	}    }    if (len >= max) {	max *= 2;	ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar));	if (ret == NULL) {	    xmlGenericError(xmlGenericErrorContext,		    "xmlSaveUri: out of memory\n");	    return(NULL);	}    }    ret[len++] = 0;    return(ret);}/** * xmlPrintURI: * @stream:  a FILE* for the output * @uri:  pointer to an xmlURI * * Prints the URI in the stream @stream. */voidxmlPrintURI(FILE *stream, xmlURIPtr uri) {    xmlChar *out;    out = xmlSaveUri(uri);    if (out != NULL) {	fprintf(stream, "%s", (char *) out);	xmlFree(out);    }}/** * xmlCleanURI: * @uri:  pointer to an xmlURI * * Make sure the xmlURI struct is free of content */static voidxmlCleanURI(xmlURIPtr uri) {    if (uri == NULL) return;    if (uri->scheme != NULL) xmlFree(uri->scheme);    uri->scheme = NULL;    if (uri->server != NULL) xmlFree(uri->server);    uri->server = NULL;    if (uri->user != NULL) xmlFree(uri->user);    uri->user = NULL;    if (uri->path != NULL) xmlFree(uri->path);    uri->path = NULL;    if (uri->fragment != NULL) xmlFree(uri->fragment);    uri->fragment = NULL;    if (uri->opaque != NULL) xmlFree(uri->opaque);    uri->opaque = NULL;    if (uri->authority != NULL) xmlFree(uri->authority);    uri->authority = NULL;    if (uri->query != NULL) xmlFree(uri->query);    uri->query = NULL;    if (uri->query_raw != NULL) xmlFree(uri->query_raw);    uri->query_raw = NULL;}/** * xmlFreeURI: * @uri:  pointer to an xmlURI * * Free up the xmlURI struct */voidxmlFreeURI(xmlURIPtr uri) {    if (uri == NULL) return;    if (uri->scheme != NULL) xmlFree(uri->scheme);    if (uri->server != NULL) xmlFree(uri->server);    if (uri->user != NULL) xmlFree(uri->user);    if (uri->path != NULL) xmlFree(uri->path);    if (uri->fragment != NULL) xmlFree(uri->fragment);    if (uri->opaque != NULL) xmlFree(uri->opaque);    if (uri->authority != NULL) xmlFree(uri->authority);    if (uri->query != NULL) xmlFree(uri->query);    if (uri->query_raw != NULL) xmlFree(uri->query_raw);    xmlFree(uri);}/************************************************************************ *									* *			Helper functions				* *									* ************************************************************************//** * xmlNormalizeURIPath: * @path:  pointer to the path string * * Applies the 5 normalization steps to a path string--that is, RFC 2396 * Section 5.2, steps 6.c through 6.g. * * Normalization occurs directly on the string, no new allocation is done * * Returns 0 or an error code */intxmlNormalizeURIPath(char *path) {    char *cur, *out;    if (path == NULL)	return(-1);    /* Skip all initial "/" chars.  We want to get to the beginning of the     * first non-empty segment.     */    cur = path;    while (cur[0] == '/')      ++cur;    if (cur[0] == '\0')      return(0);    /* Keep everything we've seen so far.  */    out = cur;    /*     * Analyze each segment in sequence for cases (c) and (d).     */    while (cur[0] != '\0') {	/*	 * c) All occurrences of "./", where "." is a complete path segment,	 *    are removed from the buffer string.	 */	if ((cur[0] == '.') && (cur[1] == '/')) {	    cur += 2;	    /* '//' normalization should be done at this point too */	    while (cur[0] == '/')		cur++;	    continue;	}	/*	 * d) If the buffer string ends with "." as a complete path segment,	 *    that "." is removed.	 */	if ((cur[0] == '.') && (cur[1] == '\0'))	    break;	/* Otherwise keep the segment.  */	while (cur[0] != '/') {            if (cur[0] == '\0')              goto done_cd;	    (out++)[0] = (cur++)[0];	}	/* nomalize // */	while ((cur[0] == '/') && (cur[1] == '/'))	    cur++;        (out++)[0] = (cur++)[0];    } done_cd:    out[0] = '\0';    /* Reset to the beginning of the first segment for the next sequence.  */    cur = path;    while (cur[0] == '/')      ++cur;    if (cur[0] == '\0')	return(0);    /*     * Analyze each segment in sequence for cases (e) and (f).     *     * e) All occurrences of "<segment>/../", where <segment> is a     *    complete path segment not equal to "..", are removed from the     *    buffer string.  Removal of these path segments is performed     *    iteratively, removing the leftmost matching pattern on each     *    iteration, until no matching pattern remains.     *     * f) If the buffer string ends with "<segment>/..", where <segment>     *    is a complete path segment not equal to "..", that     *    "<segment>/.." is removed.     *     * To satisfy the "iterative" clause in (e), we need to collapse the     * string every time we find something that needs to be removed.  Thus,     * we don't need to keep two pointers into the string: we only need a     * "current position" pointer.     */    while (1) {        char *segp, *tmp;        /* At the beginning of each iteration of this loop, "cur" points to         * the first character of the segment we want to examine.         */        /* Find the end of the current segment.  */        segp = cur;        while ((segp[0] != '/') && (segp[0] != '\0'))          ++segp;        /* If this is the last segment, we're done (we need at least two         * segments to meet the criteria for the (e) and (f) cases).         */        if (segp[0] == '\0')          break;        /* If the first segment is "..", or if the next segment _isn't_ "..",         * keep this segment and try the next one.         */        ++segp;        if (((cur[0] == '.') && (cur[1] == '.') && (segp == cur+3))            || ((segp[0] != '.') || (segp[1] != '.')                || ((segp[2] != '/') && (segp[2] != '\0')))) {          cur = segp;          continue;        }        /* If we get here, remove this segment and the next one and back up         * to the previous segment (if there is one), to implement the         * "iteratively" clause.  It's pretty much impossible to back up         * while maintaining two pointers into the buffer, so just compact         * the whole buffer now.         */        /* If this is the end of the buffer, we're done.  */        if (segp[2] == '\0') {          cur[0] = '\0';          break;        }        /* Valgrind complained, strcpy(cur, segp + 3); */	/* string will overlap, do not use strcpy */	tmp = cur;	segp += 3;	while ((*tmp++ = *segp++) != 0);        /* If there are no previous segments, then keep going from here.  */        segp = cur;        while ((segp > path) && ((--segp)[0] == '/'))          ;        if (segp == path)          continue;        /* "segp" is pointing to the end of a previous segment; find it's         * start.  We need to back up to the previous segment and start         * over with that to handle things like "foo/bar/../..".  If we         * don't do this, then on the first pass we'll remove the "bar/..",         * but be pointing at the second ".." so we won't realize we can also         * remove the "foo/..".         */        cur = segp;        while ((cur > path) && (cur[-1] != '/'))          --cur;    }    out[0] = '\0';    /*     * g) If the resulting buffer string still begins with one or more     *    complete path segments of "..", then the reference is     *    considered to be in error. Implementations may handle this     *    error by retaining these components in the resolved path (i.e.,     *    treating them as part of the final URI), by removing them from     *    the resolved path (i.e., discarding relative levels above the     *    root), or by avoiding traversal of the reference.     *     * We discard them from the final path.     */    if (path[0] == '/') {      cur = path;      while ((cur[0] == '/') && (cur[1] == '.') && (cur[2] == '.')             && ((cur[3] == '/') || (cur[3] == '\0')))	cur += 3;      if (cur != path) {	out = path;	while (cur[0] != '\0')          (out++)[0] = (cur++)[0];	out[0] = 0;      }    }    return(0);}static int is_hex(char c) {    if (((c >= '0') && (c <= '9')) ||        ((c >= 'a') && (c <= 'f')) ||        ((c >= 'A') && (c <= 'F')))	return(1);    return(0);}/** * xmlURIUnescapeString: * @str:  the string to unescape * @len:   the length in bytes to unescape (or <= 0 to indicate full string) * @target:  optional destination buffer * * Unescaping routine, but does not check that the string is an URI. The * output is a direct unsigned char translation of %XX values (no encoding) * Note that the length of the result can only be smaller or same size as * the input string. * * Returns a copy of the string, but unescaped, will return NULL only in case * of error */char *xmlURIUnescapeString(const char *str, int len, char *target) {    char *ret, *out;    const char *in;    if (str == NULL)	return(NULL);    if (len <= 0) len = strlen(str);    if (len < 0) return(NULL);    if (target == NULL) {	ret = (char *) xmlMallocAtomic(len + 1);	if (ret == NULL) {	    xmlGenericError(xmlGenericErrorContext,		    "xmlURIUnescapeString: out of memory\n");	    return(NULL);	}    } else	ret = target;    in = str;    out = ret;    while(len > 0) {	if ((len > 2) && (*in == '%') && (is_hex(in[1])) && (is_hex(in[2]))) {	    in++;	    if ((*in >= '0') && (*in <= '9')) 	        *out = (*in - '0');	    else if ((*in >= 'a') && (*in <= 'f'))	        *out = (*in - 'a') + 10;	    else if ((*in >= 'A') && (*in <= 'F'))	        *out = (*in - 'A') + 10;	    in++;	    if ((*in >= '0') && (*in <= '9')) 	        *out = *out * 16 + (*in - '0');	    else if ((*in >= 'a') && (*in <= 'f'))	        *out = *out * 16 + (*in - 'a') + 10;	    else if ((*in >= 'A') && (*in <= 'F'))	        *out = *out * 16 + (*in - 'A') + 10;	    in++;	    len -= 3;	    out++;	} else {	    *out++ = *in++;	    len--;	}    }    *out = 0;    return(ret);}/** * xmlURIEscapeStr: * @str:  string to escape * @list: exception list string of chars not to escape * * This routine escapes a string to hex, ignoring reserved characters (a-z) * and the characters in the exception list. * * Returns a new escaped string or NULL in case of error. */xmlChar *xmlURIEscapeStr(const xmlChar *str, const xmlChar *list) {    xmlChar *ret, ch;    const xmlChar *in;    unsigned int len, out;    if (str == NULL)	return(NULL);    if (str[0] == 0)	return(xmlStrdup(str));    len = xmlStrlen(str);    if (!(len > 0)) return(NULL);    len += 20;    ret = (xmlChar *) xmlMallocAtomic(len);    if (ret == NULL) {	xmlGenericError(xmlGenericErrorContext,		"xmlURIEscapeStr: out of memory\n");	return(NULL);    }    in = (const xmlChar *) str;    out = 0;    while(*in != 0) {	if (len - out <= 3) {	    len += 20;	    ret = (xmlChar *) xmlRealloc(ret, len);	    if (ret == NULL) {		xmlGenericError(xmlGenericErrorContext,			"xmlURIEscapeStr: out of memory\n");		return(NULL);	    }	}	ch = *in;	if ((ch != '@') && (!IS_UNRESERVED(ch)) && (!xmlStrchr(list, ch))) {	    unsigned char val;	    ret[out++] = '%';	    val = ch >> 4;	    if (val <= 9)		ret[out++] = '0' + val;	    else		ret[out++] = 'A' + val - 0xA;	    val = ch & 0xF;	    if (val <= 9)		ret[out++] = '0' + val;	    else		ret[out++] = 'A' + val - 0xA;	    in++;	} else {	    ret[out++] = *in++;	}    }    ret[out] = 0;    return(ret);}/** * xmlURIEscape: * @str:  the string of the URI to escape * * Escaping routine, does not do validity checks ! * It will try to escape the chars needing this, but this is heuristic * based it's impossible to be sure. * * Returns an copy of the string, but escaped * * 25 May 2001 * Uses xmlParseURI and xmlURIEscapeStr to try to escape correctly * according to RFC2396. *   - Carl Douglas */xmlChar *xmlURIEscape(const xmlChar * str){    xmlChar *ret, *segment = NULL;    xmlURIPtr uri;    int ret2;#define NULLCHK(p) if(!p) { \                   xmlGenericError(xmlGenericErrorContext, \                        "xmlURIEscape: out of memory\n"); \                   return NULL; }    if (str == NULL)        return (NULL);    uri = xmlCreateURI();    if (uri != NULL) {	/*	 * Allow escaping errors in the unescaped form	 */        uri->cleanup = 1;        ret2 = xmlParseURIReference(uri, (const char *)str);        if (ret2) {            xmlFreeURI(uri);            return (NULL);        }    }    if (!uri)        return NULL;    ret = NULL;    if (uri->scheme) {        segment = xmlURIEscapeStr(BAD_CAST uri->scheme, BAD_CAST "+-.");        NULLCHK(segment)        ret = xmlStrcat(ret, segment);

⌨️ 快捷键说明

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