summaryrefslogtreecommitdiff
path: root/src/loading
diff options
context:
space:
mode:
Diffstat (limited to 'src/loading')
-rw-r--r--src/loading/fs.rs6
-rw-r--r--src/loading/mem.rs8
-rw-r--r--src/loading/mod.rs62
3 files changed, 67 insertions, 9 deletions
diff --git a/src/loading/fs.rs b/src/loading/fs.rs
index 70ab5e53..55aa967b 100644
--- a/src/loading/fs.rs
+++ b/src/loading/fs.rs
@@ -6,7 +6,7 @@ use memmap2::Mmap;
use same_file::Handle;
use walkdir::WalkDir;
-use super::{FileHash, Loader};
+use super::{Buffer, FileHash, Loader};
use crate::font::FontInfo;
/// Loads fonts and files from the local file system.
@@ -130,7 +130,7 @@ impl Loader for FsLoader {
}
}
- fn load(&self, path: &Path) -> io::Result<Vec<u8>> {
- fs::read(path)
+ fn load(&self, path: &Path) -> io::Result<Buffer> {
+ Ok(fs::read(path)?.into())
}
}
diff --git a/src/loading/mem.rs b/src/loading/mem.rs
index 320de349..36e920d9 100644
--- a/src/loading/mem.rs
+++ b/src/loading/mem.rs
@@ -3,7 +3,7 @@ use std::collections::HashMap;
use std::io;
use std::path::{Path, PathBuf};
-use super::{FileHash, Loader};
+use super::{Buffer, FileHash, Loader};
use crate::font::FontInfo;
use crate::util::PathExt;
@@ -61,10 +61,10 @@ impl Loader for MemLoader {
}
}
- fn load(&self, path: &Path) -> io::Result<Vec<u8>> {
+ fn load(&self, path: &Path) -> io::Result<Buffer> {
self.files
.get(&path.normalize())
- .map(|cow| cow.clone().into_owned())
+ .map(|cow| cow.clone().into_owned().into())
.ok_or_else(|| io::ErrorKind::NotFound.into())
}
}
@@ -90,7 +90,7 @@ mod tests {
// Test that the file can be loaded.
assert_eq!(
- loader.load(Path::new("directory/../PTSans.ttf")).unwrap(),
+ loader.load(Path::new("directory/../PTSans.ttf")).unwrap().as_slice(),
data
);
}
diff --git a/src/loading/mod.rs b/src/loading/mod.rs
index d37dd1fc..ecc1e8d5 100644
--- a/src/loading/mod.rs
+++ b/src/loading/mod.rs
@@ -8,10 +8,14 @@ mod mem;
pub use fs::*;
pub use mem::*;
+use std::fmt::{self, Debug, Formatter};
use std::io;
+use std::ops::Deref;
use std::path::Path;
+use std::sync::Arc;
use crate::font::FontInfo;
+use crate::util::Prehashed;
/// A hash that identifies a file.
///
@@ -29,7 +33,7 @@ pub trait Loader {
fn resolve(&self, path: &Path) -> io::Result<FileHash>;
/// Load a file from a path.
- fn load(&self, path: &Path) -> io::Result<Vec<u8>>;
+ fn load(&self, path: &Path) -> io::Result<Buffer>;
}
/// A loader which serves nothing.
@@ -44,7 +48,61 @@ impl Loader for BlankLoader {
Err(io::ErrorKind::NotFound.into())
}
- fn load(&self, _: &Path) -> io::Result<Vec<u8>> {
+ fn load(&self, _: &Path) -> io::Result<Buffer> {
Err(io::ErrorKind::NotFound.into())
}
}
+
+/// A shared buffer that is cheap to clone.
+#[derive(Clone, Hash, Eq, PartialEq)]
+pub struct Buffer(Prehashed<Arc<Vec<u8>>>);
+
+impl Buffer {
+ /// Return a view into the buffer.
+ pub fn as_slice(&self) -> &[u8] {
+ self
+ }
+
+ /// Return a copy of the buffer as a vector.
+ pub fn to_vec(&self) -> Vec<u8> {
+ self.0.to_vec()
+ }
+}
+
+impl From<&[u8]> for Buffer {
+ fn from(slice: &[u8]) -> Self {
+ Self(Prehashed::new(Arc::new(slice.to_vec())))
+ }
+}
+
+impl From<Vec<u8>> for Buffer {
+ fn from(vec: Vec<u8>) -> Self {
+ Self(Prehashed::new(Arc::new(vec)))
+ }
+}
+
+impl From<Arc<Vec<u8>>> for Buffer {
+ fn from(arc: Arc<Vec<u8>>) -> Self {
+ Self(Prehashed::new(arc))
+ }
+}
+
+impl Deref for Buffer {
+ type Target = [u8];
+
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+impl AsRef<[u8]> for Buffer {
+ fn as_ref(&self) -> &[u8] {
+ self
+ }
+}
+
+impl Debug for Buffer {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ f.pad("Buffer(..)")
+ }
+}