1use std::io;
2use std::io::{Error, ErrorKind, Write};
3use std::mem::size_of;
4use encoding::{Encoding, EncoderTrap};
5use encoding::all::{UTF_16BE, UTF_16LE};
6
7pub trait StringWrite : private::Sealed {
13
14 fn write_string_u16_le_len_utf8(&mut self, string: &str) -> io::Result<usize>;
19
20 fn write_string_u16_be_len_utf8(&mut self, string: &str) -> io::Result<usize>;
25
26 fn write_string_u32_le_len_utf8(&mut self, string: &str) -> io::Result<usize>;
31
32 fn write_string_u32_be_len_utf8(&mut self, string: &str) -> io::Result<usize>;
37
38 fn write_string_zero_terminated_utf8(&mut self, string: &str) -> io::Result<usize>;
45
46 fn write_string_utf8(&mut self, string: &str) -> io::Result<usize>;
51
52 fn write_string_utf16_be(&mut self, string: &str) -> io::Result<usize>;
57
58 fn write_string_utf16_le(&mut self, string: &str) -> io::Result<usize>;
63
64 fn write_string_utf32_be(&mut self, string: &str) -> io::Result<usize>;
69
70 fn write_string_utf32_le(&mut self, string: &str) -> io::Result<usize>;
75
76 fn write_java_data_output_utf(&mut self, string: &str) -> io::Result<usize>;
85}
86
87
88const ZERO: [u8; 1] = [0u8];
89impl <T> StringWrite for T where T: Write {
90 fn write_string_u16_le_len_utf8(&mut self, string: &str) -> io::Result<usize> {
91 let x = string.as_bytes();
92 let len_u16 = x.len() as u16;
93 if x.len() != len_u16 as usize {
94 return Err(Error::new(ErrorKind::Other, "string too long"));
95 }
96
97 self.write_all(len_u16.to_le_bytes().as_slice())?;
98 self.write_all(x)?;
99 return Ok(x.len()+2);
100 }
101
102 fn write_string_u16_be_len_utf8(&mut self, string: &str) -> io::Result<usize> {
103 let x = string.as_bytes();
104 let len_u16 = x.len() as u16;
105 if x.len() != len_u16 as usize {
106 return Err(Error::new(ErrorKind::Other, "string too long"));
107 }
108
109 self.write_all(len_u16.to_be_bytes().as_slice())?;
110 self.write_all(x)?;
111 return Ok(x.len()+2);
112 }
113
114 fn write_string_u32_le_len_utf8(&mut self, string: &str) -> io::Result<usize> {
115 let x = string.as_bytes();
116 self.write_all((x.len() as u32).to_le_bytes().as_slice())?;
117 self.write_all(x)?;
118 return Ok(x.len()+4);
119 }
120
121 fn write_string_u32_be_len_utf8(&mut self, string: &str) -> io::Result<usize> {
122 let x = string.as_bytes();
123 self.write_all((x.len() as u32).to_be_bytes().as_slice())?;
124 self.write_all(x)?;
125 return Ok(x.len()+4);
126 }
127
128 fn write_string_zero_terminated_utf8(&mut self, string: &str) -> io::Result<usize> {
129 let x = string.as_bytes();
130 if x.len() == 0 {
131 return Ok(0);
132 }
133
134 for i in 0 .. x.len()-1 {
135 if x[i] == 0 {
136 return Err(Error::new(ErrorKind::InvalidInput, "Null byte found in string"));
137 }
138 }
139
140 if x[x.len()-1] == 0 {
141 self.write_all(x)?;
142 return Ok(x.len());
143 }
144
145 self.write_all(x)?;
146 self.write_all(&ZERO)?;
147 return Ok(x.len()+1);
148 }
149
150 fn write_string_utf8(&mut self, string: &str) -> io::Result<usize> {
151 let x = string.as_bytes();
152 self.write_all(x)?;
153 return Ok(x.len());
154 }
155
156 fn write_string_utf16_be(&mut self, string: &str) -> io::Result<usize> {
157 let encoded = UTF_16BE.encode(string, EncoderTrap::Strict)
158 .map_err(|e| Error::new(ErrorKind::Other, e.as_ref()))?;
159 self.write_all(encoded.as_slice())?;
160 return Ok(encoded.len());
161 }
162
163 fn write_string_utf16_le(&mut self, string: &str) -> io::Result<usize> {
164 let encoded = UTF_16LE.encode(string, EncoderTrap::Strict)
165 .map_err(|e| Error::new(ErrorKind::Other, e.as_ref()))?;
166 self.write_all(encoded.as_slice())?;
167 return Ok(encoded.len());
168 }
169
170 #[cfg(target_endian = "big")]
171 fn write_string_utf32_be(&mut self, string: &str) -> io::Result<usize> {
172 let mut data: Vec<char> = string.chars().collect();
173 let sl : &mut [u8] = unsafe { std::slice::from_raw_parts_mut(data.as_mut_ptr().cast(), data.len() * size_of::<char>()) };
174 self.write_all(sl)?;
175 return Ok(sl.len());
176 }
177
178 #[cfg(target_endian = "big")]
179 fn write_string_utf32_le(&mut self, string: &str) -> io::Result<usize> {
180 let mut data: Vec<u32> = string.chars().map(|c| c as u32).collect();
181 for i in 0 .. data.len() {
182 data[i] = data[i].to_le();
183 }
184
185 let sl : &mut [u8] = unsafe { std::slice::from_raw_parts_mut(data.as_mut_ptr().cast(), data.len() * size_of::<u32>()) };
186 self.write_all(sl)?;
187 return Ok(sl.len());
188 }
189
190 #[cfg(target_endian = "little")]
191 fn write_string_utf32_be(&mut self, string: &str) -> io::Result<usize> {
192 let mut data: Vec<u32> = string.chars().map(|c| c as u32).collect();
193 for i in 0 .. data.len() {
194 data[i] = data[i].to_be();
195 }
196
197 let sl : &mut [u8] = unsafe { std::slice::from_raw_parts_mut(data.as_mut_ptr().cast(), data.len() * size_of::<u32>()) };
198 self.write_all(sl)?;
199 return Ok(sl.len());
200 }
201
202 #[cfg(target_endian = "little")]
203 fn write_string_utf32_le(&mut self, string: &str) -> io::Result<usize> {
204 let mut data: Vec<char> = string.chars().collect();
205 let sl : &mut [u8] = unsafe { std::slice::from_raw_parts_mut(data.as_mut_ptr().cast(), data.len() * size_of::<char>()) };
206 self.write_all(sl)?;
207 return Ok(sl.len());
208 }
209
210 fn write_java_data_output_utf(&mut self, string: &str) -> io::Result<usize> {
211 let encoded = UTF_16LE.encode(string, EncoderTrap::Strict)
212 .map_err(|e| Error::new(ErrorKind::Other, e.as_ref()))?;
213
214 if encoded.len() & 1 != 0 {
215 panic!("UTF-16 encoder failed and gave a odd number of bytes as output without reporting an error!");
216 }
217
218 let sl : &[u16] = unsafe { std::slice::from_raw_parts(encoded.as_ptr().cast(), encoded.len() >> 1) };
219 let mut count : usize = 0;
220 for c_le in sl {
221 let c = c_le.to_le();
222 if c < 0x80 && c != 0 {
223 count+=1;
224 continue;
225 }
226 if c >= 0x800 {
227 count+=3;
228 continue;
229 }
230 count+=2;
231 }
232
233 if count > 65535 {
234 return Err(Error::new(ErrorKind::Other, "String length exceeds maximum allowed value"));
235 }
236
237 let mut data : Vec<u8> = vec![0u8; count+2];
238 let mut index = 2usize;
239 data[0] = ((count >> 8)& 0xFFusize) as u8;
241 data[1] = ((count >> 0)& 0xFFusize) as u8;
242
243 for c_le in sl {
244 let c = c_le.to_le();
245 if c < 0x80 && c != 0 {
246 data[index] = c as u8;
247 index+=1;
248 continue;
249 }
250
251 if c >= 0x800 {
252 data[index] = (0xE0 | ((c >> 12) & 0x0F)) as u8;
253 data[index+1] = (0x80 | ((c >> 6) & 0x3F)) as u8;
254 data[index+2] = (0x80 | ((c >> 0) & 0x3F)) as u8;
255 index+=3;
256 continue;
257 }
258
259 data[index] = (0xC0 | ((c >> 6) & 0x1F)) as u8;
260 data[index+1] = (0x80 | ((c >> 0) & 0x3F)) as u8;
261 index+=2;
262 }
263
264 self.write_all(data.as_slice())?;
265 return Ok(data.len());
266 }
267}
268
269mod private {
270 use std::io::Write;
271
272 impl <T> Sealed for T where T: Write {}
273 pub trait Sealed {
274
275 }
276}