Fan.Sys.Uri.Decoder.decode C# (CSharp) Method

decode() private method

private decode ( ) : Decoder
return System.Text.Decoder
            internal Decoder decode()
            {
                string str = this.str;
                int len = str.Length;
                int pos = 0;

                // ==== scheme ====

                // scan the string from the beginning looking for either a
                // colon or any character which doesn't fit a valid scheme
                bool hasUpper = false;
                for (int i=0; i<len; ++i)
                {
                  int c = str[i];
                  if (isScheme(c)) { hasUpper |= isUpper(c); continue; }
                  if (c != ':') break;

                  // at this point we have a scheme; if we detected
                  // any upper case characters normalize to lowercase
                  pos = i + 1;
                  string scheme = str.Substring(0, i);
                  if (hasUpper) scheme = FanStr.lower(scheme);
                  this.scheme = scheme;
                  break;
                }

                // ==== authority ====

                // authority must start with //
                if (pos+1 < len && str[pos] == '/' && str[pos+1] == '/')
                {
                  // find end of authority which is /, ?, #, or end of string;
                  // while we're scanning look for @ and last colon which isn't
                  // inside an [] IPv6 literal
                  int authStart = pos+2, authEnd = len, at = -1, colon = -1;
                  for (int i=authStart; i<len; ++i)
                  {
                int c = str[i];
                if (c == '/' || c == '?' || c == '#') { authEnd = i; break; }
                else if (c == '@' && at < 0) { at = i; colon = -1; }
                else if (c == ':') colon = i;
                else if (c == ']') colon = -1;
                  }

                  // start with assumption that there is no userinfo or port
                  int hostStart = authStart, hostEnd = authEnd;

                  // if we found an @ symbol, parse out userinfo
                  if (at > 0)
                  {
                this.userInfo = substr(authStart, at, USER);
                hostStart = at+1;
                  }

                  // if we found an colon, parse out port
                  if (colon > 0)
                  {
                this.port = Long.valueOf(Convert.ToInt64(str.Substring(colon+1, authEnd-colon-1)));
                hostEnd = colon;
                  }

                  // host is everything left in the authority
                  this.host = substr(hostStart, hostEnd, HOST);
                  pos = authEnd;
                }

                // ==== path ====

                // scan the string looking '?' or '#' which ends the path
                // section; while we're scanning count the number of slashes
                int pathStart = pos, pathEnd = len, numSegs = 1, prev = 0;
                for (int i=pathStart; i<len; ++i)
                {
                  int c = str[i];
                  if (prev != '\\')
                  {
                if (c == '?' || c == '#') { pathEnd = i; break; }
                if (i != pathStart && c == '/') ++numSegs;
                prev = c;
                  }
                  else
                  {
                prev = (c != '\\') ? c : 0;
                  }
                }

                // we now have the complete path section
                this.pathStr = substr(pathStart, pathEnd, PATH);
                this.path = pathSegments(pathStr, numSegs);
                pos = pathEnd;

                // ==== query ====

                if (pos < len && str[pos] == '?')
                {
                  // look for end of query which is # or end of string
                  int queryStart = pos+1, queryEnd = len;
                  prev = 0;
                  for (int i=queryStart; i<len; ++i)
                  {
                int c = str[i];
                if (prev != '\\')
                {
                  if (c == '#') { queryEnd = i; break; }
                  prev = c;
                }
                else
                {
                  prev = (c != '\\') ? c : 0;
                }
                  }

                  // we now have the complete query section
                  this.queryStr = substr(queryStart, queryEnd, QUERY);
                  this.query = parseQuery(queryStr);
                  pos = queryEnd;
                }

                // ==== frag ====

                if (pos < len  && str[pos] == '#')
                {
                  this.frag = substr(pos+1, len, FRAG);
                }

                // === normalize ===
                normalize();
                return this;
            }