about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/pdf/v2ch08.pdf
Commit message (Expand)AuthorAgeFilesLines
* *elioat2023-08-231-0/+0
bptato <nincsnevem662@gmail.com> 2023-10-21 20:22:21 +0200 javascript: add TextEncoder, TextDecoder' href='/ahoang/chawan/commit/src/js/encoding.nim?id=69870f3b974e65d61b564b396e01d21cc023e6e9'>69870f3b ^
78ffc938 ^
69870f3b ^
78ffc938 ^
69870f3b ^
69870f3b ^
78ffc938 ^
69870f3b ^

78ffc938 ^
69870f3b ^
78ffc938 ^

69870f3b ^




78ffc938 ^

69870f3b ^

ddffd450 ^
78ffc938 ^
69870f3b ^
78ffc938 ^
d90e456b ^
69870f3b ^


78ffc938 ^


















66b9574b ^
78ffc938 ^





66b9574b ^
78ffc938 ^





66b9574b ^
78ffc938 ^





d90e456b ^
78ffc938 ^





d90e456b ^
78ffc938 ^
d90e456b ^
78ffc938 ^


d90e456b ^
78ffc938 ^


d90e456b ^

78ffc938 ^





69870f3b ^



cc7eacf7 ^


69870f3b ^
d90e456b ^
69870f3b ^


69870f3b ^
d90e456b ^
78ffc938 ^


69870f3b ^

78ffc938 ^

69870f3b ^
78ffc938 ^
69870f3b ^

cc7eacf7 ^
69870f3b ^

cc7eacf7 ^
78ffc938 ^


69870f3b ^
78ffc938 ^
69870f3b ^













78ffc938 ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154


                           




                          

    
                            
 
                            
                     
                             
                         

                    
                   
 

                           




                                          

                                                                       

                                                        
                                                  
                          
                                 
                         
                                 


                      


















                                                                 
                                                   





                                                        
                                         





                                                        
                                                                           





                                                          
                  





                                                    
            
             
                                                  


                                              
                        


                                  

                                                              





                                                                       



                                         


                                                                    
                         
                                           


                                       
                  
                                                       


                                                                    

                       

                                                 
 
                                                                    

                
                                                                

            
                                                                       


                                                
                                                             
                                        













                                         

                                                       
import chagashi/charset
import chagashi/decoder
import chagashi/decodercore
import monoucha/javascript
import monoucha/jserror
import monoucha/jstypes
import monoucha/quickjs
import types/opt

type
  JSTextEncoder = ref object

  JSTextDecoder = ref object
    encoding: Charset
    ignoreBOM {.jsget.}: bool
    fatal {.jsget.}: bool
    doNotFlush: bool
    bomSeen: bool
    td: TextDecoder

jsDestructor(JSTextDecoder)
jsDestructor(JSTextEncoder)

type TextDecoderOptions = object of JSDict
  fatal: bool
  ignoreBOM: bool

func newJSTextDecoder(label = "utf-8", options = TextDecoderOptions()):
    JSResult[JSTextDecoder] {.jsctor.} =
  let encoding = getCharset(label)
  if encoding in {CHARSET_UNKNOWN, CHARSET_REPLACEMENT}:
    return errRangeError("Invalid encoding label")
  return ok(JSTextDecoder(
    ignoreBOM: options.ignoreBOM,
    fatal: options.fatal,
    td: newTextDecoder(encoding),
    encoding: encoding
  ))

type Growbuf = object
  p: ptr UncheckedArray[uint8]
  cap: int
  len: int

{.warning[Deprecated]: off.}:
  proc `=destroy`(growbuf: var Growbuf) =
    if growbuf.p != nil:
      dealloc(growbuf.p)
      growbuf.p = nil

const BufferSize = 128
proc grow(buf: var Growbuf) =
  if buf.cap == 0:
    buf.cap = BufferSize
  else:
    buf.cap *= 2
  buf.p = cast[ptr UncheckedArray[uint8]](buf.p.realloc(buf.cap))

proc write(buf: var Growbuf; s: openArray[uint8]) =
  if buf.len + s.len > buf.cap:
    buf.grow()
  if s.len > 0:
    copyMem(addr buf.p[buf.len], unsafeAddr s[0], s.len)
  buf.len += s.len

proc write(buf: var Growbuf; s: string) =
  if buf.len + s.len > buf.cap:
    buf.grow()
  if s.len > 0:
    copyMem(addr buf.p[buf.len], unsafeAddr s[0], s.len)
  buf.len += s.len

proc decode0(this: JSTextDecoder; ctx: JSContext; input: JSArrayBufferView;
    stream: bool): JSResult[JSValue] =
  var oq = Growbuf(
    p: cast[ptr UncheckedArray[uint8]](alloc(BufferSize)),
    len: 0,
    cap: BufferSize
  )
  let td = this.td
  var i = 0
  let H = int(input.abuf.len) - 1
  template handle_error =
    if this.fatal:
      return errTypeError("Failed to decode string")
    oq.write("\uFFFD")
    i = td.i
  while true:
    case td.decode(input.abuf.p.toOpenArray(i, H),
      oq.p.toOpenArray(0, oq.cap - 1), oq.len)
    of tdrDone:
      if not stream:
        case td.finish()
        of tdfrDone: discard
        of tdfrError: handle_error
      break
    of tdrReadInput:
      oq.write(input.abuf.p.toOpenArray(i + td.pi, i + td.ri))
    of tdrError:
      handle_error
    of tdrReqOutput:
      oq.grow()
  return ok(JS_NewStringLen(ctx, cast[cstring](oq.p), csize_t(oq.len)))

type TextDecodeOptions = object of JSDict
  stream: bool

#TODO AllowSharedBufferSource
proc decode(ctx: JSContext; this: JSTextDecoder;
    input = none(JSArrayBufferView); options = TextDecodeOptions()):
    JSResult[JSValue] {.jsfunc.} =
  if not this.doNotFlush:
    this.td = newTextDecoder(this.encoding)
    this.bomSeen = false
  if this.doNotFlush != options.stream:
    this.doNotFlush = options.stream
  if input.isSome:
    return this.decode0(ctx, input.get, options.stream)
  return ok(JS_NewString(ctx, ""))

func jencoding(this: JSTextDecoder): string {.jsfget: "encoding".} =
  return $this.encoding

func newTextEncoder(): JSTextEncoder {.jsctor.} =
  return JSTextEncoder()

func jencoding(this: JSTextEncoder): string {.jsfget: "encoding".} =
  return "utf-8"

proc dealloc_wrap(rt: JSRuntime; opaque, p: pointer) {.cdecl.} =
  dealloc(p)

proc encode(this: JSTextEncoder; input = ""): JSUint8Array {.jsfunc.} =
  # we have to validate input first :/
  #TODO it is possible to do less copies here...
  var input = input.toValidUTF8()
  let buf = cast[ptr UncheckedArray[uint8]](alloc(input.len))
  copyMem(buf, addr input[0], input.len)
  let abuf = JSArrayBuffer(
    p: buf,
    len: csize_t(input.len),
    dealloc: dealloc_wrap
  )
  return JSUint8Array(
    abuf: abuf,
    offset: 0,
    nmemb: csize_t(input.len)
  )

#TODO encodeInto

proc addEncodingModule*(ctx: JSContext) =
  ctx.registerType(JSTextDecoder, name = "TextDecoder")
  ctx.registerType(JSTextEncoder, name = "TextEncoder")