(
&self,
ctx: Ctx<'js>,
bytes: Opt<ObjectBytes<'js>>,
options: Opt<Value<'js>>,
)
| 111 | } |
| 112 | |
| 113 | pub fn decode( |
| 114 | &self, |
| 115 | ctx: Ctx<'js>, |
| 116 | bytes: Opt<ObjectBytes<'js>>, |
| 117 | options: Opt<Value<'js>>, |
| 118 | ) -> Result<String> { |
| 119 | let mut stream = false; |
| 120 | if let Some(opts) = options.0.as_ref().and_then(|v| v.as_object()) { |
| 121 | if let Some(s) = opts.get_optional("stream")? { |
| 122 | stream = s; |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | // Per the Encoding spec, the BufferSource is copied at the decode |
| 127 | // step. If the underlying buffer has been detached by the `options` |
| 128 | // getter (WPT `textdecoder-arguments` "detached during arg |
| 129 | // conversion" test), treat it as an empty byte sequence rather |
| 130 | // than throwing. |
| 131 | let input_bytes: &[u8] = bytes |
| 132 | .0 |
| 133 | .as_ref() |
| 134 | .and_then(ObjectBytes::as_bytes_opt) |
| 135 | .unwrap_or(&[]); |
| 136 | |
| 137 | let mut pending = self.pending.borrow_mut(); |
| 138 | |
| 139 | // Combine pending bytes with new input |
| 140 | let combined: Vec<u8>; |
| 141 | let mut data: &[u8] = if pending.is_empty() { |
| 142 | input_bytes |
| 143 | } else { |
| 144 | pending.extend_from_slice(input_bytes); |
| 145 | combined = std::mem::take(&mut *pending); |
| 146 | &combined |
| 147 | }; |
| 148 | |
| 149 | if !stream { |
| 150 | self.bom_seen.set(false); |
| 151 | } |
| 152 | |
| 153 | // Strip BOM if needed (only on first chunk of a decode sequence) |
| 154 | if !self.ignore_bom && !self.bom_seen.get() { |
| 155 | let skip = match self.encoder { |
| 156 | Encoder::Utf8 if data.starts_with(&[0xEF, 0xBB, 0xBF]) => 3, |
| 157 | Encoder::Utf16le if data.starts_with(&[0xFF, 0xFE]) => 2, |
| 158 | Encoder::Utf16be if data.starts_with(&[0xFE, 0xFF]) => 2, |
| 159 | _ => 0, |
| 160 | }; |
| 161 | |
| 162 | if skip > 0 { |
| 163 | self.bom_seen.set(true); |
| 164 | data = &data[skip..]; |
| 165 | } else if stream |
| 166 | && match self.encoder { |
| 167 | Encoder::Utf8 => data == [0xEF] || data == [0xEF, 0xBB], |
| 168 | Encoder::Utf16le => data == [0xFF], |
| 169 | Encoder::Utf16be => data == [0xFE], |
| 170 | _ => false, |
no test coverage detected