bytes_kman/std/
os_str.rs

1use std::ffi::OsString;
2
3use crate::{TBuffer, TBytes};
4
5// TODO: Should fix on linux utf16 characters will be ignored
6impl TBytes for std::ffi::OsString {
7    fn size(&self) -> usize {
8        self.len() * 2 + 0usize.size()
9    }
10
11    fn to_bytes(&self) -> Vec<u8> {
12        let mut buffer = Vec::with_capacity(self.size());
13        buffer.append(&mut self.len().to_bytes());
14        #[cfg(target_os = "linux")]
15        use std::os::unix::ffi::OsStrExt;
16        #[cfg(target_os = "windows")]
17        use std::os::windows::ffi::OsStrExt;
18
19        #[cfg(target_os = "linux")]
20        for byte in self.as_bytes() {
21            {
22                buffer.push(*byte);
23                buffer.push(0);
24            }
25        }
26        #[cfg(target_os = "windows")]
27        for byte in self.encode_wide() {
28            buffer.append(&mut byte.to_bytes())
29        }
30
31        buffer
32    }
33
34    fn from_bytes(buffer: &mut TBuffer) -> Option<Self>
35    where
36        Self: Sized,
37    {
38        if buffer.len() < Self::default().size() {
39            return None;
40        }
41        let len = usize::from_bytes(buffer)?;
42        if buffer.len() < len * 2 {
43            let mut bytes = len.to_bytes();
44            while let Some(byte) = bytes.pop() {
45                buffer.insert(0, byte)
46            }
47            return None;
48        }
49
50        let mut buff = Vec::with_capacity(len);
51        for _ in 0..len {
52            #[cfg(target_os = "linux")]
53            {
54                let mut iter = buffer.drain(..2);
55                let value = iter.next();
56                if let Some(value) = value {
57                    if iter.next().is_some() {
58                        buff.push(value);
59                    } else {
60                        drop(iter);
61                        buffer.insert(0, value);
62                        while let Some(byte) = buff.pop() {
63                            buffer.insert(0, byte);
64                        }
65                        let mut bytes = len.to_bytes();
66                        while let Some(byte) = bytes.pop() {
67                            buffer.insert(0, byte)
68                        }
69                        return None;
70                    }
71                } else {
72                    drop(iter);
73                    while let Some(byte) = buff.pop() {
74                        buffer.insert(0, byte);
75                    }
76                    let mut bytes = len.to_bytes();
77                    while let Some(byte) = bytes.pop() {
78                        buffer.insert(0, byte)
79                    }
80                    return None;
81                }
82            }
83            #[cfg(target_os = "windows")]
84            {
85                if let Some(value) = u16::from_bytes(buffer) {
86                    buff.push(value);
87                } else {
88                    while let Some(element) = buff.pop() {
89                        let mut bytes = element.to_bytes();
90                        while let Some(byte) = bytes.pop() {
91                            buffer.insert(0, byte);
92                        }
93                    }
94                    let mut bytes = len.to_bytes();
95                    while let Some(byte) = bytes.pop() {
96                        buffer.insert(0, byte)
97                    }
98                    return None;
99                }
100            }
101        }
102        #[cfg(target_os = "linux")]
103        use std::os::unix::ffi::OsStringExt;
104        #[cfg(target_os = "windows")]
105        use std::os::windows::ffi::OsStringExt;
106
107        #[cfg(target_os = "linux")]
108        return Some(OsString::from_vec(buff));
109        #[cfg(target_os = "windows")]
110        return Some(OsString::from_wide(&buff));
111    }
112}
113
114#[cfg(test)]
115mod test {
116    use std::ffi::OsString;
117
118    use crate::TBytes;
119    #[test]
120    fn os_string() {
121        let a = OsString::from("Hello World");
122        let mut bytes = a.to_bytes();
123
124        let b = OsString::from_bytes(&mut bytes).unwrap();
125        assert_eq!(a, b);
126    }
127
128    #[test]
129    fn incomplite() {
130        let mut buffer = Vec::new();
131        buffer.append(&mut 4usize.to_bytes());
132        buffer.push(b'g');
133        buffer.push(0);
134        buffer.push(b'r');
135        buffer.push(0);
136        buffer.push(b'a');
137        buffer.push(0);
138        let clone_buffer = buffer.clone();
139
140        let other_buffer = OsString::from_bytes(&mut buffer);
141        if let Some(other_buffer) = other_buffer {
142            panic!("This should be possible! Other buffer: {other_buffer:?}");
143        }
144
145        assert_eq!(buffer, clone_buffer);
146
147        buffer.push(b'y');
148        buffer.push(0);
149        let value = OsString::from_bytes(&mut buffer).unwrap();
150        assert_eq!(value, OsString::from("gray"))
151    }
152}