Make uri module usable for faster URI parsing:

- A version of parseUri that takes a uri as parameter and modifies it
- Export initUri so you can use the new parseUri better
- Avoid creating new strings
This commit is contained in:
def 2015-03-02 01:51:43 +01:00
commit 650a75beea

View file

@ -53,10 +53,10 @@ proc parseAuthority(authority: string, result: var Uri) =
while true: while true:
case authority[i] case authority[i]
of '@': of '@':
result.password = result.port swap result.password, result.port
result.port = "" result.port.setLen(0)
result.username = result.hostname swap result.username, result.hostname
result.hostname = "" result.hostname.setLen(0)
inPort = false inPort = false
of ':': of ':':
inPort = true inPort = true
@ -75,7 +75,7 @@ proc parsePath(uri: string, i: var int, result: var Uri) =
# The 'mailto' scheme's PATH actually contains the hostname/username # The 'mailto' scheme's PATH actually contains the hostname/username
if result.scheme.toLower == "mailto": if result.scheme.toLower == "mailto":
parseAuthority(result.path, result) parseAuthority(result.path, result)
result.path = "" result.path.setLen(0)
if uri[i] == '?': if uri[i] == '?':
i.inc # Skip '?' i.inc # Skip '?'
@ -85,13 +85,21 @@ proc parsePath(uri: string, i: var int, result: var Uri) =
i.inc # Skip '#' i.inc # Skip '#'
i.inc parseUntil(uri, result.anchor, {}, i) i.inc parseUntil(uri, result.anchor, {}, i)
proc initUri(): Uri = proc initUri*(): Uri =
## Initializes a URI.
result = Uri(scheme: "", username: "", password: "", hostname: "", port: "", result = Uri(scheme: "", username: "", password: "", hostname: "", port: "",
path: "", query: "", anchor: "") path: "", query: "", anchor: "")
proc parseUri*(uri: string): Uri = proc resetUri(uri: var Uri) =
## Parses a URI. for f in uri.fields:
result = initUri() when f is string:
f.setLen(0)
else:
f = false
proc parseUri*(uri: string, result: var Uri) =
## Parses a URI. The `result` variable will be cleared before.
resetUri(result)
var i = 0 var i = 0
@ -105,7 +113,7 @@ proc parseUri*(uri: string): Uri =
if uri[i] != ':': if uri[i] != ':':
# Assume this is a reference URI (relative URI) # Assume this is a reference URI (relative URI)
i = 0 i = 0
result.scheme = "" result.scheme.setLen(0)
parsePath(uri, i, result) parsePath(uri, i, result)
return return
i.inc # Skip ':' i.inc # Skip ':'
@ -124,6 +132,11 @@ proc parseUri*(uri: string): Uri =
# Path # Path
parsePath(uri, i, result) parsePath(uri, i, result)
proc parseUri*(uri: string): Uri =
## Parses a URI and returns it.
result = initUri()
parseUri(uri, result)
proc removeDotSegments(path: string): string = proc removeDotSegments(path: string): string =
var collection: seq[string] = @[] var collection: seq[string] = @[]
let endsWithSlash = path[path.len-1] == '/' let endsWithSlash = path[path.len-1] == '/'