forked from aldanor/hdf5-rust
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from WiresmithTech/feature/refs2
Object Reference Types
- Loading branch information
Showing
15 changed files
with
563 additions
and
2 deletions.
There are no files selected for viewing
Submodule hdf5
updated
4731 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//! Types for references. | ||
use std::mem; | ||
|
||
#[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
pub enum Reference { | ||
Object, | ||
Region, | ||
#[cfg(feature = "1.12.0")] | ||
Std, | ||
} | ||
|
||
impl Reference { | ||
pub fn size(self) -> usize { | ||
match self { | ||
Self::Object => mem::size_of::<hdf5_sys::h5r::hobj_ref_t>(), | ||
Self::Region => mem::size_of::<hdf5_sys::h5r::hdset_reg_ref_t>(), | ||
#[cfg(feature = "1.12.0")] | ||
Self::Std => mem::size_of::<hdf5_sys::h5r::H5R_ref_t>(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use crate::internal_prelude::*; | ||
use crate::Location; | ||
|
||
mod legacy; | ||
|
||
#[cfg(feature = "1.12.1")] | ||
mod standard; | ||
|
||
use hdf5_sys::h5o::H5O_type_t; | ||
use hdf5_sys::h5r::H5R_type_t; | ||
|
||
pub use legacy::ObjectReference1; | ||
#[cfg(feature = "1.12.1")] | ||
pub use standard::ObjectReference2; | ||
|
||
mod private { | ||
pub trait ObjectReferencePrivate {} | ||
} | ||
|
||
/// The trait for all object references. This provides a common interface | ||
/// over the legacy and standard reference types. | ||
/// | ||
/// This trait is sealed and cannot be implemented for types outside `hdf5::hl`. | ||
pub trait ObjectReference: Sized + H5Type + private::ObjectReferencePrivate { | ||
const REF_TYPE: H5R_type_t; | ||
fn ptr(&self) -> *const c_void; | ||
|
||
/// Get the type of the object that the reference points in the same space as the provided location. | ||
fn get_object_type(&self, location: &Location) -> Result<H5O_type_t>; | ||
|
||
/// Create a new reference in the same structure as the location provided. | ||
fn create(location: &Location, name: &str) -> Result<Self>; | ||
|
||
/// Dereference the object reference in the space provided. | ||
fn dereference(&self, location: &Location) -> Result<ReferencedObject>; | ||
} | ||
/// The result of dereferencing an [object reference](ObjectReference). | ||
/// | ||
/// Each variant represents a different type of object that can be referenced by a [ObjectReference]. | ||
#[derive(Clone, Debug)] | ||
pub enum ReferencedObject { | ||
Group(Group), | ||
Dataset(Dataset), | ||
Datatype(Datatype), | ||
} | ||
|
||
impl ReferencedObject { | ||
pub fn from_type_and_id(object_type: H5O_type_t, object_id: hid_t) -> Result<Self> { | ||
use hdf5_sys::h5o::H5O_type_t::*; | ||
let referenced_object = match object_type { | ||
H5O_TYPE_GROUP => ReferencedObject::Group(Group::from_id(object_id)?), | ||
H5O_TYPE_DATASET => ReferencedObject::Dataset(Dataset::from_id(object_id)?), | ||
H5O_TYPE_NAMED_DATATYPE => ReferencedObject::Datatype(Datatype::from_id(object_id)?), | ||
#[cfg(feature = "1.12.0")] | ||
H5O_TYPE_MAP => fail!("Can not create object from a map"), | ||
H5O_TYPE_UNKNOWN => fail!("Unknown datatype"), | ||
H5O_TYPE_NTYPES => fail!("hdf5 should not produce this type"), | ||
}; | ||
Ok(referenced_object) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
//! The pre v1.12.0 reference types. | ||
use crate::internal_prelude::*; | ||
|
||
use hdf5_sys::{ | ||
h5o::H5O_type_t, | ||
h5p::H5P_DEFAULT, | ||
h5r::{hobj_ref_t, H5Rcreate, H5Rdereference, H5Rget_obj_type2}, | ||
}; | ||
use hdf5_types::H5Type; | ||
|
||
#[cfg(not(feature = "1.12.0"))] | ||
use hdf5_sys::h5r::H5R_OBJECT as H5R_OBJECT1; | ||
#[cfg(feature = "1.12.0")] | ||
use hdf5_sys::h5r::H5R_OBJECT1; | ||
|
||
use super::{private::ObjectReferencePrivate, ObjectReference}; | ||
use crate::Location; | ||
|
||
#[repr(transparent)] | ||
#[derive(Debug, Copy, Clone)] | ||
pub struct ObjectReference1 { | ||
inner: hobj_ref_t, | ||
} | ||
|
||
unsafe impl H5Type for ObjectReference1 { | ||
fn type_descriptor() -> hdf5_types::TypeDescriptor { | ||
hdf5_types::TypeDescriptor::Reference(hdf5_types::Reference::Object) | ||
} | ||
} | ||
|
||
impl ObjectReferencePrivate for ObjectReference1 {} | ||
|
||
impl ObjectReference for ObjectReference1 { | ||
const REF_TYPE: hdf5_sys::h5r::H5R_type_t = H5R_OBJECT1; | ||
|
||
fn ptr(&self) -> *const c_void { | ||
let pointer = std::ptr::addr_of!(self.inner); | ||
pointer.cast() | ||
} | ||
|
||
fn create(location: &Location, name: &str) -> Result<Self> { | ||
let mut ref_out: std::mem::MaybeUninit<hobj_ref_t> = std::mem::MaybeUninit::uninit(); | ||
let name = to_cstring(name)?; | ||
h5call!(H5Rcreate( | ||
ref_out.as_mut_ptr().cast(), | ||
location.id(), | ||
name.as_ptr(), | ||
Self::REF_TYPE, | ||
-1 | ||
))?; | ||
let reference = unsafe { ref_out.assume_init() }; | ||
Ok(Self { inner: reference }) | ||
} | ||
|
||
fn get_object_type(&self, location: &Location) -> Result<hdf5_sys::h5o::H5O_type_t> { | ||
let mut objtype = std::mem::MaybeUninit::<H5O_type_t>::uninit(); | ||
h5call!(H5Rget_obj_type2(location.id(), H5R_OBJECT1, self.ptr(), objtype.as_mut_ptr()))?; | ||
let objtype = unsafe { objtype.assume_init() }; | ||
Ok(objtype) | ||
} | ||
|
||
fn dereference(&self, location: &Location) -> Result<ReferencedObject> { | ||
let object_type = self.get_object_type(location)?; | ||
#[cfg(feature = "1.10.0")] | ||
let object_id = | ||
h5call!(H5Rdereference(location.id(), H5P_DEFAULT, H5R_OBJECT1, self.ptr()))?; | ||
#[cfg(not(feature = "1.10.0"))] | ||
let object_id = h5call!(H5Rdereference(location.id(), H5R_OBJECT1, self.ptr()))?; | ||
ReferencedObject::from_type_and_id(object_type, object_id) | ||
} | ||
} |
Oops, something went wrong.