optimized parseurl module a bit

This commit is contained in:
Araq 2012-02-01 23:55:22 +01:00
commit 4203aef827

View file

@ -12,59 +12,62 @@
import strutils import strutils
type type
TURL* = tuple[ ## represents a *Uniform Resource Locator* (URL) TUrl* = tuple[ ## represents a *Uniform Resource Locator* (URL)
## any optional component is "" if it does not exist ## any optional component is "" if it does not exist
scheme, username, password, scheme, username, password,
hostname, port, path, query, anchor: string] hostname, port, path, query, anchor: string]
proc parseUrl*(url: string): TURL = proc parseUrl*(url: string): TUrl =
var i: int = 0 var i = 0
var scheme, username, password: string = "" var scheme, username, password: string = ""
var hostname, port, path, query, anchor: string = "" var hostname, port, path, query, anchor: string = ""
var temp: string = "" var temp = ""
if url[i] != '/': #url isn't a relative path if url[i] != '/': # url isn't a relative path
while True: while True:
#Scheme # Scheme
if url[i] == ':': if url[i] == ':':
if url[i+1] == '/' and url[i+2] == '/': if url[i+1] == '/' and url[i+2] == '/':
scheme = temp scheme = temp
temp = "" temp.setlen(0)
inc(i, 3) #Skip the // inc(i, 3) # Skip the //
#Authority(username, password) # Authority(username, password)
if url[i] == '@': if url[i] == '@':
username = temp.split(':')[0] username = temp
if temp.split(':').len() > 1: let colon = username.find(':')
password = temp.split(':')[1] if colon >= 0:
temp = "" password = username.substr(colon+1)
username = username.substr(0, colon-1)
temp.setlen(0)
inc(i) #Skip the @ inc(i) #Skip the @
#hostname(subdomain, domain, port) # hostname(subdomain, domain, port)
if url[i] == '/' or url[i] == '\0': if url[i] == '/' or url[i] == '\0':
hostname = temp hostname = temp
if hostname.split(':').len() > 1: let colon = hostname.find(':')
port = hostname.split(':')[1] if colon >= 0:
hostname = hostname.split(':')[0] port = hostname.substr(colon+1)
hostname = hostname.substr(0, colon-1)
temp = "" temp.setlen(0)
break break
temp.add(url[i]) temp.add(url[i])
inc(i) inc(i)
if url[i] == '/': inc(i) # Skip the '/' if url[i] == '/': inc(i) # Skip the '/'
#Path # Path
while True: while True:
if url[i] == '?': if url[i] == '?':
path = temp path = temp
temp = "" temp.setlen(0)
if url[i] == '#': if url[i] == '#':
if temp[0] == '?': if temp[0] == '?':
query = temp query = temp
else: else:
path = temp path = temp
temp = "" temp.setlen(0)
if url[i] == '\0': if url[i] == '\0':
if temp[0] == '?': if temp[0] == '?':
@ -80,16 +83,25 @@ proc parseUrl*(url: string): TURL =
return (scheme, username, password, hostname, port, path, query, anchor) return (scheme, username, password, hostname, port, path, query, anchor)
proc `$`*(t: TURL): string = proc `$`*(u: TUrl): string =
## turns the URL `u` into its string representation.
result = "" result = ""
if t.scheme != "": result.add(t.scheme & "://") if u.scheme.len > 0:
if t.username != "": result.add(u.scheme)
if t.password != "": result.add("://")
result.add(t.username & ":" & t.password & "@") if u.username.len > 0:
else: result.add(u.username)
result.add(t.username & "@") if u.password.len > 0:
result.add(t.hostname) result.add(":")
if t.port != "": result.add(":" & t.port) result.add(u.password)
if t.path != "": result.add("/" & t.path) result.add("@")
result.add(t.query) result.add(u.hostname)
result.add(t.anchor) if u.port.len > 0:
result.add(":")
result.add(u.port)
if u.path.len > 0:
result.add("/")
result.add(u.path)
result.add(u.query)
result.add(u.anchor)