1#[derive(Debug)]
10pub struct Reader<'a> {
11 buf: &'a [u8],
12 pos: usize,
13}
14
15impl<'a> Reader<'a> {
16 pub fn new(buf: &'a [u8], pos: usize) -> Self {
18 Reader { buf, pos }
19 }
20
21 pub fn remaining(&self) -> usize {
23 self.buf.len().saturating_sub(self.pos)
24 }
25
26 pub fn pos(&self) -> usize {
28 self.pos
29 }
30
31 pub fn at_end(&self) -> bool {
33 self.pos >= self.buf.len()
34 }
35
36 pub fn uint<const N: usize>(&mut self) -> Result<u64, crate::error::ProtoError> {
38 if self.pos + N > self.buf.len() {
39 return Err(crate::error::ProtoError::Overrun {
40 need: N,
41 at: self.pos,
42 have: self.buf.len(),
43 });
44 }
45 let mut v: u64 = 0;
46 for i in 0..N {
47 v |= (self.buf[self.pos + i] as u64) << (8 * i);
48 }
49 self.pos += N;
50 Ok(v)
51 }
52
53 pub fn u8v(&mut self) -> Result<u8, crate::error::ProtoError> {
55 if self.pos >= self.buf.len() {
56 return Err(crate::error::ProtoError::Overrun {
57 need: 1,
58 at: self.pos,
59 have: self.buf.len(),
60 });
61 }
62 let v = self.buf[self.pos];
63 self.pos += 1;
64 Ok(v)
65 }
66
67 pub fn skip(&mut self, n: usize) {
69 self.pos = (self.pos + n).min(self.buf.len());
70 }
71
72 pub fn take(&mut self, n: usize) -> Result<&'a [u8], crate::error::ProtoError> {
74 if self.pos + n > self.buf.len() {
75 return Err(crate::error::ProtoError::Overrun {
76 need: n,
77 at: self.pos,
78 have: self.buf.len(),
79 });
80 }
81 let s = &self.buf[self.pos..self.pos + n];
82 self.pos += n;
83 Ok(s)
84 }
85
86 pub fn zstring(&mut self, unicode: bool, base: usize) -> String {
93 if unicode {
94 if (base + self.pos) & 1 != 0 && !self.at_end() {
95 self.pos += 1;
96 }
97 let mut units = Vec::new();
98 while self.pos + 1 < self.buf.len() {
99 let lo = self.buf[self.pos];
100 let hi = self.buf[self.pos + 1];
101 self.pos += 2;
102 let u = lo as u16 | ((hi as u16) << 8);
103 if u == 0 {
104 break;
105 }
106 units.push(u);
107 }
108 String::from_utf16_lossy(&units)
109 } else {
110 let start = self.pos;
111 while self.pos < self.buf.len() && self.buf[self.pos] != 0 {
112 self.pos += 1;
113 }
114 let s = String::from_utf8_lossy(&self.buf[start..self.pos]).into_owned();
115 if self.pos < self.buf.len() {
116 self.pos += 1; }
118 s
119 }
120 }
121
122 pub fn fixed_string(&mut self, len: usize, unicode: bool) -> String {
125 let end = (self.pos + len).min(self.buf.len());
126 let raw = &self.buf[self.pos..end];
127 self.pos = end;
128 if unicode {
129 let units: Vec<u16> = raw
130 .chunks_exact(2)
131 .map(|c| c[0] as u16 | ((c[1] as u16) << 8))
132 .take_while(|&u| u != 0)
133 .collect();
134 String::from_utf16_lossy(&units)
135 } else {
136 String::from_utf8_lossy(raw.split(|&b| b == 0).next().unwrap_or(&[])).into_owned()
137 }
138 }
139}
140
141#[derive(Debug, Default)]
143pub struct Writer {
144 buf: Vec<u8>,
145 base: usize,
147}
148
149impl Writer {
150 pub fn new(base: usize) -> Self {
153 Writer { buf: Vec::new(), base }
154 }
155
156 pub fn len(&self) -> usize {
158 self.buf.len()
159 }
160
161 pub fn is_empty(&self) -> bool {
163 self.buf.is_empty()
164 }
165
166 pub fn into_inner(self) -> Vec<u8> {
168 self.buf
169 }
170
171 pub fn raw(&mut self, data: &[u8]) {
173 self.buf.extend_from_slice(data);
174 }
175
176 pub fn push(&mut self, v: u8) {
178 self.buf.push(v);
179 }
180
181 pub fn push_u16(&mut self, v: u16) {
183 self.buf.extend_from_slice(&v.to_le_bytes());
184 }
185
186 pub fn push_u32(&mut self, v: u32) {
188 self.buf.extend_from_slice(&v.to_le_bytes());
189 }
190
191 pub fn push_u64(&mut self, v: u64) {
193 self.buf.extend_from_slice(&v.to_le_bytes());
194 }
195
196 pub fn pad_to_parity(&mut self) {
199 if (self.base + self.buf.len()) & 1 != 0 {
200 self.buf.push(0);
201 }
202 }
203
204 pub fn zstring(&mut self, s: &str, unicode: bool) {
206 if unicode {
207 self.pad_to_parity();
208 for unit in s.encode_utf16() {
209 self.buf.extend_from_slice(&unit.to_le_bytes());
210 }
211 self.buf.extend_from_slice(&[0, 0]);
212 } else {
213 self.buf.extend_from_slice(s.as_bytes());
214 self.buf.push(0);
215 }
216 }
217}