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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use crate::{hint, Parcel, Error, ErrorKind, TryFromIntError, Settings};
use crate::types::Integer;
use std::io::prelude::*;
use std::io;
pub type SizeType = u32;
pub fn read_string(byte_count: usize,
read: &mut dyn Read,
settings: &Settings)
-> Result<String, Error> {
let bytes: Vec<u8> = read_items(byte_count, read, settings)?.collect();
String::from_utf8(bytes).map_err(Into::into)
}
pub fn read_items<T>(item_count: usize,
read: &mut dyn Read,
settings: &Settings)
-> Result<impl Iterator<Item=T>, Error>
where T: Parcel {
let mut elements = Vec::with_capacity(item_count);
for _ in 0..item_count {
let element = T::read(read, settings)?;
elements.push(element);
}
Ok(elements.into_iter())
}
pub fn write_items<'a,T>(items: impl IntoIterator<Item=&'a T>,
write: &mut dyn Write,
settings: &Settings)
-> Result<(), Error>
where T: Parcel + 'a {
for item in items.into_iter() {
item.write(write, settings)?;
}
Ok(())
}
pub fn read_list<T>(read: &mut dyn Read,
settings: &Settings,
hints: &mut hint::Hints)
-> Result<Vec<T>, Error>
where T: Parcel {
self::read_list_ext::<SizeType, T>(read, settings, hints)
}
pub fn write_list<'a,T,I>(elements: I,
write: &mut dyn Write,
settings: &Settings,
hints: &mut hint::Hints)
-> Result<(), Error>
where T: Parcel+'a,
I: IntoIterator<Item=&'a T> {
self::write_list_ext::<SizeType, T, I>(elements, write, settings, hints)
}
pub fn read_list_ext<S,T>(read: &mut dyn Read,
settings: &Settings,
hints: &mut hint::Hints)
-> Result<Vec<T>, Error>
where S: Integer,
T: Parcel {
match hints.current_field_length() {
Some(length) => {
match length.kind {
hint::LengthPrefixKind::Bytes => {
let byte_count = length.length;
let bytes: Vec<u8> = read_items(byte_count, read, settings)?.collect();
let mut read_back_bytes = io::Cursor::new(bytes);
let mut items = Vec::new();
while read_back_bytes.position() < byte_count as u64 {
let item = match T::read(&mut read_back_bytes, settings).map_err(|e| e.0) {
Ok(item) => item,
Err(ErrorKind::Io(ref io)) if io.kind() == io::ErrorKind::UnexpectedEof => {
panic!("length prefix in bytes does not match actual size");
},
Err(e) => return Err(e.into()),
};
items.push(item);
}
Ok(items)
},
hint::LengthPrefixKind::Elements => {
read_items(length.length, read, settings).map(|i| i.collect())
},
}
},
None => {
let size = S::read(read, settings)?;
let size: usize = size.to_usize().ok_or(TryFromIntError{ })?;
read_items(size, read, settings).map(|i| i.collect())
},
}
}
pub fn write_list_ext<'a,S,T,I>(elements: I,
write: &mut dyn Write,
settings: &Settings,
hints: &mut hint::Hints)
-> Result<(), Error>
where S: Integer,
T: Parcel+'a,
I: IntoIterator<Item=&'a T> {
let elements: Vec<_> = elements.into_iter().collect();
match hints.current_field_length() {
Some(_length) => {
()
},
_ => {
let length = S::from_usize(elements.len()).ok_or(TryFromIntError{ })?;
length.write(write, settings)?;
},
}
write_items(elements.into_iter(), write, settings)?;
Ok(())
}