CH-J ToolsSerververwaltung über SSH
Menü
Veröffentlichte Quellen

CH-J Tools

Durchsuchen Sie Verzeichnisse und Dateien einer bestimmten Anwendungsausgabe.

Quellen als ZIP herunterladen
CH-J / Server Manager 872 Dateien
core-20261030T220507Z-61e4558d889f Hinzugefügt: · Erstellt:
utf8.rs Hinzugefügt: Datum nicht erfasst 2,1 KB · 71 Zeilen
Code Datei herunterladen
1//! Incremental UTF-8 decoder with Node `StringDecoder` semantics: incomplete trailing
2//! sequences are kept for the next chunk, invalid bytes become U+FFFD.
4#[derive(Default)]
5pub struct Utf8Decoder {
6 pending: Vec<u8>,
7}
9fn sequence_length(first: u8) -> usize {
10 match first {
11 0x00..=0x7f => 1,
12 0xc2..=0xdf => 2,
13 0xe0..=0xef => 3,
14 0xf0..=0xf4 => 4,
15 _ => 0,
16 }
19impl Utf8Decoder {
20 pub fn write(&mut self, chunk: &[u8]) -> String {
21 let mut bytes = std::mem::take(&mut self.pending);
22 bytes.extend_from_slice(chunk);
23 // Keep an incomplete (but so far valid) sequence at the end for the next chunk.
24 let mut cut = bytes.len();
25 for back in 1..=3.min(bytes.len()) {
26 let index = bytes.len() - back;
27 let byte = bytes[index];
28 if byte & 0xc0 == 0x80 {
29 continue;
30 }
31 let needed = sequence_length(byte);
32 if needed > back {
33 cut = index;
34 }
35 break;
36 }
37 self.pending = bytes.split_off(cut);
38 String::from_utf8_lossy(&bytes).into_owned()
39 }
41 pub fn end(&mut self) -> String {
42 let rest = std::mem::take(&mut self.pending);
43 if rest.is_empty() {
44 String::new()
45 } else {
46 String::from_utf8_lossy(&rest).into_owned()
47 }
48 }
51#[cfg(test)]
52mod tests {
53 use super::*;
55 #[test]
56 fn split_multibyte() {
57 let text = "Příliš žluťoučký kůň 🐎";
58 let bytes = text.as_bytes();
59 for split in 0..bytes.len() {
60 let mut decoder = Utf8Decoder::default();
61 let mut out = decoder.write(&bytes[..split]);
62 out.push_str(&decoder.write(&bytes[split..]));
63 out.push_str(&decoder.end());
64 assert_eq!(out, text, "split at {split}");
65 }
66 let mut decoder = Utf8Decoder::default();
67 assert_eq!(decoder.write(&[0xff, b'a']), "\u{fffd}a");
68 assert_eq!(decoder.write(&[0xe2, 0x82]), "");
69 assert_eq!(decoder.end(), "\u{fffd}");
70 }
SHA-25609829b057ae9334bcf7d6c97798e2e1cdd002f6e7ae2b0a631433b262cfb7e34

CH-J Proprietary Software License 1.14 · Die Quellen werden unter der CH-J Proprietary Software License 1.14 bereitgestellt. Ihre Verfügbarkeit ändert die Lizenzbedingungen nicht und gewährt keine zusätzlichen Rechte.

SHA-256 des Archivs77380d4805485ffa4027fbe7858b5836f197a4aa9d52358a43e2d12d018744df
Dateien