summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a65bc7a)
raw | patch | inline | side by side (parent: a65bc7a)
author | ishmal <ishmal@users.sourceforge.net> | |
Thu, 29 Mar 2007 21:06:58 +0000 (21:06 +0000) | ||
committer | ishmal <ishmal@users.sourceforge.net> | |
Thu, 29 Mar 2007 21:06:58 +0000 (21:06 +0000) |
src/dom/uri.cpp | patch | blob | history | |
src/dom/uri.h | patch | blob | history |
diff --git a/src/dom/uri.cpp b/src/dom/uri.cpp
index af808f40dfc99c508b6872d469d58ad818bea29e..d2b8be66a9c1206c87f843af08596e1d36c6905f 100644 (file)
--- a/src/dom/uri.cpp
+++ b/src/dom/uri.cpp
parsebuf = NULL;
parselen = 0;
scheme = SCHEME_NONE;
- schemeStr = "";
+ schemeStr.clear();
port = 0;
- authority = "";
- path = "";
+ authority.clear();
+ path.clear();
absolute = false;
opaque = false;
- query = "";
- fragment = "";
+ query.clear();
+ fragment.clear();
}
//#########################################################################
//#A T T R I B U T E S
//#########################################################################
+static char *hexChars = "0123456789abcdef";
+
+static DOMString toStr(const std::vector<int> &arr)
+{
+ DOMString buf;
+ std::vector<int>::const_iterator iter;
+ for (iter=arr.begin() ; iter!=arr.end() ; iter++)
+ {
+ int ch = *iter;
+ if (isprint(ch))
+ buf.push_back((XMLCh)ch);
+ else
+ {
+ buf.push_back('%');
+ int hi = ((ch>>4) & 0xf);
+ buf.push_back(hexChars[hi]);
+ int lo = ((ch ) & 0xf);
+ buf.push_back(hexChars[lo]);
+ }
+ }
+ return buf;
+}
+
DOMString URI::toString() const
{
if (authority.size() > 0)
{
str.append("//");
- str.append(authority);
+ str.append(toStr(authority));
}
- str.append(path);
+ str.append(toStr(path));
if (query.size() > 0)
{
str.append("?");
- str.append(query);
+ str.append(toStr(query));
}
if (fragment.size() > 0)
{
str.append("#");
- str.append(fragment);
+ str.append(toStr(fragment));
}
return str;
}
DOMString URI::getAuthority() const
{
- DOMString ret = authority;
+ DOMString ret = toStr(authority);
if (portSpecified && port>=0)
{
char buf[7];
DOMString URI::getHost() const
{
- return authority;
+ DOMString str = toStr(authority);
+ return str;
}
int URI::getPort() const
DOMString URI::getPath() const
{
- return path;
+ DOMString str = toStr(path);
+ return str;
}
DOMString URI::getNativePath() const
DOMString URI::getQuery() const
{
- return query;
+ DOMString str = toStr(query);
+ return str;
}
DOMString URI::getFragment() const
{
- return fragment;
+ DOMString str = toStr(fragment);
+ return str;
+}
+
+
+
+
+static int find(const std::vector<int> &str, int ch, int startpos)
+{
+ for (unsigned int i = startpos ; i < str.size() ; i++)
+ {
+ if (ch == str[i])
+ return i;
+ }
+ return -1;
+}
+
+
+static int findLast(const std::vector<int> &str, int ch)
+{
+ for (unsigned int i = str.size()-1 ; i>=0 ; i--)
+ {
+ if (ch == str[i])
+ return i;
+ }
+ return -1;
+}
+
+
+static bool sequ(const std::vector<int> &str, char *key)
+{
+ char *c = key;
+ for (unsigned int i=0 ; i<str.size() ; i++)
+ {
+ if (! (*c))
+ return false;
+ if (*c != str[i])
+ return false;
+ }
+ return true;
+}
+
+
+static std::vector<int> substr(const std::vector<int> &str,
+ int startpos, int len)
+{
+ std::vector<int> buf;
+ unsigned int pos = startpos;
+ for (int i=0 ; i<len ; i++)
+ {
+ if (pos >= str.size())
+ break;
+ buf.push_back(str[pos++]);
+ }
+ return buf;
}
}
else
{
- DOMString::size_type pos = path.find_last_of('/');
- if (pos != path.npos)
+ int pos = findLast(path, '/');
+ if (pos >= 0)
{
- DOMString tpath = path.substr(0, pos+1);
- tpath.append(other.path);
- newUri.path = tpath;
+ newUri.path.clear();
+ //# append my path up to the /
+ for (int i = 0; i<pos+1 ; i++)
+ newUri.path.push_back(path[i]);
+ //# append other path
+ for (unsigned int i = 0; i<other.path.size() ; i++)
+ newUri.path.push_back(other.path[i]);
}
else
newUri.path = other.path;
}
newUri.normalize();
+
return newUri;
}
*/
void URI::normalize()
{
- std::vector<DOMString> segments;
+ std::vector< std::vector<int> > segments;
//## Collect segments
if (path.size()<2)
return;
bool abs = false;
- unsigned int pos=0;
+ int pos=0;
+ int len = (int) path.size();
+
if (path[0]=='/')
{
abs = true;
pos++;
}
- while (pos < path.size())
+
+ while (pos < len)
{
- DOMString::size_type pos2 = path.find('/', pos);
- if (pos2==path.npos)
+ int pos2 = find(path, '/', pos);
+ if (pos2 < 0)
{
- DOMString seg = path.substr(pos);
- //printf("last segment:%s\n", seg.c_str());
+ std::vector<int> seg = substr(path, pos, path.size()-pos);
+ //printf("last segment:%s\n", toStr(seg).c_str());
segments.push_back(seg);
break;
}
if (pos2>pos)
{
- DOMString seg = path.substr(pos, pos2-pos);
- //printf("segment:%s\n", seg.c_str());
+ std::vector<int> seg = substr(path, pos, pos2-pos);
+ //printf("segment:%s\n", toStr(seg).c_str());
segments.push_back(seg);
}
pos = pos2;
//## Clean up (normalize) segments
bool edited = false;
- std::vector<DOMString>::iterator iter;
+ std::vector< std::vector<int> >::iterator iter;
for (iter=segments.begin() ; iter!=segments.end() ; )
{
- DOMString s = *iter;
- if (s == ".")
+ std::vector<int> s = *iter;
+ if (sequ(s,"."))
{
iter = segments.erase(iter);
edited = true;
}
- else if (s == ".." &&
- iter != segments.begin() &&
- *(iter-1) != "..")
+ else if (sequ(s, "..") && iter != segments.begin() &&
+ !sequ(*(iter-1), ".."))
{
iter--; //back up, then erase two entries
iter = segments.erase(iter);
path.clear();
if (abs)
{
- path.append("/");
+ path.push_back('/');
}
- std::vector<DOMString>::iterator iter;
+ std::vector< std::vector<int> >::iterator iter;
for (iter=segments.begin() ; iter!=segments.end() ; iter++)
{
if (iter != segments.begin())
- path.append("/");
- path.append(*iter);
+ path.push_back('/');
+ std::vector<int> seg = *iter;
+ for (unsigned int i = 0; i<seg.size() ; i++)
+ path.push_back(seg[i]);
}
}
int val = 0;
//# Upper 4
- XMLCh ch = peek(p);
+ int ch = peek(p);
if (ch >= '0' && ch <= '9')
val += (ch - '0');
else if (ch >= 'a' && ch <= 'f')
error("parseHex : unexpected character : %c", ch);
return -1;
}
+ p++;
result = val;
return p;
}
int URI::parseEntity(int p0, int &result)
{
int p = p0;
- XMLCh ch = peek(p);
+ int ch = peek(p);
if (ch != '&')
return p0;
p++;
p = parseHex(p, val);
if (p<0)
return -1;
+ ch = peek(p);
+ if (ch != ';')
+ {
+ error("parseEntity: expected ';'");
+ return -1;
+ }
+ p++;
result = val;
return p;
}
int URI::parseAsciiEntity(int p0, int &result)
{
int p = p0;
- XMLCh ch = peek(p);
+ int ch = peek(p);
if (ch != '%')
return p0;
p++;
ch = peek(p);
if (ch == '/')
break;
+ else if (ch == '&') //IRI entity
+ {
+ int val;
+ p2 = parseEntity(p, val);
+ if (p2<p)
+ {
+ return -1;
+ }
+ p = p2;
+ authority.push_back((XMLCh)val);
+ }
+ else if (ch == '%') //ascii hex excape
+ {
+ int val;
+ p2 = parseAsciiEntity(p, val);
+ if (p2<p)
+ {
+ return -1;
+ }
+ p = p2;
+ authority.push_back((XMLCh)val);
+ }
else if (ch == ':')
+ {
portSpecified = true;
+ p++;
+ }
else if (portSpecified)
+ {
portStr.push_back((XMLCh)ch);
+ p++;
+ }
else
+ {
authority.push_back((XMLCh)ch);
- p++;
+ p++;
+ }
}
if (portStr.size() > 0)
{
p++;
}
}
-
+ //trace("path:%s", toStr(path).c_str());
return p;
}
ch = peek(p);
if (ch == '?')
break;
- fragment.push_back((XMLCh)ch);
+ fragment.push_back(ch);
p++;
}
{
parselen = str.size();
+ parsebuf = new int[str.size()];
+ if (!parsebuf)
+ {
+ error("parse : could not allocate parsebuf");
+ return false;
+ }
- DOMString tmp;
- for (unsigned int i=0 ; i<str.size() ; i++)
+ DOMString::const_iterator iter;
+ unsigned int i=0;
+ for (iter= str.begin() ; iter!=str.end() ; iter++)
{
- XMLCh ch = (XMLCh) str[i];
+ int ch = *iter;
if (ch == '\\')
- tmp.push_back((XMLCh)'/');
+ parsebuf[i++] = '/';
else
- tmp.push_back(ch);
+ parsebuf[i++] = ch;
}
- parsebuf = (char *) tmp.c_str();
int p = parse(0);
normalize();
+ delete[] parsebuf;
+
if (p < 0)
{
error("Syntax error");
}
//printf("uri:%s\n", toString().c_str());
- //printf("path:%s\n", path.c_str());
+ //printf("parse:%s\n", toStr(path).c_str());
return true;
diff --git a/src/dom/uri.h b/src/dom/uri.h
index 57c5c5554e68b35109bfede589b05d2912cd9037..87a287b39b476fc9425e58dceded57ade800ac88 100644 (file)
--- a/src/dom/uri.h
+++ b/src/dom/uri.h
DOMString schemeStr;
- DOMString authority;
+ std::vector<int> authority;
bool portSpecified;
int port;
- DOMString path;
+ std::vector<int> path;
bool absolute;
bool opaque;
- DOMString query;
+ std::vector<int> query;
- DOMString fragment;
+ std::vector<int> fragment;
void error(const char *fmt, ...)
#ifdef G_GNUC_PRINTF
int parse(int p);
- char *parsebuf;
+ int *parsebuf;
int parselen;