about summary refs log tree commit diff stats
path: root/src/io
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-12-10 19:05:38 +0100
committerbptato <nincsnevem662@gmail.com>2022-12-10 19:05:38 +0100
commit1e858c874804444bc4b95b6e89eb96a0deb8473c (patch)
tree3151b498e19c6d6eed3d90827483eb270314f3da /src/io
parentd963385cd9fd77f0a950c5b92be7774bbf76d661 (diff)
downloadchawan-1e858c874804444bc4b95b6e89eb96a0deb8473c.tar.gz
Add support for the encoding standard, fix parseLegacyColor
Also, fix a bug in the
Diffstat (limited to 'src/io')
-rw-r--r--src/io/posixstream.nim40
-rw-r--r--src/io/teestream.nim44
2 files changed, 84 insertions, 0 deletions
diff --git a/src/io/posixstream.nim b/src/io/posixstream.nim
new file mode 100644
index 00000000..9a40ce9b
--- /dev/null
+++ b/src/io/posixstream.nim
@@ -0,0 +1,40 @@
+# stdlib file handling is broken, so we use this instead of FileStream.
+import posix
+import streams
+
+type
+  PosixStream* = ref object of Stream
+    fd*: FileHandle
+
+  ErrorAgain* = object of IOError
+  ErrorWouldBlock* = object of IOError
+  ErrorBadFD* = object of IOError
+  ErrorFault* = object of IOError
+  ErrorInterrupted* = object of IOError
+  ErrorInvalid* = object of IOError
+
+proc psReadData(s: Stream, buffer: pointer, len: int): int =
+  let s = cast[PosixStream](s)
+  result = read(s.fd, buffer, len)
+  if result == -1:
+    if errno == EAGAIN:
+      raise newException(ErrorAgain, "")
+    case errno
+    of EWOULDBLOCK: raise newException(ErrorWouldBlock, "")
+    of EBADF: raise newException(ErrorBadFD, "")
+    of EFAULT: raise newException(ErrorFault, "")
+    of EINVAL: raise newException(ErrorInvalid, "")
+    else: raise newException(IOError, $strerror(errno))
+
+proc psWriteData(s: Stream, buffer: pointer, len: int) =
+  let s = cast[PosixStream](s)
+  let res = write(s.fd, buffer, len)
+  if res == -1:
+    raise newException(IOError, $strerror(errno))
+
+proc newPosixStream*(fd: FileHandle): PosixStream =
+  return PosixStream(
+    fd: fd,
+    readDataImpl: psReadData,
+    writeDataImpl: psWriteData
+  )
diff --git a/src/io/teestream.nim b/src/io/teestream.nim
new file mode 100644
index 00000000..81c9e2f0
--- /dev/null
+++ b/src/io/teestream.nim
@@ -0,0 +1,44 @@
+import streams
+
+type TeeStream = ref object of Stream
+  source: Stream
+  dest: Stream
+  closedest: bool
+
+proc tsClose(s: Stream) =
+  let s = cast[TeeStream](s)
+  s.source.close()
+  if s.closedest:
+    s.dest.close()
+
+proc tsReadData(s: Stream, buffer: pointer, bufLen: int): int =
+  let s = cast[TeeStream](s)
+  result = s.source.readData(buffer, bufLen)
+  s.dest.writeData(buffer, result)
+
+proc tsReadDataStr(s: Stream, buffer: var string, slice: Slice[int]): int =
+  let s = cast[TeeStream](s)
+  result = s.source.readDataStr(buffer, slice)
+  if result <= 0: return
+  s.dest.writeData(addr buffer[0], result)
+
+proc tsAtEnd(s: Stream): bool =
+  let s = cast[TeeStream](s)
+  return s.source.atEnd
+
+proc newTeeStream*(source, dest: Stream, closedest = true): TeeStream =
+  return TeeStream(
+    source: source,
+    dest: dest,
+    closedest: closedest,
+    closeImpl: tsClose,
+    readDataImpl:
+      cast[proc(s: Stream, buffer: pointer, len: int): int
+      {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
+      ](tsReadData),
+    readDataStrImpl:
+      cast[proc(s: Stream, buffer: var string, slice: Slice[int]): int
+      {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.}
+      ](tsReadDataStr),
+    atEndImpl: tsAtEnd
+  )