1use std::io::{Write, Result, Error, ErrorKind};
2
3use byteorder::{ByteOrder, WriteBytesExt};
4
5pub trait Utf16WriteExt: WriteBytesExt {
7 fn write_shorts<T: ByteOrder>(&mut self, buf: &[u16]) -> Result<usize> {
9 let mut len = 0;
10 for &short in buf {
11 match self.write_u16::<T>(short) {
12 Ok(()) => (),
13 Err(_) if len > 0 => return Ok(len),
14 Err(e) => return Err(e),
15 }
16 len += 1;
17 }
18 Ok(len)
19 }
20 fn write_all_shorts<T: ByteOrder>(&mut self, mut buf: &[u16]) -> Result<()> {
22 while !buf.is_empty() {
23 match self.write_shorts::<T>(buf) {
24 Ok(0) => return Err(Error::new(ErrorKind::WriteZero,
25 "failed to write whole buffer")),
26 Ok(n) => buf = &buf[n..],
27 Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
28 Err(e) => return Err(e),
29 }
30 }
31 Ok(())
32 }
33 fn write_bom<T: ByteOrder>(&mut self) -> Result<()> {
35 self.write_u16::<T>(0xfeff)
36 }
37 fn write_utf16_string<'a, T: ByteOrder>(&mut self, s: &'a str) -> Result<Utf16Written<'a>> {
41 let mut encoder = s.encode_utf16();
42
43 if let Some(short) = encoder.next() {
44 match self.write_u16::<T>(short) {
45 Ok(()) => (),
46 Err(e) => return Err(e),
47 }
48 }
49 while let Some(short) = encoder.next() {
50 match self.write_u16::<T>(short) {
51 Ok(()) => (),
52 Err(_) => return Ok(Utf16Written::Missing(encoder)),
53 }
54 }
55 Ok(Utf16Written::FullyComplete)
56 }
57}
58
59impl<T: Write> Utf16WriteExt for T {}
60
61use std::str::EncodeUtf16;
62
63pub enum Utf16Written<'a> {
65 FullyComplete,
67 Missing(EncodeUtf16<'a>)
69}