1use std::io::{Write, Result, Error};
2use futures::{Poll, Future};
3use byteorder::{ByteOrder, NativeEndian, BigEndian, LittleEndian};
4
5use pattern::{Buf, Window};
6use pattern::write::{self, U24, I24, U40, I40, U48, I48, U56, I56};
7use pattern::combinators::{PartialBuf, LE, BE};
8use matcher::{AsyncMatch, Matcher};
9use io::{AsyncWrite, AsyncIoError};
10
11pub struct PatternWriter<W>(W);
16impl<W: Write> PatternWriter<W> {
17 pub fn new(inner: W) -> Self {
19 PatternWriter(inner)
20 }
21}
22impl<W: Write> Write for PatternWriter<W> {
23 fn write(&mut self, buf: &[u8]) -> Result<usize> {
24 self.0.write(buf)
25 }
26 fn flush(&mut self) -> Result<()> {
27 self.0.flush()
28 }
29}
30impl<W> Matcher for PatternWriter<W> {
31 type Error = Error;
32}
33
34pub trait WriteInto<W: Write>: AsyncMatch<PatternWriter<W>> {
77 fn write_into(self, writer: W) -> WritePattern<Self, W> {
95 WritePattern(self.async_match(PatternWriter(writer)))
96 }
97
98 fn sync_write_into(self, writer: W) -> Result<Self::Value> {
100 self.write_into(writer).wait().map(|(_, v)| v).map_err(
101 |e| {
102 e.into_error()
103 },
104 )
105 }
106}
107impl<W: Write, T> WriteInto<W> for T
108where
109 T: AsyncMatch<PatternWriter<W>>,
110{
111}
112
113pub struct WritePattern<P, W>(P::Future)
117where
118 P: AsyncMatch<PatternWriter<W>>;
119impl<P, W> Future for WritePattern<P, W>
120where
121 P: AsyncMatch<PatternWriter<W>>,
122{
123 type Item = (W, P::Value);
124 type Error = AsyncIoError<W>;
125 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
126 Ok(self.0.poll().map_err(|e| e.map_state(|w| w.0))?.map(
127 |(m, v)| {
128 (m.0, v)
129 },
130 ))
131 }
132}
133
134pub struct WriteFlush<W>(super::futures::Flush<PatternWriter<W>>);
139impl<W: Write> Future for WriteFlush<W> {
140 type Item = (PatternWriter<W>, ());
141 type Error = AsyncIoError<PatternWriter<W>>;
142 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
143 Ok(self.0.poll()?.map(|m| (m, ())))
144 }
145}
146impl<W: Write> AsyncMatch<PatternWriter<W>> for write::Flush {
147 type Future = WriteFlush<W>;
148 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
149 WriteFlush(matcher.async_flush())
150 }
151}
152
153pub struct WriteBuf<W, B>(super::futures::WriteAll<PatternWriter<W>, B>);
168impl<W: Write, B: AsRef<[u8]>> Future for WriteBuf<W, B> {
169 type Item = (PatternWriter<W>, B);
170 type Error = AsyncIoError<PatternWriter<W>>;
171 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
172 self.0.poll().map_err(|e| e.map_state(|(w, _)| w))
173 }
174}
175impl<W: Write, B: AsRef<[u8]>> AsyncMatch<PatternWriter<W>> for Buf<B> {
176 type Future = WriteBuf<W, B>;
177 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
178 WriteBuf(matcher.async_write_all(self.0))
179 }
180}
181impl<W: Write> AsyncMatch<PatternWriter<W>> for Vec<u8> {
182 type Future = WriteBuf<W, Self>;
183 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
184 WriteBuf(matcher.async_write_all(self))
185 }
186}
187impl<W: Write> AsyncMatch<PatternWriter<W>> for String {
188 type Future = WriteBuf<W, Self>;
189 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
190 WriteBuf(matcher.async_write_all(self))
191 }
192}
193impl<W: Write, B: AsRef<[u8]>> AsyncMatch<PatternWriter<W>> for Window<B> {
194 type Future = WriteBuf<W, Self>;
195 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
196 WriteBuf(matcher.async_write_all(self))
197 }
198}
199
200pub struct WritePartialBuf<W, B>(super::futures::WriteBytes<PatternWriter<W>, B>);
222impl<W: Write, B: AsRef<[u8]>> Future for WritePartialBuf<W, B> {
223 type Item = (PatternWriter<W>, (B, usize));
224 type Error = AsyncIoError<PatternWriter<W>>;
225 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
226 self.0
227 .poll()
228 .map(|a| a.map(|(w, b, s)| (w, (b, s))))
229 .map_err(|e| e.map_state(|(w, _)| w))
230 }
231}
232impl<W: Write, B: AsRef<[u8]>> AsyncMatch<PatternWriter<W>> for PartialBuf<B> {
233 type Future = WritePartialBuf<W, B>;
234 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
235 WritePartialBuf(matcher.async_write(self.0))
236 }
237}
238
239pub struct WriteFixnum<W, P>
241where
242 P: AsyncMatch<PatternWriter<W>>,
243{
244 future: P::Future,
245}
246impl<W: Write, P> Future for WriteFixnum<W, P>
247where
248 P: AsyncMatch<PatternWriter<W>>,
249{
250 type Item = (PatternWriter<W>, ());
251 type Error = AsyncIoError<PatternWriter<W>>;
252 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
253 Ok(self.future.poll()?.map(|(w, _)| (w, ())))
254 }
255}
256
257macro_rules! impl_write_fixnum_pattern {
258 ($pat:ty, $size:expr, $conv:expr) => {
259 impl<W: Write> AsyncMatch<PatternWriter<W>> for $pat {
260 type Future = WriteFixnum<W, Buf<[u8; $size]>>;
261 fn async_match(self, matcher: PatternWriter<W>) -> Self::Future {
262 let mut buf = [0; $size];
263 $conv(&mut buf[..], self);
264 let future = Buf(buf).async_match(matcher);
265 WriteFixnum{future: future}
266 }
267 }
268 }
269}
270impl_write_fixnum_pattern!(u8, 1, |b: &mut [u8], n: Self| b[0] = n);
271impl_write_fixnum_pattern!(i8, 1, |b: &mut [u8], n: Self| b[0] = n as u8);
272
273impl_write_fixnum_pattern!(u16, 2, NativeEndian::write_u16);
274impl_write_fixnum_pattern!(BE<u16>, 2, |b: &mut [u8], n: Self| BigEndian::write_u16(b,n.0));
275impl_write_fixnum_pattern!(LE<u16>, 2, |b: &mut [u8], n: Self| LittleEndian::write_u16(b,n.0));
276impl_write_fixnum_pattern!(i16, 2, NativeEndian::write_i16);
277impl_write_fixnum_pattern!(BE<i16>, 2, |b: &mut [u8], n: Self| BigEndian::write_i16(b,n.0));
278impl_write_fixnum_pattern!(LE<i16>, 2, |b: &mut [u8], n: Self| LittleEndian::write_i16(b,n.0));
279
280impl_write_fixnum_pattern!(
281 U24, 3, |b: &mut [u8], n: Self| NativeEndian::write_uint(b, u64::from(n.0), 3));
282impl_write_fixnum_pattern!(
283 BE<U24>, 3, |b: &mut [u8], n: Self| BigEndian::write_uint(b,u64::from((n.0).0), 3));
284impl_write_fixnum_pattern!(
285 LE<U24>, 3, |b: &mut [u8], n: Self| LittleEndian::write_uint(b,u64::from((n.0).0), 3));
286impl_write_fixnum_pattern!(
287 I24, 3, |b: &mut [u8], n: Self| NativeEndian::write_int(b, i64::from(n.0), 3));
288impl_write_fixnum_pattern!(
289 BE<I24>, 3, |b: &mut [u8], n: Self| BigEndian::write_int(b,i64::from((n.0).0), 3));
290impl_write_fixnum_pattern!(
291 LE<I24>, 3, |b: &mut [u8], n: Self| LittleEndian::write_int(b,i64::from((n.0).0), 3));
292
293impl_write_fixnum_pattern!(u32, 4, NativeEndian::write_u32);
294impl_write_fixnum_pattern!(BE<u32>, 4, |b: &mut [u8], n: Self| BigEndian::write_u32(b,n.0));
295impl_write_fixnum_pattern!(LE<u32>, 4, |b: &mut [u8], n: Self| LittleEndian::write_u32(b,n.0));
296impl_write_fixnum_pattern!(i32, 4, NativeEndian::write_i32);
297impl_write_fixnum_pattern!(BE<i32>, 4, |b: &mut [u8], n: Self| BigEndian::write_i32(b,n.0));
298impl_write_fixnum_pattern!(LE<i32>, 4, |b: &mut [u8], n: Self| LittleEndian::write_i32(b,n.0));
299
300impl_write_fixnum_pattern!(U40, 5,
301 |b: &mut [u8], n: Self| NativeEndian::write_uint(b, n.0 as u64, 5));
302impl_write_fixnum_pattern!(BE<U40>, 5,
303 |b: &mut [u8], n: Self| BigEndian::write_uint(b,(n.0).0 as u64, 5));
304impl_write_fixnum_pattern!(LE<U40>, 5,
305 |b: &mut [u8], n: Self| LittleEndian::write_uint(b,(n.0).0 as u64, 5));
306impl_write_fixnum_pattern!(I40, 5,
307 |b: &mut [u8], n: Self| NativeEndian::write_int(b, n.0 as i64, 5));
308impl_write_fixnum_pattern!(BE<I40>, 5,
309 |b: &mut [u8], n: Self| BigEndian::write_int(b,(n.0).0 as i64, 5));
310impl_write_fixnum_pattern!(LE<I40>, 5,
311 |b: &mut [u8], n: Self| LittleEndian::write_int(b,(n.0).0 as i64, 5));
312
313impl_write_fixnum_pattern!(U48, 6,
314 |b: &mut [u8], n: Self| NativeEndian::write_uint(b, n.0 as u64, 6));
315impl_write_fixnum_pattern!(BE<U48>, 6,
316 |b: &mut [u8], n: Self| BigEndian::write_uint(b,(n.0).0 as u64, 6));
317impl_write_fixnum_pattern!(LE<U48>, 6,
318 |b: &mut [u8], n: Self| LittleEndian::write_uint(b,(n.0).0 as u64, 6));
319impl_write_fixnum_pattern!(I48, 6,
320 |b: &mut [u8], n: Self| NativeEndian::write_int(b, n.0 as i64, 6));
321impl_write_fixnum_pattern!(BE<I48>, 6,
322 |b: &mut [u8], n: Self| BigEndian::write_int(b,(n.0).0 as i64, 6));
323impl_write_fixnum_pattern!(LE<I48>, 6,
324 |b: &mut [u8], n: Self| LittleEndian::write_int(b,(n.0).0 as i64, 6));
325
326impl_write_fixnum_pattern!(U56, 7,
327 |b: &mut [u8], n: Self| NativeEndian::write_uint(b, n.0 as u64, 7));
328impl_write_fixnum_pattern!(BE<U56>, 7,
329 |b: &mut [u8], n: Self| BigEndian::write_uint(b,(n.0).0 as u64, 7));
330impl_write_fixnum_pattern!(LE<U56>, 7,
331 |b: &mut [u8], n: Self| LittleEndian::write_uint(b,(n.0).0 as u64, 7));
332impl_write_fixnum_pattern!(I56, 7,
333 |b: &mut [u8], n: Self| NativeEndian::write_int(b, n.0 as i64, 7));
334impl_write_fixnum_pattern!(BE<I56>, 7,
335 |b: &mut [u8], n: Self| BigEndian::write_int(b,(n.0).0 as i64, 7));
336impl_write_fixnum_pattern!(LE<I56>, 7,
337 |b: &mut [u8], n: Self| LittleEndian::write_int(b,(n.0).0 as i64, 7));
338
339impl_write_fixnum_pattern!(u64, 8, NativeEndian::write_u64);
340impl_write_fixnum_pattern!(BE<u64>, 8, |b: &mut [u8], n: Self| BigEndian::write_u64(b,n.0));
341impl_write_fixnum_pattern!(LE<u64>, 8, |b: &mut [u8], n: Self| LittleEndian::write_u64(b,n.0));
342impl_write_fixnum_pattern!(i64, 8, NativeEndian::write_i64);
343impl_write_fixnum_pattern!(BE<i64>, 8, |b: &mut [u8], n: Self| BigEndian::write_i64(b,n.0));
344impl_write_fixnum_pattern!(LE<i64>, 8, |b: &mut [u8], n: Self| LittleEndian::write_i64(b,n.0));