utf16_ext/
write.rs

1use std::io::{Write, Result, Error, ErrorKind};
2
3use byteorder::{ByteOrder, WriteBytesExt};
4
5/// An extension of `std::io::Write` for utf16
6pub trait Utf16WriteExt: WriteBytesExt {
7    /// Like `Write::write` but with `u16`s
8    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    /// Like `Write::write_all` but with `u16`s
21    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    /// Writes a byte order maker character
34    fn write_bom<T: ByteOrder>(&mut self) -> Result<()> {
35        self.write_u16::<T>(0xfeff)
36    }
37    /// Writes a string as UTF-16
38    ///
39    /// Returns Ok(len) of the string written so far
40    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
63/// Represents how much a string buffer was written
64pub enum Utf16Written<'a> {
65    /// Indicates that the whole string buffer written without errors
66    FullyComplete,
67    /// Indicates an erorr occured when writing, also gives the rest of the encoder
68    Missing(EncodeUtf16<'a>)
69}