]>
Commit | Line | Data |
---|---|---|
dfeec247 | 1 | use parking_lot::Mutex; |
48663c56 XL |
2 | use std::error::Error; |
3 | use std::path::Path; | |
4 | ||
5 | #[derive(Clone, Copy, Eq, PartialEq, Debug)] | |
6 | pub struct Addr(pub u32); | |
7 | ||
8 | impl Addr { | |
9 | pub fn as_usize(self) -> usize { | |
10 | self.0 as usize | |
11 | } | |
12 | } | |
13 | ||
60c5eb7d | 14 | pub trait SerializationSink: Sized + Send + Sync + 'static { |
48663c56 XL |
15 | fn from_path(path: &Path) -> Result<Self, Box<dyn Error>>; |
16 | ||
dfeec247 XL |
17 | /// Atomically write `num_bytes` to the sink. The implementation must ensure |
18 | /// that concurrent invocations of `write_atomic` do not conflict with each | |
19 | /// other. | |
20 | /// | |
21 | /// The `write` argument is a function that must fill the output buffer | |
22 | /// passed to it. The output buffer is guaranteed to be exactly `num_bytes` | |
23 | /// large. | |
48663c56 XL |
24 | fn write_atomic<W>(&self, num_bytes: usize, write: W) -> Addr |
25 | where | |
26 | W: FnOnce(&mut [u8]); | |
dfeec247 XL |
27 | |
28 | /// Same as write_atomic() but might be faster in cases where bytes to be | |
29 | /// written are already present in a buffer (as opposed to when it is | |
30 | /// benefical to directly serialize into the output buffer). | |
31 | fn write_bytes_atomic(&self, bytes: &[u8]) -> Addr { | |
32 | self.write_atomic(bytes.len(), |sink| sink.copy_from_slice(bytes)) | |
33 | } | |
48663c56 XL |
34 | } |
35 | ||
60c5eb7d XL |
36 | /// A `SerializationSink` that writes to an internal `Vec<u8>` and can be |
37 | /// converted into this raw `Vec<u8>`. This implementation is only meant to be | |
38 | /// used for testing and is not very efficient. | |
39 | pub struct ByteVecSink { | |
40 | data: Mutex<Vec<u8>>, | |
41 | } | |
48663c56 | 42 | |
60c5eb7d XL |
43 | impl ByteVecSink { |
44 | pub fn new() -> ByteVecSink { | |
45 | ByteVecSink { | |
46 | data: Mutex::new(Vec::new()), | |
48663c56 | 47 | } |
60c5eb7d | 48 | } |
48663c56 | 49 | |
60c5eb7d XL |
50 | pub fn into_bytes(self) -> Vec<u8> { |
51 | self.data.into_inner() | |
48663c56 | 52 | } |
60c5eb7d | 53 | } |
48663c56 | 54 | |
60c5eb7d XL |
55 | impl SerializationSink for ByteVecSink { |
56 | fn from_path(_path: &Path) -> Result<Self, Box<dyn Error>> { | |
57 | unimplemented!() | |
58 | } | |
48663c56 | 59 | |
60c5eb7d XL |
60 | fn write_atomic<W>(&self, num_bytes: usize, write: W) -> Addr |
61 | where | |
62 | W: FnOnce(&mut [u8]), | |
63 | { | |
64 | let mut data = self.data.lock(); | |
48663c56 | 65 | |
60c5eb7d | 66 | let start = data.len(); |
48663c56 | 67 | |
60c5eb7d | 68 | data.resize(start + num_bytes, 0); |
48663c56 | 69 | |
60c5eb7d | 70 | write(&mut data[start..]); |
48663c56 | 71 | |
60c5eb7d | 72 | Addr(start as u32) |
48663c56 | 73 | } |
60c5eb7d | 74 | } |
48663c56 | 75 | |
60c5eb7d XL |
76 | impl std::fmt::Debug for ByteVecSink { |
77 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
78 | write!(f, "ByteVecSink") | |
48663c56 XL |
79 | } |
80 | } |