diff options
author | bptato <nincsnevem662@gmail.com> | 2022-12-10 22:50:23 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-12-10 22:50:23 +0100 |
commit | 940325abfc9714b06de920a2a7f8911eae22f357 (patch) | |
tree | 9651d5f1d22e3eaa6b098b6bbed97a583244375d /src/ips | |
parent | 5c267ce6c9c1add997767f5eaad248cdd829c6fc (diff) | |
download | chawan-940325abfc9714b06de920a2a7f8911eae22f357.tar.gz |
Fix blocking socketstream recv/send, clean up ips/serialize & types/color
Write always blocks for now, as it's too big of a footgun not to
Diffstat (limited to 'src/ips')
-rw-r--r-- | src/ips/serialize.nim | 370 | ||||
-rw-r--r-- | src/ips/socketstream.nim | 17 |
2 files changed, 235 insertions, 152 deletions
diff --git a/src/ips/serialize.nim b/src/ips/serialize.nim index 09754466..73320b27 100644 --- a/src/ips/serialize.nim +++ b/src/ips/serialize.nim @@ -1,6 +1,7 @@ # Write data to streams. import options +import sets import streams import tables @@ -8,152 +9,122 @@ import buffer/cell import io/request import js/regex import types/buffersource -import types/color import types/url -proc slen*[T](o: T): int = - when T is string: - return slen(o.len) + o.len - elif T is bool: - return sizeof(char) - elif T is URL: - return ($o).slen - elif T is seq: - result = slen(o.len) - for x in o: - result += slen(x) - elif T is Option: - result = slen(o.isSome) - if o.isSome: - result += slen(o.get) - elif T is MimePart: - result += slen(o.isFile) - result += slen(o.name) - result += slen(o.content) - if o.isFile: - result += slen(o.filename) - result += slen(o.contentType) - result += slen(o.fileSize) - result += slen(o.isStream) - elif T is Request: - result += slen(o.httpmethod) - result += slen(o.url) - result += slen(o.headers) - result += slen(o.body) - result += slen(o.multipart) - elif T is CellColor: - result += slen(o.rgb) - if o.rgb: - result += slen(o.rgbcolor) - else: - result += slen(o.color) - elif T is Regex: - result += slen(o.plen) - result += o.plen - result += slen(o.buf) - elif T is BufferSource: - result += slen(o.t) - case o.t - of CLONE: result += slen(o.clonepid) - of LOAD_REQUEST: result += slen(o.request) - of LOAD_PIPE: result += slen(o.fd) - result += slen(o.location) - result += slen(o.contenttype) - elif T is tuple: - for f in o.fields: - result += slen(f) - elif T is object: - for f in o.fields: - result += slen(f) - elif T is ref object: - result += slen(o[]) - else: - result += sizeof(o) +proc swrite*(stream: Stream, n: SomeNumber) +proc sread*(stream: Stream, n: var SomeNumber) +func slen*(n: SomeNumber): int -template swrite*[T](stream: Stream, o: T) = - stream.write(o) +proc swrite*[T](stream: Stream, s: set[T]) +proc sread*[T](stream: Stream, s: var set[T]) +func slen*[T](s: set[T]): int -proc swrite*(stream: Stream, s: string) = - stream.swrite(s.len) - stream.write(s) +proc swrite*[T: enum](stream: Stream, x: T) +proc sread*[T: enum](stream: Stream, x: var T) +func slen*[T: enum](x: T): int -proc swrite*(stream: Stream, b: bool) = - if b: - stream.swrite(1u8) - else: - stream.swrite(0u8) +proc swrite*(stream: Stream, s: string) +proc sread*(stream: Stream, s: var string) +func slen*(s: string): int -proc swrite*(stream: Stream, url: Url) = - stream.swrite(url.serialize()) +proc swrite*(stream: Stream, b: bool) +proc sread*(stream: Stream, b: var bool) +func slen*(b: bool): int -proc swrite*(stream: Stream, tup: tuple) = - for f in tup.fields: - stream.swrite(f) +proc swrite*(stream: Stream, url: Url) +proc sread*(stream: Stream, url: var Url) +func slen*(url: Url): int -proc swrite*[T](stream: Stream, s: seq[T]) = - stream.swrite(s.len) - for m in s: - stream.swrite(m) +proc swrite*(stream: Stream, tup: tuple) +proc sread*(stream: Stream, tup: var tuple) +func slen*(tup: tuple): int -proc swrite*[U, V](stream: Stream, t: Table[U, V]) = - stream.swrite(t.len) - for k, v in t: - stream.swrite(k) - stream.swrite(v) +proc swrite*[T](stream: Stream, s: seq[T]) +proc sread*[T](stream: Stream, s: var seq[T]) +func slen*(s: seq): int -proc swrite*(stream: Stream, obj: object) = - for f in obj.fields: - stream.swrite(f) +proc swrite*[U, V](stream: Stream, t: Table[U, V]) +proc sread*[U, V](stream: Stream, t: var Table[U, V]) +func slen*[U, V](t: Table[U, V]): int -proc swrite*(stream: Stream, obj: ref object) = - stream.swrite(obj[]) +proc swrite*(stream: Stream, obj: object) +proc sread*(stream: Stream, obj: var object) +func slen*(obj: object): int -proc swrite*(stream: Stream, part: MimePart) = - stream.swrite(part.isFile) - stream.swrite(part.name) - stream.swrite(part.content) - if part.isFile: - stream.swrite(part.filename) - stream.swrite(part.contentType) - stream.swrite(part.fileSize) - stream.swrite(part.isStream) +proc swrite*(stream: Stream, obj: ref object) +proc sread*(stream: Stream, obj: var ref object) +func slen*(obj: ref object): int -proc swrite*[T](stream: Stream, o: Option[T]) = - stream.swrite(o.issome) - if o.issome: - stream.swrite(o.get) +proc swrite*(stream: Stream, part: MimePart) +proc sread*(stream: Stream, part: var MimePart) +func slen*(part: MimePart): int -proc swrite*(stream: Stream, request: Request) = - stream.swrite(request[]) +proc swrite*[T](stream: Stream, o: Option[T]) +proc sread*[T](stream: Stream, o: var Option[T]) +func slen*[T](o: Option[T]): int -proc swrite*(stream: Stream, color: CellColor) = - stream.swrite(color.rgb) - if color.rgb: - stream.swrite(color.rgbcolor) - else: - stream.swrite(color.color) +proc swrite*(stream: Stream, regex: Regex) +proc sread*(stream: Stream, regex: var Regex) +func slen*(regex: Regex): int -proc swrite*(stream: Stream, regex: Regex) = - stream.swrite(regex.plen) - stream.writeData(regex.bytecode, regex.plen) - stream.swrite(regex.buf) +proc swrite*(stream: Stream, source: BufferSource) +proc sread*(stream: Stream, source: var BufferSource) +func slen*(source: BufferSource): int -proc swrite*(stream: Stream, source: BufferSource) = - stream.swrite(source.t) - case source.t - of CLONE: stream.swrite(source.clonepid) - of LOAD_REQUEST: stream.swrite(source.request) - of LOAD_PIPE: stream.swrite(source.fd) - stream.swrite(source.location) - stream.swrite(source.contenttype) +proc swrite*(stream: Stream, n: SomeNumber) = + stream.write(n) + +proc sread*(stream: Stream, n: var SomeNumber) = + stream.read(n) -template sread*[T](stream: Stream, o: T) = - stream.read(o) +func slen*(n: SomeNumber): int = + return sizeof(n) + +proc swrite*[T: enum](stream: Stream, x: T) = + stream.swrite(cast[int](x)) + +proc sread*[T: enum](stream: Stream, x: var T) = + var i: int + stream.sread(i) + x = cast[T](i) + +func slen*[T: enum](x: T): int = + return sizeof(int) + +proc swrite*[T](stream: Stream, s: set[T]) = + stream.swrite(s.card) + for e in s: + stream.swrite(e) + +proc sread*[T](stream: Stream, s: var set[T]) = + var len: int + stream.sread(len) + for i in 0 ..< len: + var x: T + stream.sread(x) + s.incl(x) + +func slen*[T](s: set[T]): int = + result = slen(s.card) + for x in s: + result += slen(x) + +proc swrite*(stream: Stream, s: string) = + stream.swrite(s.len) + stream.write(s) proc sread*(stream: Stream, s: var string) = var len: int stream.sread(len) stream.readStr(len, s) +func slen*(s: string): int = + slen(s.len) + s.len + +proc swrite*(stream: Stream, b: bool) = + if b: + stream.swrite(1u8) + else: + stream.swrite(0u8) proc sread*(stream: Stream, b: var bool) = var n: uint8 @@ -164,6 +135,39 @@ proc sread*(stream: Stream, b: var bool) = assert n == 0u8 b = false +func slen*(b: bool): int = + return sizeof(uint8) + +proc swrite*(stream: Stream, url: Url) = + stream.swrite(url.serialize()) + +proc sread*(stream: Stream, url: var Url) = + var s: string + stream.sread(s) + url = newURL(s) + +func slen*(url: Url): int = + slen(url.serialize()) + +proc swrite*(stream: Stream, tup: tuple) = + for f in tup.fields: + stream.swrite(f) + +proc sread*(stream: Stream, tup: var tuple) = + for f in tup.fields: + stream.sread(f) + +func slen*(tup: tuple): int = + for f in tup.fields: + result += slen(f) + +proc swrite*[T](stream: Stream, s: seq[T]) = + stream.swrite(s.len) + var i = 0 + for m in s: + stream.swrite(m) + inc i + proc sread*[T](stream: Stream, s: var seq[T]) = var len: int stream.sread(len) @@ -171,15 +175,16 @@ proc sread*[T](stream: Stream, s: var seq[T]) = for i in 0..<len: stream.sread(s[i]) -proc sread*[T](stream: Stream, o: var Option[T]) = - var x: bool - stream.sread(x) - if x: - var m: T - stream.sread(m) - o = some(m) - else: - o = none(T) +func slen*(s: seq): int = + result = slen(s.len) + for x in s: + result += slen(x) + +proc swrite*[U, V](stream: Stream, t: Table[U, V]) = + stream.swrite(t.len) + for k, v in t: + stream.swrite(k) + stream.swrite(v) proc sread*[U, V](stream: Stream, t: var Table[U, V]) = var len: int @@ -191,22 +196,43 @@ proc sread*[U, V](stream: Stream, t: var Table[U, V]) = stream.sread(v) t[k] = v +func slen*[U, V](t: Table[U, V]): int = + result = slen(t.len) + for k, v in t: + result += slen(k) + result += slen(v) + +proc swrite*(stream: Stream, obj: object) = + for f in obj.fields: + stream.swrite(f) + proc sread*(stream: Stream, obj: var object) = for f in obj.fields: stream.sread(f) -proc sread*(stream: Stream, tup: var tuple) = - for f in tup.fields: - stream.sread(f) +func slen*(obj: object): int = + for f in obj.fields: + result += slen(f) + +proc swrite*(stream: Stream, obj: ref object) = + stream.swrite(obj[]) -proc read*(stream: Stream, obj: var ref object) = +proc sread*(stream: Stream, obj: var ref object) = new(obj) stream.sread(obj[]) -proc sread*(stream: Stream, url: var Url) = - var s: string - stream.sread(s) - url = newURL(s) +func slen*(obj: ref object): int = + slen(obj[]) + +proc swrite*(stream: Stream, part: MimePart) = + stream.swrite(part.isFile) + stream.swrite(part.name) + stream.swrite(part.content) + if part.isFile: + stream.swrite(part.filename) + stream.swrite(part.contentType) + stream.swrite(part.fileSize) + stream.swrite(part.isStream) proc sread*(stream: Stream, part: var MimePart) = var isFile: bool @@ -223,15 +249,40 @@ proc sread*(stream: Stream, part: var MimePart) = stream.sread(part.fileSize) stream.sread(part.isStream) -proc sread*(stream: Stream, color: var CellColor) = - var rgb: bool - stream.sread(rgb) - if rgb: - color = CellColor(rgb: true) - stream.sread(color.rgbcolor) +func slen*(part: MimePart): int = + result += slen(part.isFile) + result += slen(part.name) + result += slen(part.content) + if part.isFile: + result += slen(part.filename) + result += slen(part.contentType) + result += slen(part.fileSize) + result += slen(part.isStream) + +proc swrite*[T](stream: Stream, o: Option[T]) = + stream.swrite(o.issome) + if o.isSome: + stream.swrite(o.get) + +proc sread*[T](stream: Stream, o: var Option[T]) = + var x: bool + stream.sread(x) + if x: + var m: T + stream.sread(m) + o = some(m) else: - color = CellColor(rgb: false) - stream.sread(color.color) + o = none(T) + +func slen*[T](o: Option[T]): int = + result = slen(o.isSome) + if o.isSome: + result += slen(o.get) + +proc swrite*(stream: Stream, regex: Regex) = + stream.swrite(regex.plen) + stream.writeData(regex.bytecode, regex.plen) + stream.swrite(regex.buf) proc sread*(stream: Stream, regex: var Regex) = assert regex.bytecode == nil @@ -243,6 +294,20 @@ proc sread*(stream: Stream, regex: var Regex) = if l != regex.plen: `=destroy`(regex) +func slen*(regex: Regex): int = + result += slen(regex.plen) + result += regex.plen + result += slen(regex.buf) + +proc swrite*(stream: Stream, source: BufferSource) = + stream.swrite(source.t) + case source.t + of CLONE: stream.swrite(source.clonepid) + of LOAD_REQUEST: stream.swrite(source.request) + of LOAD_PIPE: stream.swrite(source.fd) + stream.swrite(source.location) + stream.swrite(source.contenttype) + proc sread*(stream: Stream, source: var BufferSource) = var t: BufferSourceType stream.sread(t) @@ -258,3 +323,12 @@ proc sread*(stream: Stream, source: var BufferSource) = stream.sread(source.fd) stream.sread(source.location) stream.sread(source.contenttype) + +func slen*(source: BufferSource): int = + result += slen(source.t) + case source.t + of CLONE: result += slen(source.clonepid) + of LOAD_REQUEST: result += slen(source.request) + of LOAD_PIPE: result += slen(source.fd) + result += slen(source.location) + result += slen(source.contenttype) diff --git a/src/ips/socketstream.nim b/src/ips/socketstream.nim index c0abf07f..5d0485fa 100644 --- a/src/ips/socketstream.nim +++ b/src/ips/socketstream.nim @@ -11,12 +11,16 @@ import ips/serversocket type SocketStream* = ref object of Stream source*: Socket - recvw*: bool + blk*: bool isend: bool proc sockReadData(s: Stream, buffer: pointer, len: int): int = let s = SocketStream(s) - result = s.source.recv(buffer, len) + if s.blk: + while result < len: + result += s.source.recv(cast[pointer](cast[int](buffer) + result), len - result) + else: + result = s.source.recv(buffer, len) if result < 0: if errno == EAGAIN: raise newException(ErrorAgain, "") @@ -30,7 +34,10 @@ proc sockReadData(s: Stream, buffer: pointer, len: int): int = s.isend = true proc sockWriteData(s: Stream, buffer: pointer, len: int) = - discard SocketStream(s).source.send(buffer, len) + #TODO maybe don't block if blk is false? + var i = 0 + while i < len: + i += SocketStream(s).source.send(cast[pointer](cast[int](buffer) + i), len - i) proc sockAtEnd(s: Stream): bool = SocketStream(s).isend @@ -94,6 +101,7 @@ func newSocketStream*(): SocketStream = proc connectSocketStream*(path: string, buffered = true, blocking = true): SocketStream = result = newSocketStream() + result.blk = blocking let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP, buffered) #if not blocking: # sock.getFd().setBlocking(false) @@ -106,8 +114,9 @@ proc connectSocketStream*(pid: Pid, buffered = true, blocking = true): SocketStr except OSError: return nil -proc acceptSocketStream*(ssock: ServerSocket): SocketStream = +proc acceptSocketStream*(ssock: ServerSocket, blocking = true): SocketStream = result = newSocketStream() + result.blk = blocking var sock: Socket ssock.sock.accept(sock, inheritable = true) result.source = sock |