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();