diff options
Diffstat (limited to 'ext/web/lib.rs')
-rw-r--r-- | ext/web/lib.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/ext/web/lib.rs b/ext/web/lib.rs index 0d57bf10e..ae5cf2d80 100644 --- a/ext/web/lib.rs +++ b/ext/web/lib.rs @@ -90,6 +90,7 @@ pub fn init<P: TimersPermission + 'static>( op_base64_atob::decl(), op_base64_btoa::decl(), op_encoding_normalize_label::decl(), + op_encoding_decode_single::decl(), op_encoding_new_decoder::decl(), op_encoding_decode::decl(), op_encoding_encode_into::decl(), @@ -216,6 +217,64 @@ fn op_encoding_normalize_label(label: String) -> Result<String, AnyError> { } #[op] +fn op_encoding_decode_single( + data: ZeroCopyBuf, + options: DecoderOptions, +) -> Result<U16String, AnyError> { + let DecoderOptions { + label, + ignore_bom, + fatal, + } = options; + + let encoding = Encoding::for_label(label.as_bytes()).ok_or_else(|| { + range_error(format!( + "The encoding label provided ('{}') is invalid.", + label + )) + })?; + + let mut decoder = if ignore_bom { + encoding.new_decoder_without_bom_handling() + } else { + encoding.new_decoder_with_bom_removal() + }; + + let max_buffer_length = decoder + .max_utf16_buffer_length(data.len()) + .ok_or_else(|| range_error("Value too large to decode."))?; + + let mut output = vec![0; max_buffer_length]; + + if fatal { + let (result, _, written) = + decoder.decode_to_utf16_without_replacement(&data, &mut output, true); + match result { + DecoderResult::InputEmpty => { + output.truncate(written); + Ok(output.into()) + } + DecoderResult::OutputFull => { + Err(range_error("Provided buffer too small.")) + } + DecoderResult::Malformed(_, _) => { + Err(type_error("The encoded data is not valid.")) + } + } + } else { + let (result, _, written, _) = + decoder.decode_to_utf16(&data, &mut output, true); + match result { + CoderResult::InputEmpty => { + output.truncate(written); + Ok(output.into()) + } + CoderResult::OutputFull => Err(range_error("Provided buffer too small.")), + } + } +} + +#[op] fn op_encoding_new_decoder( state: &mut OpState, options: DecoderOptions, |