📄 uri.c.svn-base
字号:
} if (ret != 0) return(ret); if (*cur == '?') { cur++; ret = xmlParseURIQuery(uri, &cur); if (ret != 0) return(ret); } *str = cur; return(0);}/** * xmlParseAbsoluteURI: * @uri: pointer to an URI structure * @str: pointer to the string to analyze * * Parse an URI reference string and fills in the appropriate fields * of the @uri structure * * absoluteURI = scheme ":" ( hier_part | opaque_part ) * * Returns 0 or the error code */static intxmlParseAbsoluteURI(xmlURIPtr uri, const char **str) { int ret; const char *cur; if (str == NULL) return(-1); cur = *str; ret = xmlParseURIScheme(uri, str); if (ret != 0) return(ret); if (**str != ':') { *str = cur; return(1); } (*str)++; if (**str == '/') return(xmlParseURIHierPart(uri, str)); return(xmlParseURIOpaquePart(uri, str));}/** * xmlParseRelativeURI: * @uri: pointer to an URI structure * @str: pointer to the string to analyze * * Parse an relative URI string and fills in the appropriate fields * of the @uri structure * * relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ] * abs_path = "/" path_segments * net_path = "//" authority [ abs_path ] * rel_path = rel_segment [ abs_path ] * * Returns 0 or the error code */static intxmlParseRelativeURI(xmlURIPtr uri, const char **str) { int ret = 0; const char *cur; if (str == NULL) return(-1); cur = *str; if ((cur[0] == '/') && (cur[1] == '/')) { cur += 2; ret = xmlParseURIAuthority(uri, &cur); if (ret != 0) return(ret); if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } } else if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } else if (cur[0] != '#' && cur[0] != '?') { ret = xmlParseURIRelSegment(uri, &cur); if (ret != 0) return(ret); if (cur[0] == '/') { cur++; ret = xmlParseURIPathSegments(uri, &cur, 1); } } if (ret != 0) return(ret); if (*cur == '?') { cur++; ret = xmlParseURIQuery(uri, &cur); if (ret != 0) return(ret); } *str = cur; return(ret);}/** * xmlParseURIReference: * @uri: pointer to an URI structure * @str: the string to analyze * * Parse an URI reference string and fills in the appropriate fields * of the @uri structure * * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] * * Returns 0 or the error code */intxmlParseURIReference(xmlURIPtr uri, const char *str) { int ret; const char *tmp = str; if (str == NULL) return(-1); xmlCleanURI(uri); /* * Try first to parse absolute refs, then fallback to relative if * it fails. */ ret = xmlParseAbsoluteURI(uri, &str); if (ret != 0) { xmlCleanURI(uri); str = tmp; ret = xmlParseRelativeURI(uri, &str); } if (ret != 0) { xmlCleanURI(uri); return(ret); } if (*str == '#') { str++; ret = xmlParseURIFragment(uri, &str); if (ret != 0) return(ret); } if (*str != 0) { xmlCleanURI(uri); return(1); } return(0);}/** * xmlParseURI: * @str: the URI string to analyze * * Parse an URI * * URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ] * * Returns a newly build xmlURIPtr or NULL in case of error */xmlURIPtrxmlParseURI(const char *str) { xmlURIPtr uri; int ret; if (str == NULL) return(NULL); uri = xmlCreateURI(); if (uri != NULL) { ret = xmlParseURIReference(uri, str); if (ret) { xmlFreeURI(uri); return(NULL); } } return(uri);}/************************************************************************ * * * Public functions * * * ************************************************************************//** * xmlBuildURI: * @URI: the URI instance found in the document * @base: the base value * * Computes he final URI of the reference done by checking that * the given URI is valid, and building the final URI using the * base URI. This is processed according to section 5.2 of the * RFC 2396 * * 5.2. Resolving Relative References to Absolute Form * * Returns a new URI string (to be freed by the caller) or NULL in case * of error. */xmlChar *xmlBuildURI(const xmlChar *URI, const xmlChar *base) { xmlChar *val = NULL; int ret, len, indx, cur, out; xmlURIPtr ref = NULL; xmlURIPtr bas = NULL; xmlURIPtr res = NULL; /* * 1) The URI reference is parsed into the potential four components and * fragment identifier, as described in Section 4.3. * * NOTE that a completely empty URI is treated by modern browsers * as a reference to "." rather than as a synonym for the current * URI. Should we do that here? */ if (URI == NULL) ret = -1; else { if (*URI) { ref = xmlCreateURI(); if (ref == NULL) goto done; ret = xmlParseURIReference(ref, (const char *) URI); } else ret = 0; } if (ret != 0) goto done; if ((ref != NULL) && (ref->scheme != NULL)) { /* * The URI is absolute don't modify. */ val = xmlStrdup(URI); goto done; } if (base == NULL) ret = -1; else { bas = xmlCreateURI(); if (bas == NULL) goto done; ret = xmlParseURIReference(bas, (const char *) base); } if (ret != 0) { if (ref) val = xmlSaveUri(ref); goto done; } if (ref == NULL) { /* * the base fragment must be ignored */ if (bas->fragment != NULL) { xmlFree(bas->fragment); bas->fragment = NULL; } val = xmlSaveUri(bas); goto done; } /* * 2) If the path component is empty and the scheme, authority, and * query components are undefined, then it is a reference to the * current document and we are done. Otherwise, the reference URI's * query and fragment components are defined as found (or not found) * within the URI reference and not inherited from the base URI. * * NOTE that in modern browsers, the parsing differs from the above * in the following aspect: the query component is allowed to be * defined while still treating this as a reference to the current * document. */ res = xmlCreateURI(); if (res == NULL) goto done; if ((ref->scheme == NULL) && (ref->path == NULL) && ((ref->authority == NULL) && (ref->server == NULL))) { if (bas->scheme != NULL) res->scheme = xmlMemStrdup(bas->scheme); 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; } if (bas->path != NULL) res->path = xmlMemStrdup(bas->path); if (ref->query != NULL) res->query = xmlMemStrdup(ref->query); else if (bas->query != NULL) res->query = xmlMemStrdup(bas->query); if (ref->fragment != NULL) res->fragment = xmlMemStrdup(ref->fragment); goto step_7; } /* * 3) If the scheme component is defined, indicating that the reference * starts with a scheme name, then the reference is interpreted as an * absolute URI and we are done. Otherwise, the reference URI's * scheme is inherited from the base URI's scheme component. */ if (ref->scheme != NULL) { val = xmlSaveUri(ref); goto done; } if (bas->scheme != NULL) res->scheme = xmlMemStrdup(bas->scheme); if (ref->query != NULL) res->query = xmlMemStrdup(ref->query); if (ref->fragment != NULL) res->fragment = xmlMemStrdup(ref->fragment); /* * 4) If the authority component is defined, then the reference is a * network-path and we skip to step 7. Otherwise, the reference * URI's authority is inherited from the base URI's authority * component, which will also be undefined if the URI scheme does not * use an authority component. */ 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);}/** * 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){#if defined(_WIN32) && !defined(__CYGWIN__) int len = 0; int i = 0; xmlChar *p = NULL;#endif xmlChar *ret; xmlURIPtr uri; if (path == NULL) return(NULL); if ((uri = xmlParseURI((const char *) path)) != NULL) { xmlFreeURI(uri); return xmlStrdup(path); } uri = xmlCreateURI(); if (uri == NULL) { return(NULL); }#if defined(_WIN32) && !defined(__CYGWIN__) len = xmlStrlen(path); if ((len > 2) && IS_WINDOWS_PATH(path)) { uri->scheme = xmlStrdup(BAD_CAST "file"); uri->path = xmlMallocAtomic(len + 2); uri->path[0] = '/'; p = uri->path + 1; strncpy(p, path, len + 1); } else { uri->path = xmlStrdup(path); p = uri->path; } while (*p != '\0') { if (*p == '\\') *p = '/'; p++; }#else uri->path = (char *) xmlStrdup((const xmlChar *) path);#endif ret = xmlSaveUri(uri); xmlFreeURI(uri); return(ret);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -