44 static char *StrNDup(
const char *z,
int n);
45 static void ReplaceStr(
char **pzDest,
const char *zSrc);
47 static char *Trim(
char *z);
54 TGHtmlUri::TGHtmlUri(
const char *zUri)
58 fZScheme = fZAuthority = fZPath = fZQuery = fZFragment = (
char *) 0;
61 while (isspace(*zUri)) ++zUri;
62 n = ComponentLength(zUri,
"",
":/?# ");
63 if (n > 0 && zUri[n] ==
':') {
64 fZScheme = StrNDup(zUri, n);
67 n = ComponentLength(zUri,
"//",
"/?# ");
69 fZAuthority = StrNDup(&zUri[2], n-2);
72 n = ComponentLength(zUri,
"",
"?# ");
74 fZPath = StrNDup(zUri, n);
77 n = ComponentLength(zUri,
"?",
"# ");
79 fZQuery = StrNDup(&zUri[1], n-1);
82 n = ComponentLength(zUri,
"#",
" ");
84 fZFragment = StrNDup(&zUri[1], n-1);
92 TGHtmlUri::TGHtmlUri(
const TGHtmlUri *uri)
94 fZScheme = fZAuthority = fZPath = fZQuery = fZFragment = (
char *) 0;
97 if (uri->fZScheme) fZScheme = StrDup(uri->fZScheme);
98 if (uri->fZAuthority) fZAuthority = StrDup(uri->fZAuthority);
99 if (uri->fZPath) fZPath = StrDup(uri->fZPath);
100 if (uri->fZQuery) fZQuery = StrDup(uri->fZQuery);
101 if (uri->fZFragment) fZFragment = StrDup(uri->fZFragment);
108 TGHtmlUri::~TGHtmlUri()
110 if (fZScheme)
delete[] fZScheme;
111 if (fZAuthority)
delete[] fZAuthority;
112 if (fZPath)
delete[] fZPath;
113 if (fZQuery)
delete[] fZQuery;
114 if (fZFragment)
delete[] fZFragment;
120 int TGHtmlUri::EqualsUri(
const TGHtmlUri *uri,
int field_mask)
124 if (field_mask & URI_SCHEME_MASK) {
125 if (uri->fZScheme && fZScheme) {
126 if (strcmp(uri->fZScheme, fZScheme) != 0)
return 0;
127 }
else if (uri->fZScheme != fZScheme) {
132 if (field_mask & URI_AUTH_MASK) {
133 if (uri->fZAuthority && fZAuthority) {
134 if (strcmp(uri->fZAuthority, fZAuthority) != 0)
return 0;
135 }
else if (uri->fZAuthority != fZAuthority) {
140 if (field_mask & URI_PATH_MASK) {
141 if (uri->fZPath && fZPath) {
142 if (strcmp(uri->fZPath, fZPath) != 0)
return 0;
143 }
else if (uri->fZPath != fZPath) {
148 if (field_mask & URI_QUERY_MASK) {
149 if (uri->fZQuery && fZQuery) {
150 if (strcmp(uri->fZQuery, fZQuery) != 0)
return 0;
151 }
else if (uri->fZQuery != fZQuery) {
156 if (field_mask & URI_FRAGMENT_MASK) {
157 if (uri->fZFragment && fZFragment) {
158 if (strcmp(uri->fZFragment, fZFragment) != 0)
return 0;
159 }
else if (uri->fZFragment != fZFragment) {
183 int TGHtmlUri::ComponentLength(
const char *z,
const char *zInit,
const char *zTerm)
187 for (n = 0; zInit[n]; ++n) {
188 if (zInit[n] != z[n])
return 0;
191 for (i = 0; zTerm[i]; ++i) {
192 if (z[n] == zTerm[i])
return n;
204 char *TGHtmlUri::BuildUri()
209 if (fZScheme) n += strlen(fZScheme) + 1;
210 if (fZAuthority) n += strlen(fZAuthority) + 3;
211 if (fZPath) n += strlen(fZPath) + 1;
212 if (fZQuery) n += strlen(fZQuery) + 1;
213 if (fZFragment) n += strlen(fZFragment) + 1;
215 if (z == 0)
return 0;
219 sprintf(z,
"%s:", fZScheme);
224 sprintf(&z[n],
"//%s", fZAuthority);
227 if (fZAuthority && fZAuthority[strlen(fZAuthority)-1] !=
'/' &&
228 !(fZPath && fZPath[0] ==
'/')) {
235 sprintf(&z[n],
"%s", fZPath);
240 sprintf(&z[n],
"?%s", fZQuery);
245 sprintf(&z[n],
"#%s", fZFragment);
257 static char *StrNDup(
const char *z,
int n)
261 if (n <= 0) n = strlen(z);
262 zResult =
new char[n + 1];
264 memcpy(zResult, z, n);
273 static void ReplaceStr(
char **pzDest,
const char *zSrc)
275 if (*pzDest != 0)
delete[] *pzDest;
279 *pzDest = StrNDup(zSrc, -1);
284 static char *Trim(
char *z)
291 while (isspace(*z)) z++;
293 zNew =
new char[i + 1];
294 if (zNew == 0)
return 0;
296 while (i > 0 && isspace(zNew[i-1])) zNew[--i] = 0;
307 char *TGHtml::ResolveUri(
const char *zUri)
310 TGHtmlUri *base, *term;
312 if (zUri == 0 || *zUri == 0)
return 0;
314 if (fZBaseHref && *fZBaseHref) {
315 base =
new TGHtmlUri(fZBaseHref);
317 base =
new TGHtmlUri(fZBase);
320 term =
new TGHtmlUri(zUri);
322 if (term->fZScheme == 0 &&
323 term->fZAuthority == 0 &&
325 term->fZQuery == 0 &&
327 ReplaceStr(&base->fZFragment, term->fZFragment);
328 }
else if (term->fZScheme) {
333 }
else if (term->fZAuthority) {
334 ReplaceStr(&base->fZAuthority, term->fZAuthority);
335 ReplaceStr(&base->fZPath, term->fZPath);
336 ReplaceStr(&base->fZQuery, term->fZQuery);
337 ReplaceStr(&base->fZFragment, term->fZFragment);
338 }
else if (term->fZPath && (term->fZPath[0] ==
'/' || base->fZPath == 0)) {
339 ReplaceStr(&base->fZPath, term->fZPath);
340 ReplaceStr(&base->fZQuery, term->fZQuery);
341 ReplaceStr(&base->fZFragment, term->fZFragment);
342 }
else if (term->fZPath && base->fZPath) {
345 zBuf =
new char[strlen(base->fZPath) + strlen(term->fZPath) + 2];
348 sprintf(zBuf,
"%s", base->fZPath);
349 for (i = strlen(zBuf) - 1; i >= 0 && zBuf[i] !=
'/'; --i) {
353 strcat(zBuf, term->fZPath);
354 for (i = 0; zBuf[i]; i++) {
355 if (zBuf[i] ==
'/' && zBuf[i+1] ==
'.' && zBuf[i+2] ==
'/') {
357 strcpy(&zBuf[i+1], &zBuf[i+3]);
361 if (zBuf[i] ==
'/' && zBuf[i+1] ==
'.' && zBuf[i+2] == 0) {
365 if (i > 0 && zBuf[i] ==
'/' && zBuf[i+1] ==
'.' &&
366 zBuf[i+2] ==
'.' && (zBuf[i+3] ==
'/' || zBuf[i+3] == 0)) {
367 for (j = i - 1; j >= 0 && zBuf[j] !=
'/'; --j) {}
370 strcpy(&zBuf[j+1], &zBuf[i+4]);
379 delete[] base->fZPath;
382 ReplaceStr(&base->fZQuery, term->fZQuery);
383 ReplaceStr(&base->fZFragment, term->fZFragment);
387 result = base->BuildUri();