diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/web/08_text_encoding.js | 9 | ||||
-rw-r--r-- | ext/web/lib.rs | 59 |
2 files changed, 28 insertions, 40 deletions
diff --git a/ext/web/08_text_encoding.js b/ext/web/08_text_encoding.js index 9e0c1f311..db724033f 100644 --- a/ext/web/08_text_encoding.js +++ b/ext/web/08_text_encoding.js @@ -25,6 +25,7 @@ TypedArrayPrototypeSubarray, TypedArrayPrototypeSlice, Uint8Array, + Uint32Array, } = window.__bootstrap.primordials; class TextDecoder { @@ -199,10 +200,16 @@ context: "Argument 2", allowShared: true, }); - return ops.op_encoding_encode_into(source, destination); + ops.op_encoding_encode_into(source, destination, encodeIntoBuf); + return { + read: encodeIntoBuf[0], + written: encodeIntoBuf[1], + }; } } + const encodeIntoBuf = new Uint32Array(2); + webidl.configurePrototype(TextEncoder); const TextEncoderPrototype = TextEncoder.prototype; diff --git a/ext/web/lib.rs b/ext/web/lib.rs index 9c1e85952..0eec63ab9 100644 --- a/ext/web/lib.rs +++ b/ext/web/lib.rs @@ -10,7 +10,9 @@ use deno_core::error::type_error; use deno_core::error::AnyError; use deno_core::include_js_files; use deno_core::op; +use deno_core::serde_v8; use deno_core::url::Url; +use deno_core::v8; use deno_core::ByteString; use deno_core::CancelHandle; use deno_core::Extension; @@ -19,11 +21,11 @@ use deno_core::Resource; use deno_core::ResourceId; use deno_core::U16String; use deno_core::ZeroCopyBuf; + use encoding_rs::CoderResult; use encoding_rs::Decoder; use encoding_rs::DecoderResult; use encoding_rs::Encoding; -use serde::Serialize; use std::borrow::Cow; use std::cell::RefCell; use std::fmt; @@ -314,46 +316,25 @@ impl Resource for TextDecoderResource { } } -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct EncodeIntoResult { - read: usize, - written: usize, -} - -#[op] +#[op(v8)] fn op_encoding_encode_into( - input: String, + scope: &mut v8::HandleScope, + input: serde_v8::Value, buffer: &mut [u8], -) -> EncodeIntoResult { - // Since `input` is already UTF-8, we can simply find the last UTF-8 code - // point boundary from input that fits in `buffer`, and copy the bytes up to - // that point. - let boundary = if buffer.len() >= input.len() { - input.len() - } else { - let mut boundary = buffer.len(); - - // The maximum length of a UTF-8 code point is 4 bytes. - for _ in 0..4 { - if input.is_char_boundary(boundary) { - break; - } - debug_assert!(boundary > 0); - boundary -= 1; - } - - debug_assert!(input.is_char_boundary(boundary)); - boundary - }; - - buffer[..boundary].copy_from_slice(input[..boundary].as_bytes()); - - EncodeIntoResult { - // The `read` output parameter is measured in UTF-16 code units. - read: input[..boundary].encode_utf16().count(), - written: boundary, - } + out_buf: &mut [u32], +) -> Result<(), AnyError> { + let s = v8::Local::<v8::String>::try_from(input.v8_value)?; + + let mut nchars = 0; + out_buf[1] = s.write_utf8( + scope, + buffer, + Some(&mut nchars), + v8::WriteOptions::NO_NULL_TERMINATION + | v8::WriteOptions::REPLACE_INVALID_UTF8, + ) as u32; + out_buf[0] = nchars as u32; + Ok(()) } /// Creates a [`CancelHandle`] resource that can be used to cancel invocations of certain ops. |