diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-03-15 15:31:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-15 15:31:55 +0100 |
commit | dc6e0c3591709d6f8887bb672af1de54dfc8a974 (patch) | |
tree | 0239d62e419b840f1c4e5cd631a7b87689ed2a3b /core/bindings.rs | |
parent | ec3f44581bf4312cbbe36b71daca7f0474177cf3 (diff) |
feat: Deno.core.{encode,decode}; standalone UTF-8 encoding/decoding (#4349)
This commits add two new methods to "Deno.core" namespace: "encode" and "decode".
Those methods are bound in Rust to provide a) fast b) generally available of encoding and decoding UTF-8 strings.
Both methods are now used in "cli/js/dispatch_json.ts".
Diffstat (limited to 'core/bindings.rs')
-rw-r--r-- | core/bindings.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/core/bindings.rs b/core/bindings.rs index cb9c15ee1..9df9a78a0 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -35,6 +35,12 @@ lazy_static! { v8::ExternalReference { function: queue_microtask.map_fn_to() }, + v8::ExternalReference { + function: encode.map_fn_to() + }, + v8::ExternalReference { + function: decode.map_fn_to() + }, ]); } @@ -156,6 +162,22 @@ pub fn initialize_context<'s>( format_error_val.into(), ); + let mut encode_tmpl = v8::FunctionTemplate::new(scope, encode); + let encode_val = encode_tmpl.get_function(scope, context).unwrap(); + core_val.set( + context, + v8::String::new(scope, "encode").unwrap().into(), + encode_val.into(), + ); + + let mut decode_tmpl = v8::FunctionTemplate::new(scope, decode); + let decode_val = decode_tmpl.get_function(scope, context).unwrap(); + core_val.set( + context, + v8::String::new(scope, "decode").unwrap().into(), + decode_val.into(), + ); + core_val.set_accessor( context, v8::String::new(scope, "shared").unwrap().into(), @@ -551,6 +573,52 @@ fn format_error( rv.set(e.into()) } +fn encode( + scope: v8::FunctionCallbackScope, + args: v8::FunctionCallbackArguments, + mut rv: v8::ReturnValue, +) { + let text = match v8::Local::<v8::String>::try_from(args.get(0)) { + Ok(s) => s, + Err(_) => { + let msg = v8::String::new(scope, "Invalid argument").unwrap(); + let exception = v8::Exception::type_error(scope, msg); + scope.isolate().throw_exception(exception); + return; + } + }; + let text_str = text.to_rust_string_lossy(scope); + let text_bytes = text_str.as_bytes().to_vec().into_boxed_slice(); + let buf = boxed_slice_to_uint8array(scope, text_bytes); + rv.set(buf.into()) +} + +fn decode( + scope: v8::FunctionCallbackScope, + args: v8::FunctionCallbackArguments, + mut rv: v8::ReturnValue, +) { + let buf = match v8::Local::<v8::ArrayBufferView>::try_from(args.get(0)) { + Ok(view) => { + let byte_offset = view.byte_offset(); + let byte_length = view.byte_length(); + let backing_store = view.buffer().unwrap().get_backing_store(); + let buf = unsafe { &**backing_store.get() }; + &buf[byte_offset..byte_offset + byte_length] + } + Err(..) => { + let msg = v8::String::new(scope, "Invalid argument").unwrap(); + let exception = v8::Exception::type_error(scope, msg); + scope.isolate().throw_exception(exception); + return; + } + }; + + let text_str = + v8::String::new_from_utf8(scope, &buf, v8::NewStringType::Normal).unwrap(); + rv.set(text_str.into()) +} + fn queue_microtask( scope: v8::FunctionCallbackScope, args: v8::FunctionCallbackArguments, |