1use std::ffi::OsString;
2
3use crate::{TBuffer, TBytes};
4
5impl 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}