MCPcopy Create free account
hub / github.com/awslabs/llrt / decode_data

Method decode_data

modules/llrt_string_decoder/src/string_decoder.rs:29–192  ·  view source on GitHub ↗

Try to decode the given buffer and store the incomplete bytes. The logic was adapted from the [Node implementation]. [Node implementation]: https://github.com/nodejs/node/blob/ba06c5c509956dc413f91b755c1c93798bb700d4/src/string_decoder.cc#L66

(&mut self, ctx: &Ctx<'_>, mut data: &[u8])

Source from the content-addressed store, hash-verified

27 ///
28 /// [Node implementation]: https://github.com/nodejs/node/blob/ba06c5c509956dc413f91b755c1c93798bb700d4/src/string_decoder.cc#L66
29 fn decode_data(&mut self, ctx: &Ctx<'_>, mut data: &[u8]) -> Result<String> {
30 let mut result = String::new();
31
32 if matches!(
33 self.encoder,
34 Encoder::Utf8 | Encoder::Utf16le | Encoder::Base64
35 ) {
36 // See if we want bytes to finish a character from the previous
37 // chunk; if so, copy the new bytes to the missing bytes buffer
38 // and create a string from it that is to be prepended to the main body.
39 if self.missing_bytes > 0 {
40 if matches!(self.encoder, Encoder::Utf8) {
41 // For UTF-8, we need special alignment treatment:
42 // If an incomplete character is found at a chunk boundary, we use
43 // its remainder and try to decode it.
44 let mut i = 0;
45 while i < data.len() && i < self.missing_bytes {
46 if (data[i] & 0xC0) != 0x80 {
47 // This byte is not a continuation byte even though it should have
48 // been one. We stop decoding of the incomplete character at this
49 // point (but still use the rest of the incomplete bytes from this
50 // chunk) and assume that the new, unexpected byte starts a new one.
51 self.missing_bytes = 0;
52 self.buffer.extend_from_slice(&data[..i]);
53 self.buffered_bytes += i;
54 data = &data[i..];
55 break;
56 }
57 i += 1;
58 }
59 } else if matches!(self.encoder, Encoder::Utf16le) {
60 // For UTF-16le, we need special alignment treatment:
61 // If we have a high surrogate we need to extend the missing bytes
62 // to 3 to get the low surrogate.
63 let mut i = 0;
64 while i < data.len() && i < self.missing_bytes {
65 if (data[i] & 0xFC) == 0xD8 {
66 self.missing_bytes = 3;
67 break;
68 }
69 i += 1;
70 }
71 }
72
73 let found_bytes = std::cmp::min(data.len(), self.missing_bytes);
74 self.buffer.extend_from_slice(&data[..found_bytes]);
75
76 data = &data[found_bytes..];
77
78 self.missing_bytes -= found_bytes;
79 self.buffered_bytes += found_bytes;
80 if self.missing_bytes == 0 {
81 // We have enough bytes to decode the buffered character
82 result = self.make_string(ctx, &self.buffer)?;
83 self.buffer.clear();
84 self.buffered_bytes = 0;
85 }
86 }

Callers 2

endMethod · 0.80
writeMethod · 0.80

Calls 4

make_stringMethod · 0.80
clearMethod · 0.65
lenMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected