1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![warn(missing_docs)]
pub extern crate byteorder;
use std::io::{Read, Error, ErrorKind};
use byteorder::{ByteOrder, ReadBytesExt};
mod auto;
pub use auto::*;
pub trait Utf16ReadExt: ReadBytesExt {
fn shorts<T: ByteOrder>(self) -> Shorts<T, Self>
where Self: Sized {
Shorts(PhantomData, self)
}
fn utf16_chars<T: ByteOrder>(self) -> Chars<T, Self>
where Self: Sized {
Chars(PhantomData, self)
}
fn read_utf16_line<T: ByteOrder>(&mut self, buf: &mut String) -> Result<usize, Error> {
let mut len = 0;
for c in self.utf16_chars::<T>() {
match c {
Ok(c) => {
buf.push(c);
len += 1;
if c == '\n' {
break
}
}
Err(e) => match e.kind() {
ErrorKind::Interrupted => continue,
_ => return Err(e),
}
}
}
Ok(len)
}
fn utf16_lines<T: ByteOrder>(self) -> Lines<T, Self>
where Self: Sized {
Lines(PhantomData, self)
}
}
impl<T: Read> Utf16ReadExt for T {}
use std::marker::PhantomData;
#[derive(Debug)]
pub struct Shorts<T: ByteOrder, R>(PhantomData<T>, R);
#[derive(Debug)]
pub struct Chars<T: ByteOrder, R>(PhantomData<T>, R);
impl<T: ByteOrder, R: Utf16ReadExt> Iterator for Shorts<T, R> {
type Item = Result<u16, Error>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.1.read_u16::<T>() {
Ok(u) => break Some(Ok(u)),
Err(e) => match e.kind() {
ErrorKind::Interrupted => (),
ErrorKind::UnexpectedEof => break None,
_ => break Some(Err(e)),
}
}
}
}
}
use std::char::decode_utf16;
impl<T: ByteOrder, R: Utf16ReadExt> Iterator for Chars<T, R> {
type Item = Result<char, Error>;
fn next(&mut self) -> Option<Self::Item> {
let first = match self.1.read_u16::<T>() {
Ok(f) => f,
Err(ref e) if e.kind() == ErrorKind::UnexpectedEof => return None,
Err(e) => return Some(Err(e))
};
match decode_utf16(Some(first)).next().unwrap() {
Ok(c) => Some(Ok(c)),
Err(_) => {
let snd = match self.1.read_u16::<T>() {
Ok(f) => f,
Err(ref e) if e.kind() == ErrorKind::UnexpectedEof => return None,
Err(e) => return Some(Err(e))
};
Some(decode_utf16(Some(first).into_iter().chain(Some(snd))).next().unwrap()
.map_err(|e| Error::new(ErrorKind::InvalidData, e)))
}
}
}
}
#[derive(Debug)]
pub struct Lines<T: ByteOrder, B>(PhantomData<T>, B);
impl<T: ByteOrder, B: Utf16ReadExt> Iterator for Lines<T, B> {
type Item = Result<String, Error>;
fn next(&mut self) -> Option<Self::Item> {
let mut buf = String::new();
match self.1.read_utf16_line::<T>(&mut buf) {
Ok(0) => None,
Ok(_n) => {
if buf.ends_with("\n") {
buf.pop();
if buf.ends_with("\r") {
buf.pop();
}
}
Some(Ok(buf))
}
Err(e) => Some(Err(e))
}
}
}