# Write data to streams. import options import sets import streams import tables import loader/request import types/blob import types/buffersource import types/formdata import types/url import types/opt proc swrite*(stream: Stream, n: SomeNumber) proc sread*(stream: Stream, n: var SomeNumber) func slen*(n: SomeNumber): int 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*[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, s: string) proc sread*(stream: Stream, s: var string) func slen*(s: string): int proc swrite*(stream: Stream, b: bool) proc sread*(stream: Stream, b: var bool) func slen*(b: bool): int proc swrite*(stream: Stream, url: Url) proc sread*(stream: Stream, url: var Url) func slen*(url: Url): int proc swrite*(stream: Stream, tup: tuple) proc sread*(stream: Stream, tup: var tuple) func slen*(tup: tuple): int proc swrite*[T](stream: Stream, s: seq[T]) proc sread*[T](stream: Stream, s: var seq[T]) func slen*(s: seq): int 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: object) proc sread*(stream: Stream, obj: var object) func slen*(obj: object): int proc swrite*(stream: Stream, obj: ref object) proc sread*(stream: Stream, obj: var ref object) func slen*(obj: ref object): int proc swrite*(stream: Stream, part: FormDataEntry) proc sread*(stream: Stream, part: var FormDataEntry) func slen*(part: FormDataEntry): int proc swrite*(stream: Stream, blob: Blob) proc sread*(stream: Stream, blob: var Blob) func slen*(blob: Blob): int 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*[T, E](stream: Stream, o: Result[T, E]) proc sread*[T, E](stream: Stream, o: var Result[T, E]) func slen*[T, E](o: Result[T, E]): int proc swrite*(stream: Stream, source: BufferSource) proc sread*(stream: Stream, source: var BufferSource) func slen*(source: BufferSource): int proc swrite*(stream: Stream, n: SomeNumber) = stream.write(n) proc sread*(stream: Stream, n: var SomeNumber) = if stream.readData(addr n, sizeof(n)) < sizeof(n): raise newException(EOFError, "eof") func slen*(n: SomeNumber): int = return sizeof(n) proc swrite*[T: enum](stream: Stream, x: T) = static: doAssert sizeof(int) >= sizeof(T) stream.swrite(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) if len > 0: s = newString(len) prepareMutation(s) if stream.readData(addr s[0], len) < len: raise newException(EOFError, "eof") else: 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 stream.sread(n) if n == 1u8: b = true else: assert n == 0u8 b = false func slen*(b: bool): int = return sizeof(uint8) proc swrite*(stream: Stream, url: URL) = if url != nil: stream.swrite(url.serialize()) else: stream.swrite("") proc sread*(stream: Stream, url: var URL) = var s: string stream.sread(s) if s == "": url = nil else: let x = newURL(s) if x.isSome: url = x.get else: url = nil func slen*(url: URL): int = if url == nil: return slen("") return 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) s.setLen(len) for i in 0.. 0: let n = stream.readData(blob.buffer, int(blob.size)) assert n == int(blob.size) func slen*(blob: Blob): int = result += slen(blob.isfile) if blob.isfile: result = slen(WebFile(blob).path) else: result += slen(blob.ctype) result += slen(blob.size) result += int(blob.size) #TODO ?? 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: o = none(T) func slen*[T](o: Option[T]): int = result = slen(o.isSome) if o.isSome: result += slen(o.get) proc swrite*[T, E](stream: Stream, o: Result[T, E]) = stream.swrite(o.isOk) if o.isOk: when not (T is void): stream.swrite(o.get) else: when not (E is void): stream.swrite(o.error) proc sread*[T, E](stream: Stream, o: var Result[T, E]) = var x: bool stream.sread(x) if x: when not (T is void): var m: T stream.sread(m) o.ok(m) else: o.ok() else: when not (E is void): var e: E stream.sread(e) o.err(e) else: o.err() func slen*[T, E](o: Result[T, E]): int = result = slen(o.isSome) if o.isSome: when not (T is void): result += slen(o.get) else: when not (E is void): result += slen(o.error) 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) stream.swrite(source.charset) proc sread*(stream: Stream, source: var BufferSource) = var t: BufferSourceType stream.sread(t) case t of CLONE: source = BufferSource(t: CLONE) stream.sread(source.clonepid) of LOAD_REQUEST: source = BufferSource(t: LOAD_REQUEST) stream.sread(source.request) of LOAD_PIPE: source = BufferSource(t: LOAD_PIPE) stream.sread(source.fd) stream.sread(source.location) stream.sread(source.contentType) stream.sread(source.charset) 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)