wasefire_wire/
writer.rs

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use alloc::vec::Vec;
16
17#[derive(Default)]
18pub struct Writer<'a> {
19    owned: Vec<u8>,
20    chunks: Vec<Chunk<'a>>,
21}
22
23impl<'a> Writer<'a> {
24    pub(crate) fn new() -> Self {
25        Writer::default()
26    }
27
28    pub(crate) fn put_share(&mut self, data: &'a [u8]) {
29        self.chunks.push(Chunk::Borrowed(data));
30    }
31
32    pub(crate) fn put_copy(&mut self, data: &[u8]) {
33        let offset = self.owned.len();
34        self.owned.extend_from_slice(data);
35        let length = data.len();
36        self.chunks.push(Chunk::Owned { offset, length });
37    }
38
39    pub(crate) fn finalize(self, data: &mut Vec<u8>) {
40        data.reserve_exact(self.chunks.iter().map(|x| x.len()).sum());
41        for chunk in self.chunks {
42            data.extend_from_slice(chunk.slice(&self.owned));
43        }
44    }
45}
46
47enum Chunk<'a> {
48    Owned { offset: usize, length: usize },
49    Borrowed(&'a [u8]),
50}
51
52impl<'a> Chunk<'a> {
53    fn slice(&self, owned: &'a [u8]) -> &'a [u8] {
54        match *self {
55            Chunk::Owned { offset, length } => &owned[offset ..][.. length],
56            Chunk::Borrowed(x) => x,
57        }
58    }
59
60    fn len(&self) -> usize {
61        match *self {
62            Chunk::Owned { length, .. } => length,
63            Chunk::Borrowed(x) => x.len(),
64        }
65    }
66}