Skip to content

Commit 4429b00

Browse files
committed
Big rework: replace traits with specializations
Related changes: - For now: remove impl Dimension from Dataspace - Remove Clone from Dataspace/PropertyList, replace with .copy() - Remove FromID and ID traits
1 parent ada8b03 commit 4429b00

14 files changed

+433
-376
lines changed

hdf5-rs/src/container.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use ffi::h5d::H5Dopen2;
22
use ffi::h5g::{H5G_info_t, H5Gget_info, H5Gcreate2, H5Gopen2};
3-
use ffi::h5i::hid_t;
43
use ffi::h5l::{H5Lmove, H5Lcreate_soft, H5Lcreate_hard, H5Ldelete, H5L_SAME_LOC};
54
use ffi::h5p::{H5Pcreate, H5Pset_create_intermediate_group, H5P_DEFAULT};
65
use globals::H5P_LINK_CREATE;
@@ -9,18 +8,13 @@ use dataset::{Dataset, DatasetBuilder};
98
use datatype::ToDatatype;
109
use error::Result;
1110
use group::Group;
12-
use handle::{ID, FromID};
13-
use location::Location;
11+
use location::LocationType;
12+
use object::{Object, ObjectID};
1413
use plist::PropertyList;
1514
use util::to_cstring;
1615

1716
use std::default::Default;
1817

19-
fn group_info(id: hid_t) -> Result<H5G_info_t> {
20-
let info: *mut H5G_info_t = &mut H5G_info_t::default();
21-
h5call!(H5Gget_info(id, info)).and(Ok(unsafe { *info }))
22-
}
23-
2418
fn make_lcpl() -> Result<PropertyList> {
2519
h5lock!({
2620
let lcpl = PropertyList::from_id(h5try!(H5Pcreate(*H5P_LINK_CREATE)))?;
@@ -29,19 +23,26 @@ fn make_lcpl() -> Result<PropertyList> {
2923
}
3024

3125
/// A trait for HDF5 objects that can contain other objects (file, group).
32-
pub trait Container: Location {
26+
pub trait ContainerType : LocationType {}
27+
28+
impl<T: ContainerType> Object<T> {
29+
fn group_info(&self) -> Result<H5G_info_t> {
30+
let info: *mut H5G_info_t = &mut H5G_info_t::default();
31+
h5call!(H5Gget_info(self.id(), info)).and(Ok(unsafe { *info }))
32+
}
33+
3334
/// Returns the number of objects in the container (or 0 if the container is invalid).
34-
fn len(&self) -> u64 {
35-
group_info(self.id()).map(|info| info.nlinks).unwrap_or(0)
35+
pub fn len(&self) -> u64 {
36+
self.group_info().map(|info| info.nlinks).unwrap_or(0)
3637
}
3738

3839
/// Returns true if the container has no linked objects (or if the container is invalid).
39-
fn is_empty(&self) -> bool {
40+
pub fn is_empty(&self) -> bool {
4041
self.len() == 0
4142
}
4243

4344
/// Create a new group in a file or group.
44-
fn create_group(&self, name: &str) -> Result<Group> {
45+
pub fn create_group(&self, name: &str) -> Result<Group> {
4546
h5lock!({
4647
let lcpl = make_lcpl()?;
4748
let name = to_cstring(name)?;
@@ -52,14 +53,14 @@ pub trait Container: Location {
5253
}
5354

5455
/// Opens an existing group in a file or group.
55-
fn group(&self, name: &str) -> Result<Group> {
56+
pub fn group(&self, name: &str) -> Result<Group> {
5657
let name = to_cstring(name)?;
5758
Group::from_id(h5try!(H5Gopen2(
5859
self.id(), name.as_ptr(), H5P_DEFAULT)))
5960
}
6061

6162
/// Creates a soft link. Note: `src` and `dst` are relative to the current object.
62-
fn link_soft(&self, src: &str, dst: &str) -> Result<()> {
63+
pub fn link_soft(&self, src: &str, dst: &str) -> Result<()> {
6364
h5lock!({
6465
let lcpl = make_lcpl()?;
6566
let src = to_cstring(src)?;
@@ -71,7 +72,7 @@ pub trait Container: Location {
7172
}
7273

7374
/// Creates a hard link. Note: `src` and `dst` are relative to the current object.
74-
fn link_hard(&self, src: &str, dst: &str) -> Result<()> {
75+
pub fn link_hard(&self, src: &str, dst: &str) -> Result<()> {
7576
let src = to_cstring(src)?;
7677
let dst = to_cstring(dst)?;
7778
h5call!(H5Lcreate_hard(
@@ -80,7 +81,7 @@ pub trait Container: Location {
8081
}
8182

8283
/// Relinks an object. Note: `name` and `path` are relative to the current object.
83-
fn relink(&self, name: &str, path: &str) -> Result<()> {
84+
pub fn relink(&self, name: &str, path: &str) -> Result<()> {
8485
let name = to_cstring(name)?;
8586
let path = to_cstring(path)?;
8687
h5call!(H5Lmove(
@@ -89,20 +90,20 @@ pub trait Container: Location {
8990
}
9091

9192
/// Removes a link to an object from this file or group.
92-
fn unlink(&self, name: &str) -> Result<()> {
93+
pub fn unlink(&self, name: &str) -> Result<()> {
9394
let name = to_cstring(name)?;
9495
h5call!(H5Ldelete(
9596
self.id(), name.as_ptr(), H5P_DEFAULT
9697
)).and(Ok(()))
9798
}
9899

99100
/// Instantiates a new dataset builder.
100-
fn new_dataset<T: ToDatatype>(&self) -> DatasetBuilder<T> {
101-
DatasetBuilder::<T>::new::<Self>(self)
101+
pub fn new_dataset<D: ToDatatype>(&self) -> DatasetBuilder<D> {
102+
DatasetBuilder::<D>::new(&self)
102103
}
103104

104105
/// Opens an existing dataset in the file or group.
105-
fn dataset(&self, name: &str) -> Result<Dataset> {
106+
pub fn dataset(&self, name: &str) -> Result<Dataset> {
106107
let name = to_cstring(name)?;
107108
Dataset::from_id(h5try!(H5Dopen2(
108109
self.id(), name.as_ptr(), H5P_DEFAULT)))
@@ -112,10 +113,8 @@ pub trait Container: Location {
112113
#[cfg(test)]
113114
mod tests {
114115
use error::silence_errors;
115-
use handle::ID;
116+
use object::ObjectID;
116117
use test::with_tmp_file;
117-
use super::Container;
118-
use location::Location;
119118

120119
#[test]
121120
pub fn test_group() {

hdf5-rs/src/dataset.rs

Lines changed: 28 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ use ffi::h5p::{
1111
};
1212
use globals::H5P_LINK_CREATE;
1313

14-
use container::Container;
15-
use datatype::{Datatype, ToDatatype, AnyDatatype};
14+
use container::ContainerType;
15+
use datatype::{Datatype, ToDatatype};
1616
use error::Result;
1717
use filters::Filters;
18-
use handle::{Handle, ID, FromID, get_id_type};
19-
use location::Location;
20-
use object::Object;
18+
use handle::Handle;
19+
use location::LocationType;
20+
use object::{Object, ObjectType, AllowTypes, ObjectDetail, ObjectID};
2121
use plist::PropertyList;
2222
use space::{Dataspace, Dimension, Ix};
2323
use util::to_cstring;
@@ -34,44 +34,31 @@ pub enum Chunk {
3434
Manual(Vec<Ix>)
3535
}
3636

37-
/// Represents the HDF5 dataset object.
38-
pub struct Dataset {
39-
handle: Handle,
37+
pub struct DatasetID {
4038
dcpl: PropertyList,
4139
filters: Filters,
4240
}
4341

44-
#[doc(hidden)]
45-
impl ID for Dataset {
46-
fn id(&self) -> hid_t {
47-
self.handle.id()
42+
impl ObjectType for DatasetID {
43+
fn allow_types() -> AllowTypes {
44+
AllowTypes::Just(H5I_DATASET)
4845
}
49-
}
5046

51-
#[doc(hidden)]
52-
impl FromID for Dataset {
53-
fn from_id(id: hid_t) -> Result<Dataset> {
54-
h5lock!({
55-
match get_id_type(id) {
56-
H5I_DATASET => {
57-
let handle = Handle::new(id)?;
58-
let dcpl = PropertyList::from_id(h5try!(H5Dget_create_plist(id)))?;
59-
let filters = Filters::from_dcpl(&dcpl)?;
60-
Ok(Dataset {
61-
handle: handle,
62-
dcpl: dcpl,
63-
filters: filters,
64-
})
65-
},
66-
_ => Err(From::from(format!("Invalid property list id: {}", id))),
67-
}
68-
})
47+
fn from_id(id: hid_t) -> Result<DatasetID> {
48+
let dcpl = PropertyList::from_id(h5try!(H5Dget_create_plist(id)))?;
49+
let filters = Filters::from_dcpl(&dcpl)?;
50+
Ok(DatasetID {dcpl: dcpl, filters: filters })
51+
}
52+
53+
fn type_name() -> &'static str {
54+
"file"
6955
}
7056
}
7157

72-
impl Object for Dataset {}
58+
impl LocationType for DatasetID {}
7359

74-
impl Location for Dataset {}
60+
/// Represents the HDF5 dataset object.
61+
pub type Dataset = Object<DatasetID>;
7562

7663
impl Dataset {
7764
/// Returns the shape of the dataset.
@@ -103,7 +90,7 @@ impl Dataset {
10390

10491
/// Returns whether this dataset has a chunked layout.
10592
pub fn is_chunked(&self) -> bool {
106-
h5lock!(H5Pget_layout(self.dcpl.id()) == H5D_layout_t::H5D_CHUNKED)
93+
h5lock!(H5Pget_layout(self.detail().dcpl.id()) == H5D_layout_t::H5D_CHUNKED)
10794
}
10895

10996
/// Returns whether this dataset's type is equivalent to the given type.
@@ -125,7 +112,7 @@ impl Dataset {
125112
let ndim = self.ndim();
126113
let mut dims: Vec<hsize_t> = Vec::with_capacity(ndim);
127114
dims.set_len(ndim);
128-
H5Pget_chunk(self.dcpl.id(), ndim as c_int, dims.as_mut_ptr());
115+
H5Pget_chunk(self.detail().dcpl.id(), ndim as c_int, dims.as_mut_ptr());
129116
dims.iter().map(|&x| x as Ix).collect()
130117
})
131118
} else {
@@ -136,14 +123,14 @@ impl Dataset {
136123

137124
/// Returns the filters used to create the dataset.
138125
pub fn filters(&self) -> Filters {
139-
self.filters.clone()
126+
self.detail().filters.clone()
140127
}
141128

142129
/// Returns `true` if object modification time is tracked by the dataset.
143130
pub fn tracks_times(&self) -> bool {
144131
unsafe {
145132
let track_times: *mut hbool_t = &mut 0;
146-
h5lock!(H5Pget_obj_track_times(self.dcpl.id(), track_times));
133+
h5lock!(H5Pget_obj_track_times(self.detail().dcpl.id(), track_times));
147134
*track_times == 1
148135
}
149136
}
@@ -167,14 +154,14 @@ impl Dataset {
167154
pub fn fill_value<T: ToDatatype>(&self) -> Result<Option<T>> {
168155
h5lock!({
169156
let defined: *mut H5D_fill_value_t = &mut H5D_fill_value_t::H5D_FILL_VALUE_UNDEFINED;
170-
h5try!(H5Pfill_value_defined(self.dcpl.id(), defined));
157+
h5try!(H5Pfill_value_defined(self.detail().dcpl.id(), defined));
171158
match *defined {
172159
H5D_fill_value_t::H5D_FILL_VALUE_ERROR => fail!("Invalid fill value"),
173160
H5D_fill_value_t::H5D_FILL_VALUE_UNDEFINED => Ok(None),
174161
_ => {
175162
let datatype = T::to_datatype()?;
176163
let buf: *mut c_void = libc::malloc(datatype.size() as size_t);
177-
h5try!(H5Pget_fill_value(self.dcpl.id(), datatype.id(), buf));
164+
h5try!(H5Pget_fill_value(self.detail().dcpl.id(), datatype.id(), buf));
178165
let result = Ok(Some(T::from_raw_ptr(buf)));
179166
libc::free(buf);
180167
result
@@ -205,7 +192,7 @@ pub struct DatasetBuilder<T> {
205192

206193
impl<T: ToDatatype> DatasetBuilder<T> {
207194
/// Create a new dataset builder and bind it to the parent container.
208-
pub fn new<C: Container>(parent: &C) -> DatasetBuilder<T> {
195+
pub fn new<C: ContainerType>(parent: &Object<C>) -> DatasetBuilder<T> {
209196
h5lock!({
210197
// Store the reference to the parent handle and try to increase its reference count.
211198
let handle = Handle::new(parent.id());
@@ -433,13 +420,10 @@ pub mod tests {
433420
use ffi::h5d::H5Dwrite;
434421
use ffi::h5s::H5S_ALL;
435422
use ffi::h5p::H5P_DEFAULT;
436-
use container::Container;
437423
use datatype::ToDatatype;
438424
use file::File;
439425
use filters::{Filters, gzip_available, szip_available};
440-
use handle::ID;
441-
use location::Location;
442-
use object::Object;
426+
use object::ObjectID;
443427
use test::{with_tmp_file, with_tmp_path};
444428
use libc::c_void;
445429
use std::io::Read;

0 commit comments

Comments
 (0)