mirror of
https://github.com/nim-lang/Nim.git
synced 2026-05-05 13:34:46 +00:00
Merge branch 'devel' into fix_bracket_expr
This commit is contained in:
@@ -1074,9 +1074,9 @@ when not defined(js):
|
||||
## for nice error messages.
|
||||
var p: JsonParser
|
||||
p.open(s, filename)
|
||||
defer: p.close()
|
||||
discard getTok(p) # read first token
|
||||
result = p.parseJson()
|
||||
p.close()
|
||||
|
||||
proc parseJson*(buffer: string): JsonNode =
|
||||
## Parses JSON from `buffer`.
|
||||
@@ -1203,6 +1203,17 @@ when isMainModule:
|
||||
testJson{["c", "d"]} = %true
|
||||
assert(testJson["c"]["d"].bval)
|
||||
|
||||
# make sure no memory leek when parsing invalid string
|
||||
let startMemory = getOccupiedMem()
|
||||
for i in 0 .. 10000:
|
||||
try:
|
||||
discard parseJson"""{ invalid"""
|
||||
except:
|
||||
discard
|
||||
# memory diff should less than 2M
|
||||
assert(abs(getOccupiedMem() - startMemory) < 2 * 1024 * 1024)
|
||||
|
||||
|
||||
# test `$`
|
||||
let stringified = $testJson
|
||||
let parsedAgain = parseJson(stringified)
|
||||
|
||||
@@ -533,6 +533,18 @@ proc getSockOpt*(socket: Socket, opt: SOBool, level = SOL_SOCKET): bool {.
|
||||
var res = getSockOptInt(socket.fd, cint(level), toCInt(opt))
|
||||
result = res != 0
|
||||
|
||||
proc getLocalAddr*(socket: Socket): (string, Port) =
|
||||
## Get the socket's local address and port number.
|
||||
##
|
||||
## This is high-level interface for `getsockname`:idx:.
|
||||
getLocalAddr(socket.fd, socket.domain)
|
||||
|
||||
proc getPeerAddr*(socket: Socket): (string, Port) =
|
||||
## Get the socket's peer address and port number.
|
||||
##
|
||||
## This is high-level interface for `getpeername`:idx:.
|
||||
getPeerAddr(socket.fd, socket.domain)
|
||||
|
||||
proc setSockOpt*(socket: Socket, opt: SOBool, value: bool, level = SOL_SOCKET) {.
|
||||
tags: [WriteIOEffect].} =
|
||||
## Sets option ``opt`` to a boolean value specified by ``value``.
|
||||
|
||||
@@ -371,6 +371,76 @@ proc getSockName*(socket: SocketHandle): Port =
|
||||
raiseOSError(osLastError())
|
||||
result = Port(rawsockets.ntohs(name.sin_port))
|
||||
|
||||
proc getLocalAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||
## returns the socket's local address and port number.
|
||||
##
|
||||
## Similar to POSIX's `getsockname`:idx:.
|
||||
case domain
|
||||
of AF_INET:
|
||||
var name: Sockaddr_in
|
||||
when useWinVersion:
|
||||
name.sin_family = int16(ord(AF_INET))
|
||||
else:
|
||||
name.sin_family = posix.AF_INET
|
||||
var namelen = sizeof(name).SockLen
|
||||
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||
addr(namelen)) == -1'i32:
|
||||
raiseOSError(osLastError())
|
||||
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
|
||||
of AF_INET6:
|
||||
var name: Sockaddr_in6
|
||||
when useWinVersion:
|
||||
name.sin6_family = int16(ord(AF_INET6))
|
||||
else:
|
||||
name.sin6_family = posix.AF_INET6
|
||||
var namelen = sizeof(name).SockLen
|
||||
if getsockname(socket, cast[ptr SockAddr](addr(name)),
|
||||
addr(namelen)) == -1'i32:
|
||||
raiseOSError(osLastError())
|
||||
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||
var buf: array[64, char]
|
||||
if inet_ntop(name.sin6_family.cint,
|
||||
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
||||
raiseOSError(osLastError())
|
||||
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
|
||||
else:
|
||||
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||
|
||||
proc getPeerAddr*(socket: SocketHandle, domain: Domain): (string, Port) =
|
||||
## returns the socket's peer address and port number.
|
||||
##
|
||||
## Similar to POSIX's `getpeername`:idx:
|
||||
case domain
|
||||
of AF_INET:
|
||||
var name: Sockaddr_in
|
||||
when useWinVersion:
|
||||
name.sin_family = int16(ord(AF_INET))
|
||||
else:
|
||||
name.sin_family = posix.AF_INET
|
||||
var namelen = sizeof(name).SockLen
|
||||
if getpeername(socket, cast[ptr SockAddr](addr(name)),
|
||||
addr(namelen)) == -1'i32:
|
||||
raiseOSError(osLastError())
|
||||
result = ($inet_ntoa(name.sin_addr), Port(rawsockets.ntohs(name.sin_port)))
|
||||
of AF_INET6:
|
||||
var name: Sockaddr_in6
|
||||
when useWinVersion:
|
||||
name.sin6_family = int16(ord(AF_INET6))
|
||||
else:
|
||||
name.sin6_family = posix.AF_INET6
|
||||
var namelen = sizeof(name).SockLen
|
||||
if getpeername(socket, cast[ptr SockAddr](addr(name)),
|
||||
addr(namelen)) == -1'i32:
|
||||
raiseOSError(osLastError())
|
||||
# Cannot use INET6_ADDRSTRLEN here, because it's a C define.
|
||||
var buf: array[64, char]
|
||||
if inet_ntop(name.sin6_family.cint,
|
||||
addr name, buf.cstring, sizeof(buf).int32).isNil:
|
||||
raiseOSError(osLastError())
|
||||
result = ($buf, Port(rawsockets.ntohs(name.sin6_port)))
|
||||
else:
|
||||
raiseOSError(OSErrorCode(-1), "invalid socket family in getLocalAddr")
|
||||
|
||||
proc getSockOptInt*(socket: SocketHandle, level, optname: int): int {.
|
||||
tags: [ReadIOEffect].} =
|
||||
## getsockopt for integer options.
|
||||
|
||||
@@ -21,9 +21,22 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
|
||||
return $buf
|
||||
|
||||
proc `$`(x: uint64): string =
|
||||
var buf: array [0..59, char]
|
||||
discard c_sprintf(buf, "%llu", x)
|
||||
return $buf
|
||||
if x == 0:
|
||||
result = "0"
|
||||
else:
|
||||
var buf: array [60, char]
|
||||
var i = 0
|
||||
var n = x
|
||||
while n != 0:
|
||||
let nn = n div 10'u64
|
||||
buf[i] = char(n - 10'u64 * nn + ord('0'))
|
||||
inc i
|
||||
n = nn
|
||||
|
||||
let half = i div 2
|
||||
# Reverse
|
||||
for t in 0 .. < half: swap(buf[t], buf[i-t-1])
|
||||
result = $buf
|
||||
|
||||
proc reprStrAux(result: var string, s: string) =
|
||||
if cast[pointer](s) == nil:
|
||||
@@ -294,4 +307,3 @@ when not defined(useNimRtl):
|
||||
reprAux(result, addr(p), typ, cl)
|
||||
add result, "\n"
|
||||
deinitReprClosure(cl)
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ type
|
||||
bytes*: array[0..15, char]
|
||||
|
||||
Sockaddr_in6* {.importc: "SOCKADDR_IN6",
|
||||
header: "winsock2.h".} = object
|
||||
header: "ws2tcpip.h".} = object
|
||||
sin6_family*: int16
|
||||
sin6_port*: int16 # unsigned
|
||||
sin6_flowinfo*: int32 # unsigned
|
||||
@@ -511,6 +511,9 @@ proc connect*(s: SocketHandle, name: ptr SockAddr, namelen: SockLen): cint {.
|
||||
proc getsockname*(s: SocketHandle, name: ptr SockAddr,
|
||||
namelen: ptr SockLen): cint {.
|
||||
stdcall, importc: "getsockname", dynlib: ws2dll.}
|
||||
proc getpeername*(s: SocketHandle, name: ptr SockAddr,
|
||||
namelen: ptr SockLen): cint {.
|
||||
stdcall, importc, dynlib: ws2dll.}
|
||||
proc getsockopt*(s: SocketHandle, level, optname: cint, optval: pointer,
|
||||
optlen: ptr SockLen): cint {.
|
||||
stdcall, importc: "getsockopt", dynlib: ws2dll.}
|
||||
@@ -572,6 +575,9 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
|
||||
proc inet_ntoa*(i: InAddr): cstring {.
|
||||
stdcall, importc, dynlib: ws2dll.}
|
||||
|
||||
proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
|
||||
stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
|
||||
|
||||
const
|
||||
MAXIMUM_WAIT_OBJECTS* = 0x00000040
|
||||
|
||||
|
||||
Reference in New Issue
Block a user