about summary refs log tree commit diff stats
path: root/src/render
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-05-16 13:17:41 +0200
committerbptato <nincsnevem662@gmail.com>2023-05-16 13:18:47 +0200
commit4e0fd8c7ef2ad2f61c1ac0572e02b92b1c42b688 (patch)
tree83adafc3a2046bb8af09d7c57340dc9374eebbd6 /src/render
parent951d587f7edf3544d30ba039530a1d19b7e9db78 (diff)
downloadchawan-4e0fd8c7ef2ad2f61c1ac0572e02b92b1c42b688.tar.gz
Refactor config, add charset opts
Only document-charset supported for now.
Diffstat (limited to 'src/render')
-rw-r--r--src/render/rendertext.nim33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/render/rendertext.nim b/src/render/rendertext.nim
index e91c1e10..d0576c75 100644
--- a/src/render/rendertext.nim
+++ b/src/render/rendertext.nim
@@ -10,14 +10,35 @@ type StreamRenderer* = object
   ansiparser: AnsiCodeParser
   format: Format
   af: bool
+  stream: Stream
   decoder: DecoderStream
+  charsets: seq[Charset]
   newline: bool
   w: int
 
-proc newStreamRenderer*(stream: Stream): StreamRenderer =
+proc newStreamRenderer*(stream: Stream, charsets: seq[Charset]): StreamRenderer =
   result.format = newFormat()
   result.ansiparser.state = PARSE_DONE
-  result.decoder = newDecoderStream(stream, CHARSET_UTF_8)
+  for i in countdown(charsets.high, 0):
+    result.charsets.add(charsets[i])
+  let cs = result.charsets.pop()
+  let em = if charsets.len > 0:
+    DECODER_ERROR_MODE_FATAL
+  else:
+    DECODER_ERROR_MODE_REPLACEMENT
+  result.stream = stream
+  result.decoder = newDecoderStream(stream, cs, errormode = em)
+
+proc rewind(renderer: var StreamRenderer) =
+  renderer.stream.setPosition(0)
+  let cs = renderer.charsets.pop()
+  let em = if renderer.charsets.len > 0:
+    DECODER_ERROR_MODE_FATAL
+  else:
+    DECODER_ERROR_MODE_REPLACEMENT
+  renderer.decoder = newDecoderStream(renderer.stream, cs, errormode = em)
+  renderer.format = newFormat()
+  renderer.ansiparser.state = PARSE_DONE
 
 proc renderStream*(grid: var FlexibleGrid, renderer: var StreamRenderer, len: int) =
   if len == 0: return
@@ -28,7 +49,13 @@ proc renderStream*(grid: var FlexibleGrid, renderer: var StreamRenderer, len: in
 
   if grid.len == 0: grid.addLine()
   var buf = newSeq[Rune](len * 4)
-  let n = renderer.decoder.readData(addr buf[0], buf.len * sizeof(buf[0]))
+  var n: int
+  while true:
+    n = renderer.decoder.readData(addr buf[0], buf.len * sizeof(buf[0]))
+    if renderer.decoder.failed:
+      renderer.rewind()
+      continue
+    break
   for i in 0 ..< n div sizeof(buf[0]):
     if renderer.newline:
       # avoid newline at end of stream