private Uri slice(Range range, bool forcePathAbs)
{
if (m_pathStr == null)
throw Err.make("Uri has no path: " + this).val;
int size = m_path.sz();
int s = range.start(size);
int e = range.end(size);
int n = e - s + 1;
if (n < 0) throw IndexErr.make(range).val;
bool head = (s == 0);
bool tail = (e == size-1);
if (head && tail && (!forcePathAbs || isPathAbs())) return this;
Sections t = new Sections();
t.path = m_path.getRange(range);
StringBuilder sb = new StringBuilder(m_pathStr.Length);
if ((head && isPathAbs()) || forcePathAbs) sb.Append('/');
for (int i=0; i<t.path.sz(); ++i)
{
if (i > 0) sb.Append('/');
sb.Append(t.path.get(i));
}
if (t.path.sz() > 0 && (!tail || isDir())) sb.Append('/');
t.pathStr = sb.ToString();
if (head)
{
t.scheme = m_scheme;
t.userInfo = m_userInfo;
t.host = m_host;
t.port = m_port;
}
if (tail)
{
t.queryStr = m_queryStr;
t.query = m_query;
t.frag = m_frag;
}
else
{
t.query = emptyQuery();
}
if (!head && !tail)
{
t.str = t.pathStr;
}
return new Uri(t);
}