blob: a1693aa3ac292c4287d590cdd4ab359bca4a8b44 (
plain) (
blame)
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
|
import bindings/quickjs
import js/domexception
import js/javascript
import js/jstypes
import types/opt
import utils/twtstr
# atob and btoa convert Latin-1 to base64 and vice versa. (And throw on
# anything above latin-1.)
proc atob*(data: string): DOMResult[NarrowString] =
let r = atob0(data)
if r.isNone:
return err(newDOMException(r.error, "InvalidCharacterError"))
return ok(NarrowString(r.get))
const AMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
func btoa*(data: openArray[uint8]): string =
if data.len == 0:
return ""
var L = data.len div 3 * 4
if (let rem = data.len mod 3; rem) > 0:
L += 3 - rem
var s = newStringOfCap(L)
var i = 0
let endw = data.len - 2
while i < endw:
let n = uint32(data[i]) shl 16 or
uint32(data[i + 1]) shl 8 or
uint32(data[i + 2])
i += 3
s &= AMap[n shr 18 and 0x3F]
s &= AMap[n shr 12 and 0x3F]
s &= AMap[n shr 6 and 0x3F]
s &= AMap[n and 0x3F]
if i < data.len:
let b1 = uint32(data[i])
inc i
if i < data.len:
let b2 = uint32(data[i])
s &= AMap[b1 shr 2] # 6 bits of b1
s &= AMap[b1 shl 4 and 0x3F or b2 shr 4] # 2 bits of b1 | 4 bits of b2
s &= AMap[b2 shl 2 and 0x3F] # 4 bits of b2
else:
s &= AMap[b1 shr 2] # 6 bits of b1
s &= AMap[b1 shl 4 and 0x3F] # 2 bits of b1
s &= '='
s &= '='
return s
func btoa*(data: string): string =
return btoa(data.toOpenArrayByte(0, data.len - 1))
proc btoa*(ctx: JSContext; data: JSValue): DOMResult[string] =
let data = JS_ToString(ctx, data)
if JS_IsException(data):
return err()
assert JS_IsString(data)
if JS_IsStringWideChar(data):
JS_FreeValue(ctx, data)
return errDOMException("Invalid character in string",
"InvalidCharacterError")
let len = int(JS_GetStringLength(data))
if len == 0:
JS_FreeValue(ctx, data)
return ok("")
let buf = JS_GetNarrowStringBuffer(data)
let res = btoa(buf.toOpenArray(0, len - 1))
JS_FreeValue(ctx, data)
return ok(res)
|