diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/html/env.nim | 31 | ||||
-rw-r--r-- | src/html/formdata.nim | 1 | ||||
-rw-r--r-- | src/js/base64.nim | 75 | ||||
-rw-r--r-- | src/local/term.nim | 1 | ||||
-rw-r--r-- | src/utils/twtstr.nim | 41 |
5 files changed, 67 insertions, 82 deletions
diff --git a/src/html/env.nim b/src/html/env.nim index 4d5c3941..d550430d 100644 --- a/src/html/env.nim +++ b/src/html/env.nim @@ -9,7 +9,6 @@ import html/script import html/xmlhttprequest import io/dynstream import io/promise -import js/base64 import js/console import js/domexception import js/encoding @@ -29,6 +28,7 @@ import types/blob import types/opt import types/url import types/winattrs +import utils/twtstr # NavigatorID proc appCodeName(navigator: var Navigator): string {.jsfget.} = "Mozilla" @@ -227,12 +227,33 @@ func getTop(window: Window): Window {.jsuffget: "top".} = func getParent(window: Window): Window {.jsfget: "parent".} = return window #TODO frames? -proc atob(window: Window; data: string): DOMResult[NarrowString] {.jsfunc.} = - return atob(data) +# See twtstr for the actual implementations. +proc atob(ctx: JSContext; window: Window; data: string): JSValue {.jsfunc.} = + let r = atob0(data) + if r.isNone: + let ex = newDOMException($r.error, "InvalidCharacterError") + return JS_Throw(ctx, ctx.toJS(ex)) + return ctx.toJS(NarrowString(r.get)) -proc btoa(ctx: JSContext; window: Window; data: JSValue): DOMResult[string] +proc btoa(ctx: JSContext; window: Window; data: JSValue): JSValue {.jsfunc.} = - return btoa(ctx, data) + let data = JS_ToString(ctx, data) + if JS_IsException(data): + return JS_EXCEPTION + doAssert JS_IsString(data) + if JS_IsStringWideChar(data): + JS_FreeValue(ctx, data) + let ex = newDOMException("Invalid character in string", + "InvalidCharacterError") + return JS_Throw(ctx, ctx.toJS(ex)) + let len = int(JS_GetStringLength(data)) + if len == 0: + JS_FreeValue(ctx, data) + return ctx.toJS("") + let buf = JS_GetNarrowStringBuffer(data) + let res = btoa(buf.toOpenArray(0, len - 1)) + JS_FreeValue(ctx, data) + return ctx.toJS(res) proc alert(window: Window; s: string) {.jsfunc.} = window.console.error(s) diff --git a/src/html/formdata.nim b/src/html/formdata.nim index b5a21b1e..56d49df2 100644 --- a/src/html/formdata.nim +++ b/src/html/formdata.nim @@ -3,7 +3,6 @@ import html/catom import html/dom import html/enums import io/dynstream -import js/base64 import js/domexception import monoucha/fromjs import monoucha/javascript diff --git a/src/js/base64.nim b/src/js/base64.nim deleted file mode 100644 index f9137fb3..00000000 --- a/src/js/base64.nim +++ /dev/null @@ -1,75 +0,0 @@ -import js/domexception -import monoucha/javascript -import monoucha/jstypes -import monoucha/quickjs -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] = - # Note: the actual atob implementation (atob0) is in twtstr. - let r = atob0(data) - if r.isNone: - return errDOMException($r.error, "InvalidCharacterError") - return ok(NarrowString(r.get)) - -const AMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - -func btoa*(s: var string; data: openArray[uint8]) = - 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 &= '=' - -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) - s.btoa(data) - 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) diff --git a/src/local/term.nim b/src/local/term.nim index 0d760fbe..903b145b 100644 --- a/src/local/term.nim +++ b/src/local/term.nim @@ -11,7 +11,6 @@ import chagashi/decoder import chagashi/encoder import config/config import io/dynstream -import js/base64 import types/blob import types/cell import types/color diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim index e5dab87a..342ecede 100644 --- a/src/utils/twtstr.nim +++ b/src/utils/twtstr.nim @@ -673,3 +673,44 @@ func atob0*(data: string): Result[string, cstring] = elif j != 0: return err("Incorrect number of characters in encoded string") return ok(outs) + +const AMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + +func btoa*(s: var string; data: openArray[uint8]) = + 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 &= '=' + +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) + s.btoa(data) + return s + +func btoa*(data: openArray[char]): string = + return btoa(data.toOpenArrayByte(0, data.len - 1)) |