feat(body): add body::aggregate and body::to_bytes functions
				
					
				
			Adds utility functions to `hyper::body` to help asynchronously collecting all the buffers of some `HttpBody` into one. - `aggregate` will collect all into an `impl Buf` without copying the contents. This is ideal if you don't need a contiguous buffer. - `to_bytes` will copy all the data into a single contiguous `Bytes` buffer.
This commit is contained in:
		
							
								
								
									
										75
									
								
								src/common/buf.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/common/buf.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| use std::collections::VecDeque; | ||||
| use std::io::IoSlice; | ||||
|  | ||||
| use bytes::Buf; | ||||
|  | ||||
| pub(crate) struct BufList<T> { | ||||
|     bufs: VecDeque<T>, | ||||
| } | ||||
|  | ||||
| impl<T: Buf> BufList<T> { | ||||
|     pub(crate) fn new() -> BufList<T> { | ||||
|         BufList { | ||||
|             bufs: VecDeque::new(), | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     pub(crate) fn push(&mut self, buf: T) { | ||||
|         debug_assert!(buf.has_remaining()); | ||||
|         self.bufs.push_back(buf); | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     pub(crate) fn bufs_cnt(&self) -> usize { | ||||
|         self.bufs.len() | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T: Buf> Buf for BufList<T> { | ||||
|     #[inline] | ||||
|     fn remaining(&self) -> usize { | ||||
|         self.bufs.iter().map(|buf| buf.remaining()).sum() | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn bytes(&self) -> &[u8] { | ||||
|         for buf in &self.bufs { | ||||
|             return buf.bytes(); | ||||
|         } | ||||
|         &[] | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn advance(&mut self, mut cnt: usize) { | ||||
|         while cnt > 0 { | ||||
|             { | ||||
|                 let front = &mut self.bufs[0]; | ||||
|                 let rem = front.remaining(); | ||||
|                 if rem > cnt { | ||||
|                     front.advance(cnt); | ||||
|                     return; | ||||
|                 } else { | ||||
|                     front.advance(rem); | ||||
|                     cnt -= rem; | ||||
|                 } | ||||
|             } | ||||
|             self.bufs.pop_front(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #[inline] | ||||
|     fn bytes_vectored<'t>(&'t self, dst: &mut [IoSlice<'t>]) -> usize { | ||||
|         if dst.is_empty() { | ||||
|             return 0; | ||||
|         } | ||||
|         let mut vecs = 0; | ||||
|         for buf in &self.bufs { | ||||
|             vecs += buf.bytes_vectored(&mut dst[vecs..]); | ||||
|             if vecs == dst.len() { | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         vecs | ||||
|     } | ||||
| } | ||||
| @@ -7,6 +7,7 @@ macro_rules! ready { | ||||
|     }; | ||||
| } | ||||
|  | ||||
| pub(crate) mod buf; | ||||
| pub(crate) mod drain; | ||||
| pub(crate) mod exec; | ||||
| pub(crate) mod io; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user