1pub mod dataset;
15mod traits;
16
17pub use dataset::{Dataset, FieldType, RasterDataset, VectorDataset};
18
19pub use traits::{
20 ByteRange, CogSupport, DataSink, DataSource, OverviewSupport, RasterRead, RasterWrite,
21};
22
23#[cfg(feature = "async")]
24pub use traits::{AsyncDataSource, AsyncRasterRead};
25
26#[cfg(feature = "std")]
27pub mod mmap;
28
29#[cfg(feature = "std")]
30pub use mmap::{MmapDataSource, MmapDataSourceRw};
31
32#[cfg(feature = "std")]
33mod file {
34 use std::fs::File;
37 use std::io::{Read, Seek, SeekFrom};
38 use std::path::{Path, PathBuf};
39 use std::sync::Mutex;
40
41 use crate::error::{IoError, OxiGdalError, Result};
42 use crate::io::{ByteRange, DataSource};
43
44 pub struct FileDataSource {
46 path: PathBuf,
47 file: Mutex<File>,
48 size: u64,
49 }
50
51 impl FileDataSource {
52 pub fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
57 let path = path.as_ref().to_path_buf();
58 let file = File::open(&path).map_err(|e| {
59 OxiGdalError::Io(IoError::Read {
60 message: format!("Failed to open file '{}': {}", path.display(), e),
61 })
62 })?;
63
64 let metadata = file.metadata().map_err(|e| {
65 OxiGdalError::Io(IoError::Read {
66 message: format!("Failed to get file metadata: {e}"),
67 })
68 })?;
69
70 Ok(Self {
71 path,
72 file: Mutex::new(file),
73 size: metadata.len(),
74 })
75 }
76
77 #[must_use]
79 pub fn path(&self) -> &Path {
80 &self.path
81 }
82 }
83
84 impl DataSource for FileDataSource {
85 fn size(&self) -> Result<u64> {
86 Ok(self.size)
87 }
88
89 fn read_range(&self, range: ByteRange) -> Result<Vec<u8>> {
90 let mut file = self.file.lock().map_err(|e| OxiGdalError::Internal {
91 message: format!("Failed to lock file mutex: {e}"),
92 })?;
93
94 file.seek(SeekFrom::Start(range.start)).map_err(|_| {
95 OxiGdalError::Io(IoError::Seek {
96 position: range.start,
97 })
98 })?;
99
100 let len = range.len() as usize;
101 let mut buffer = vec![0u8; len];
102 file.read_exact(&mut buffer).map_err(|e| {
103 OxiGdalError::Io(IoError::Read {
104 message: format!(
105 "Failed to read {} bytes at offset {}: {}",
106 len, range.start, e
107 ),
108 })
109 })?;
110
111 Ok(buffer)
112 }
113 }
114
115 impl std::fmt::Debug for FileDataSource {
116 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117 f.debug_struct("FileDataSource")
118 .field("path", &self.path)
119 .field("size", &self.size)
120 .finish()
121 }
122 }
123}
124
125#[cfg(feature = "std")]
126pub use file::FileDataSource;