1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::io; 15 use std::io::{Read, Write}; 16 17 use crate::io::ReadBuf; 18 19 pub(crate) struct FileBuf { 20 pub(crate) buf: Vec<u8>, 21 idx: usize, 22 } 23 24 impl FileBuf { 25 #[inline] with_capacity(n: usize) -> FileBuf26 pub(crate) fn with_capacity(n: usize) -> FileBuf { 27 FileBuf { 28 buf: Vec::with_capacity(n), 29 idx: 0, 30 } 31 } 32 remaining(&self) -> usize33 pub(crate) fn remaining(&self) -> usize { 34 self.buf.len() - self.idx 35 } 36 append_to(&mut self, buf: &mut ReadBuf<'_>) -> usize37 pub(crate) fn append_to(&mut self, buf: &mut ReadBuf<'_>) -> usize { 38 let n = std::cmp::min(self.remaining(), buf.remaining()); 39 let r_idx = n + self.idx; 40 buf.append(&self.buf[self.idx..r_idx]); 41 42 if r_idx == self.buf.len() { 43 self.idx = 0; 44 self.buf.truncate(0); 45 } else { 46 self.idx = r_idx; 47 } 48 n 49 } 50 51 #[inline] append(&mut self, other: &[u8], buf_size_limit: usize) -> usize52 pub(crate) fn append(&mut self, other: &[u8], buf_size_limit: usize) -> usize { 53 let n = std::cmp::min(other.len(), buf_size_limit); 54 self.buf.extend_from_slice(&other[..n]); 55 n 56 } 57 58 #[allow(clippy::uninit_vec)] 59 #[inline] reserve(&mut self, size: usize, buf_size_limit: usize)60 pub(crate) fn reserve(&mut self, size: usize, buf_size_limit: usize) { 61 let len = std::cmp::min(size, buf_size_limit); 62 self.buf.reserve(len.saturating_sub(self.buf.len())); 63 // need to set length in order to read 64 unsafe { self.buf.set_len(len) } 65 } 66 read<R: Read>(&mut self, io: &mut R) -> io::Result<usize>67 pub(crate) fn read<R: Read>(&mut self, io: &mut R) -> io::Result<usize> { 68 let ret = loop { 69 match io.read(&mut self.buf) { 70 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {} 71 res => break res, 72 } 73 }; 74 match ret { 75 Ok(n) => self.buf.truncate(n), 76 _ => self.buf.truncate(0), 77 } 78 ret 79 } 80 81 #[inline] write<W: Write>(&mut self, io: &mut W) -> io::Result<()>82 pub(crate) fn write<W: Write>(&mut self, io: &mut W) -> io::Result<()> { 83 let res = io.write_all(&self.buf); 84 self.buf.clear(); 85 res 86 } 87 88 // Returns the number of bytes that get dropped in the file buf 89 #[inline] drop_unread(&mut self) -> i6490 pub(crate) fn drop_unread(&mut self) -> i64 { 91 let ret = self.buf.len(); 92 self.clear(); 93 ret as i64 94 } 95 96 #[inline] clear(&mut self)97 pub(crate) fn clear(&mut self) { 98 self.idx = 0; 99 self.buf.clear(); 100 } 101 } 102