mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 09:24:36 +00:00
added system.del; delete; insert
This commit is contained in:
@@ -17,7 +17,7 @@ type
|
||||
TResponse* = tuple[
|
||||
version: string, status: string, headers: seq[THeader],
|
||||
body: string]
|
||||
THeader* = tuple[htype: string, hvalue: string]
|
||||
THeader* = tuple[htype, hvalue: string]
|
||||
|
||||
EInvalidProtocol* = object of EBase ## exception that is raised when server
|
||||
## does not conform to the implemented
|
||||
@@ -54,20 +54,49 @@ proc getHeaderValue*(headers: seq[THeader], name: string): string =
|
||||
return headers[i].hvalue
|
||||
return ""
|
||||
|
||||
proc parseChunks(data: var string, start: int, s: TSocket): string =
|
||||
proc charAt(d: var string, i: var int, s: TSocket): char {.inline.} =
|
||||
result = d[i]
|
||||
while result == '\0':
|
||||
d = s.recv()
|
||||
i = 0
|
||||
result = d[i]
|
||||
|
||||
proc parseChunks(d: var string, start: int, s: TSocket): string =
|
||||
# get chunks:
|
||||
var i = start
|
||||
result = ""
|
||||
while true:
|
||||
var chunkSize = 0
|
||||
var j = parseHex(data, chunkSize, i)
|
||||
if j <= 0: break
|
||||
inc(i, j)
|
||||
while data[i] notin {'\C', '\L', '\0'}: inc(i)
|
||||
if data[i] == '\C': inc(i)
|
||||
if data[i] == '\L': inc(i)
|
||||
if chunkSize <= 0: break
|
||||
var x = copy(data, i, i+chunkSize-1)
|
||||
var digitFound = false
|
||||
echo "number: ", copy(d, i, i + 10)
|
||||
while true:
|
||||
case d[i]
|
||||
of '0'..'9':
|
||||
digitFound = true
|
||||
chunkSize = chunkSize shl 4 or (ord(d[i]) - ord('0'))
|
||||
of 'a'..'f':
|
||||
digitFound = true
|
||||
chunkSize = chunkSize shl 4 or (ord(d[i]) - ord('a') + 10)
|
||||
of 'A'..'F':
|
||||
digitFound = true
|
||||
chunkSize = chunkSize shl 4 or (ord(d[i]) - ord('A') + 10)
|
||||
of '\0':
|
||||
d = s.recv()
|
||||
i = -1
|
||||
else: break
|
||||
inc(i)
|
||||
|
||||
echo "chunksize: ", chunkSize
|
||||
if chunkSize <= 0:
|
||||
echo copy(d, i)
|
||||
assert digitFound
|
||||
break
|
||||
while charAt(d, i, s) notin {'\C', '\L', '\0'}: inc(i)
|
||||
if charAt(d, i, s) == '\C': inc(i)
|
||||
if charAt(d, i, s) == '\L': inc(i)
|
||||
else: httpError("CR-LF after chunksize expected")
|
||||
|
||||
var x = copy(d, i, i+chunkSize-1)
|
||||
var size = x.len
|
||||
result.add(x)
|
||||
|
||||
@@ -82,18 +111,17 @@ proc parseChunks(data: var string, start: int, s: TSocket): string =
|
||||
dec(missing, bytesRead)
|
||||
|
||||
# next chunk:
|
||||
data = s.recv()
|
||||
d = s.recv()
|
||||
i = 0
|
||||
# skip trailing CR-LF:
|
||||
while data[i] in {'\C', '\L'}: inc(i)
|
||||
if data[i] == '\0': data.add(s.recv())
|
||||
while charAt(d, i, s) in {'\C', '\L'}: inc(i)
|
||||
|
||||
proc parseBody(data: var string, start: int, s: TSocket,
|
||||
proc parseBody(d: var string, start: int, s: TSocket,
|
||||
headers: seq[THeader]): string =
|
||||
if getHeaderValue(headers, "Transfer-Encoding") == "chunked":
|
||||
result = parseChunks(data, start, s)
|
||||
result = parseChunks(d, start, s)
|
||||
else:
|
||||
result = copy(data, start)
|
||||
result = copy(d, start)
|
||||
# -REGION- Content-Length
|
||||
# (http://tools.ietf.org/html/rfc2616#section-4.4) NR.3
|
||||
var contentLengthHeader = getHeaderValue(headers, "Content-Length")
|
||||
@@ -112,7 +140,7 @@ proc parseBody(data: var string, start: int, s: TSocket,
|
||||
result.add(moreData)
|
||||
|
||||
proc parseResponse(s: TSocket): TResponse =
|
||||
var data = s.recv()
|
||||
var d = s.recv()
|
||||
var i = 0
|
||||
|
||||
# Parse the version
|
||||
@@ -120,8 +148,8 @@ proc parseResponse(s: TSocket): TResponse =
|
||||
# ``HTTP/1.1`` 200 OK
|
||||
|
||||
var matches: array[0..1, string]
|
||||
var L = data.matchLen(peg"\i 'HTTP/' {'1.1'/'1.0'} \s+ {(!\n .)*}\n",
|
||||
matches, i)
|
||||
var L = d.matchLen(peg"\i 'HTTP/' {'1.1'/'1.0'} \s+ {(!\n .)*}\n",
|
||||
matches, i)
|
||||
if L < 0: httpError("invalid HTTP header")
|
||||
|
||||
result.version = matches[0]
|
||||
@@ -135,29 +163,29 @@ proc parseResponse(s: TSocket): TResponse =
|
||||
result.headers = @[]
|
||||
while true:
|
||||
var key = ""
|
||||
while data[i] != ':':
|
||||
if data[i] == '\0': httpError("invalid HTTP header, ':' expected")
|
||||
key.add(data[i])
|
||||
while d[i] != ':':
|
||||
if d[i] == '\0': httpError("invalid HTTP header, ':' expected")
|
||||
key.add(d[i])
|
||||
inc(i)
|
||||
inc(i) # skip ':'
|
||||
if data[i] == ' ': inc(i) # skip if the character is a space
|
||||
if d[i] == ' ': inc(i) # skip if the character is a space
|
||||
var val = ""
|
||||
while data[i] notin {'\C', '\L', '\0'}:
|
||||
val.add(data[i])
|
||||
while d[i] notin {'\C', '\L', '\0'}:
|
||||
val.add(d[i])
|
||||
inc(i)
|
||||
|
||||
result.headers.add((key, val))
|
||||
|
||||
if data[i] == '\C': inc(i)
|
||||
if data[i] == '\L': inc(i)
|
||||
if d[i] == '\C': inc(i)
|
||||
if d[i] == '\L': inc(i)
|
||||
else: httpError("invalid HTTP header, CR-LF expected")
|
||||
|
||||
if data[i] == '\C': inc(i)
|
||||
if data[i] == '\L':
|
||||
if d[i] == '\C': inc(i)
|
||||
if d[i] == '\L':
|
||||
inc(i)
|
||||
break
|
||||
|
||||
result.body = parseBody(data, i, s, result.headers)
|
||||
result.body = parseBody(d, i, s, result.headers)
|
||||
|
||||
proc request*(url: string): TResponse =
|
||||
var r = parse(url)
|
||||
@@ -169,6 +197,8 @@ proc request*(url: string): TResponse =
|
||||
headers = "GET / HTTP/1.1\c\L"
|
||||
|
||||
add(headers, "Host: " & r.hostname & "\c\L\c\L")
|
||||
add(headers, "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; pl;" &
|
||||
" rv:1.9.2) Gecko/20100115 Firefox/3.6")
|
||||
|
||||
var s = socket()
|
||||
s.connect(r.hostname, TPort(80))
|
||||
@@ -210,4 +240,7 @@ proc downloadFile*(url: string, outputFilename: string) =
|
||||
|
||||
|
||||
when isMainModule:
|
||||
downloadFile("http://www.google.com", "GoogleTest.html")
|
||||
#downloadFile("http://force7.de/nimrod/index.html", "nimrodindex.html")
|
||||
#downloadFile("http://www.httpwatch.com/", "ChunkTest.html")
|
||||
downloadFile("http://www.httpwatch.com/httpgallery/chunked/", "ChunkTest.html")
|
||||
|
||||
|
||||
0
lib/pure/parseutils.nim
Normal file → Executable file
0
lib/pure/parseutils.nim
Normal file → Executable file
@@ -321,8 +321,8 @@ proc parseEntity(my: var TXmlParser, dest: var string) =
|
||||
elif buf[pos] == 'g' and buf[pos+1] == 't' and buf[pos+2] == ';':
|
||||
add(dest, '>')
|
||||
inc(pos, 2)
|
||||
elif buf[pos] == 'a' and buf[pos+1] == 'm' and buf[pos+2] == 'p'
|
||||
and buf[pos+3] == ';':
|
||||
elif buf[pos] == 'a' and buf[pos+1] == 'm' and buf[pos+2] == 'p' and
|
||||
buf[pos+3] == ';':
|
||||
add(dest, '&')
|
||||
inc(pos, 3)
|
||||
elif buf[pos] == 'a' and buf[pos+1] == 'p' and buf[pos+2] == 'o' and
|
||||
|
||||
@@ -698,6 +698,31 @@ proc add *[T](x: var seq[T], y: openArray[T]) {.noSideEffect.} =
|
||||
setLen(x, xl + y.len)
|
||||
for i in 0..high(y): x[xl+i] = y[i]
|
||||
|
||||
proc del* [T](x: var seq[T], i: int) {.noSideEffect.} =
|
||||
## deletes the item at index `i` by putting ``x[high(x)]`` into position `i`.
|
||||
## This is an O(1) operation.
|
||||
var xl = x.len
|
||||
x[i] = x[xl-1]
|
||||
setLen(x, xl-1)
|
||||
|
||||
proc delete*[T](x: var seq[T], i: int) {.noSideEffect.} =
|
||||
## deletes the item at index `i` by moving ``x[i+1..]`` by one position.
|
||||
## This is an O(n) operation.
|
||||
var xl = x.len
|
||||
for j in i..xl-2: x[j] = x[j+1]
|
||||
setLen(x, xl-1)
|
||||
|
||||
proc insert*[T](x: var seq[T], item: T, i = 0) {.noSideEffect.} =
|
||||
## inserts `item` into `x` at position `i`.
|
||||
var xl = x.len
|
||||
setLen(x, xl+1)
|
||||
var j = xl-1
|
||||
while j >= i:
|
||||
x[j+1] = x[j]
|
||||
inc(j)
|
||||
x[i] = item
|
||||
|
||||
|
||||
proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.}
|
||||
## takes any Nimrod variable and returns its string representation. It
|
||||
## works even for complex data graphs with cycles. This is a great
|
||||
|
||||
@@ -311,7 +311,8 @@ proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, maxRecDepth: int)
|
||||
toRope("align"), toRope(n.align),
|
||||
toRope("sons"), result])
|
||||
|
||||
proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int, maxRecDepth: int): PRope =
|
||||
proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int,
|
||||
maxRecDepth: int): PRope =
|
||||
var istr: PRope
|
||||
if n == nil:
|
||||
result = toRope("null")
|
||||
|
||||
Reference in New Issue
Block a user