?? uri.c
字號:
/** * uri.c: set of generic URI related routines * * Reference: RFCs 2396, 2732 and 2373 * * See Copyright for the status of this software. * * daniel@veillard.com */#define IN_LIBXML#include "libxml.h"#include <string.h>#include <libxml/xmlmemory.h>#include <libxml/uri.h>#include <libxml/globals.h>#include <libxml/xmlerror.h>/************************************************************************ * * * Macros to differentiate various character type * * directly extracted from RFC 2396 * * * ************************************************************************//* * alpha = lowalpha | upalpha */#define IS_ALPHA(x) (IS_LOWALPHA(x) || IS_UPALPHA(x))/* * lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | * "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | * "u" | "v" | "w" | "x" | "y" | "z" */#define IS_LOWALPHA(x) (((x) >= 'a') && ((x) <= 'z'))/* * upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | * "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | * "U" | "V" | "W" | "X" | "Y" | "Z" */#define IS_UPALPHA(x) (((x) >= 'A') && ((x) <= 'Z'))#ifdef IS_DIGIT#undef IS_DIGIT#endif/* * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" */#define IS_DIGIT(x) (((x) >= '0') && ((x) <= '9'))/* * alphanum = alpha | digit */#define IS_ALPHANUM(x) (IS_ALPHA(x) || IS_DIGIT(x))/* * hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | * "a" | "b" | "c" | "d" | "e" | "f" */#define IS_HEX(x) ((IS_DIGIT(x)) || (((x) >= 'a') && ((x) <= 'f')) || \ (((x) >= 'A') && ((x) <= 'F')))/* * mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */#define IS_MARK(x) (((x) == '-') || ((x) == '_') || ((x) == '.') || \ ((x) == '!') || ((x) == '~') || ((x) == '*') || ((x) == '\'') || \ ((x) == '(') || ((x) == ')'))/* * reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | "," | * "[" | "]" */#define IS_RESERVED(x) (((x) == ';') || ((x) == '/') || ((x) == '?') || \ ((x) == ':') || ((x) == '@') || ((x) == '&') || ((x) == '=') || \ ((x) == '+') || ((x) == '$') || ((x) == ',') || ((x) == '[') || \ ((x) == ']'))/* * unreserved = alphanum | mark */#define IS_UNRESERVED(x) (IS_ALPHANUM(x) || IS_MARK(x))/* * escaped = "%" hex hex */#define IS_ESCAPED(p) ((*(p) == '%') && (IS_HEX((p)[1])) && \ (IS_HEX((p)[2])))/* * uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | * "&" | "=" | "+" | "$" | "," */#define IS_URIC_NO_SLASH(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) ||\ ((*(p) == ';')) || ((*(p) == '?')) || ((*(p) == ':')) ||\ ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) ||\ ((*(p) == '+')) || ((*(p) == '$')) || ((*(p) == ',')))/* * pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | "," */#define IS_PCHAR(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \ ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) ||\ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) ||\ ((*(p) == ',')))/* * rel_segment = 1*( unreserved | escaped | * ";" | "@" | "&" | "=" | "+" | "$" | "," ) */#define IS_SEGMENT(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \ ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || \ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \ ((*(p) == ',')))/* * scheme = alpha *( alpha | digit | "+" | "-" | "." ) */#define IS_SCHEME(x) ((IS_ALPHA(x)) || (IS_DIGIT(x)) || \ ((x) == '+') || ((x) == '-') || ((x) == '.'))/* * reg_name = 1*( unreserved | escaped | "$" | "," | * ";" | ":" | "@" | "&" | "=" | "+" ) */#define IS_REG_NAME(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \ ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || \ ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || \ ((*(p) == '=')) || ((*(p) == '+')))/* * userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" | * "+" | "$" | "," ) */#define IS_USERINFO(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \ ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) || \ ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || \ ((*(p) == ',')))/* * uric = reserved | unreserved | escaped */#define IS_URIC(p) ((IS_UNRESERVED(*(p))) || (IS_ESCAPED(p)) || \ (IS_RESERVED(*(p))))/* * unwise = "{" | "}" | "|" | "\" | "^" | "`"*/ #define IS_UNWISE(p) \ (((*(p) == '{')) || ((*(p) == '}')) || ((*(p) == '|')) || \ ((*(p) == '\\')) || ((*(p) == '^')) || ((*(p) == '[')) || \ ((*(p) == ']')) || ((*(p) == '`'))) /* * Skip to next pointer char, handle escaped sequences */#define NEXT(p) ((*p == '%')? p += 3 : p++)/* * Productions from the spec. * * authority = server | reg_name * reg_name = 1*( unreserved | escaped | "$" | "," | * ";" | ":" | "@" | "&" | "=" | "+" ) * * path = [ abs_path | opaque_part ] */#define STRNDUP(s, n) (char *) xmlStrndup((const xmlChar *)(s), (n))/************************************************************************ * * * Generic URI structure functions * * * ************************************************************************//** * xmlCreateURI: * * Simply creates an empty xmlURI * * Returns the new structure or NULL in case of error */xmlURIPtrxmlCreateURI(void) { xmlURIPtr ret; ret = (xmlURIPtr) xmlMalloc(sizeof(xmlURI)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlCreateURI: out of memory\n"); return(NULL); } memset(ret, 0, sizeof(xmlURI)); return(ret);}/** * xmlSaveUri: * @uri: pointer to an xmlURI * * Save the URI as an escaped string * * Returns a new string (to be deallocated by caller) */xmlChar *xmlSaveUri(xmlURIPtr uri) { xmlChar *ret = NULL; const char *p; int len; int max; if (uri == NULL) return(NULL); max = 80; ret = (xmlChar *) xmlMallocAtomic((max + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlSaveUri: out of memory\n"); return(NULL); } len = 0; if (uri->scheme != NULL) { p = uri->scheme; while (*p != 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++] = *p++; } 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++] = ':'; } if (uri->opaque != NULL) { p = uri->opaque; 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_RESERVED(*(p)) || IS_UNRESERVED(*(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'); } } } else { if (uri->server != 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++] = '/'; ret[len++] = '/'; if (uri->user != NULL) { p = uri->user; 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))) || ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '&')) || ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || ((*(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 + 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->server; while (*p != 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++] = *p++; } if (uri->port > 0) { if (len + 10 >= max) { max *= 2; ret = (xmlChar *) xmlRealloc(ret, (max + 1) * sizeof(xmlChar)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlSaveUri: out of memory\n"); return(NULL); } } len += snprintf((char *) &ret[len], max - len, ":%d", uri->port); } } else if (uri->authority != 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++] = '/'; ret[len++] = '/'; p = uri->authority; 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))) || ((*(p) == '$')) || ((*(p) == ',')) || ((*(p) == ';')) || ((*(p) == ':')) || ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) || ((*(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'); } } } else if (uri->scheme != 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++] = '/'; ret[len++] = '/'; } if (uri->path != NULL) { p = uri->path; 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))) || ((*(p) == '/')) || ((*(p) == ';')) || ((*(p) == '@')) || ((*(p) == '&')) || ((*(p) == '=')) || ((*(p) == '+')) || ((*(p) == '$')) || ((*(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 (uri->query_raw != NULL) { if (len + 1 >= 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->query_raw; while (*p != 0) { if (len + 1 >= 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++; } } else if (uri->query != 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->query; 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'); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -