///|
fn read_direct_chunks(
bytes : Bytes,
layout : DataLayout,
dataspace : Dataspace,
datatype : Datatype,
base_address : UInt64,
filters : Array[Filter],
output : FixedArray[Byte],
selection : Array[UInt64]?,
) -> Unit raise Hdf5Error {
guard layout.element_size == datatype.size else {
raise InvalidField("chunk element size does not match datatype")
}
let rank = dataspace.dimensions.length()
let chunk_size = chunk_byte_size(layout.chunk_dimensions, datatype.size)
let start = address_to_offset(layout.data_address, base_address)
match layout.chunk_index {
Single(stored_size, mask) => {
guard dataspace.maximum_dimensions == dataspace.dimensions &&
dataspace.dimensions ==
layout.chunk_dimensions.map(size => size.to_uint64()) else {
raise InvalidField("single chunk dimensions must match dataspace")
}
guard stored_size is Some(_) || filters.length() == 0 else {
raise InvalidField("filtered single chunk is missing its stored size")
}
let offsets = Array::make(rank, 0UL)
if !chunk_contains_selection(
offsets,
layout.chunk_dimensions,
dataspace.dimensions,
selection,
) {
return
}
let decoded = read_filtered_chunk(
bytes,
layout.data_address,
base_address,
stored_size.unwrap_or(chunk_size.to_uint64()),
filters,
mask,
datatype.size,
chunk_size,
)
copy_chunk(
decoded,
decoded.length(),
offsets,
layout.chunk_dimensions,
dataspace.dimensions,
datatype.size,
output,
selection,
)
}
Implicit => {
guard filters.length() == 0 else {
raise InvalidField("implicit chunks cannot have filters")
}
guard dataspace.maximum_dimensions.length() == rank else {
raise InvalidField("implicit chunks require maximum dimensions")
}
let current_grid : Array[Int64] = []
let maximum_grid : Array[Int64] = []
for dimension in 0.. 0 {
dimension = dimension - 1
coordinates[dimension] = remaining % current_grid[dimension]
remaining = remaining / current_grid[dimension]
offsets[dimension] = (coordinates[dimension] *
layout.chunk_dimensions[dimension].to_int64()).reinterpret_as_uint64()
}
let mut stored_index = 0L
for dimension in 0..
raise InvalidField("expected direct chunk index")
}
}
///|
fn read_source_direct_chunks(
source : &Hdf5Source,
layout : DataLayout,
dataspace : Dataspace,
datatype : Datatype,
base_address : UInt64,
filters : Array[Filter],
output : FixedArray[Byte],
selection : Array[UInt64]?,
) -> Unit raise Hdf5Error {
guard layout.element_size == datatype.size else {
raise InvalidField("chunk element size does not match datatype")
}
let rank = dataspace.dimensions.length()
let chunk_size = chunk_byte_size(layout.chunk_dimensions, datatype.size)
let start = source_address_to_offset(layout.data_address, base_address)
match layout.chunk_index {
Single(stored_size, mask) => {
guard dataspace.maximum_dimensions == dataspace.dimensions &&
dataspace.dimensions ==
layout.chunk_dimensions.map(size => size.to_uint64()) else {
raise InvalidField("single chunk dimensions must match dataspace")
}
guard stored_size is Some(_) || filters.length() == 0 else {
raise InvalidField("filtered single chunk is missing its stored size")
}
let offsets = Array::make(rank, 0UL)
if !chunk_contains_selection(
offsets,
layout.chunk_dimensions,
dataspace.dimensions,
selection,
) {
return
}
let decoded = read_source_filtered_chunk(
source,
layout.data_address,
base_address,
stored_size.unwrap_or(chunk_size.to_uint64()),
filters,
mask,
datatype.size,
chunk_size,
)
copy_chunk(
decoded,
decoded.length(),
offsets,
layout.chunk_dimensions,
dataspace.dimensions,
datatype.size,
output,
selection,
)
}
Implicit => {
guard filters.length() == 0 else {
raise InvalidField("implicit chunks cannot have filters")
}
guard dataspace.maximum_dimensions.length() == rank else {
raise InvalidField("implicit chunks require maximum dimensions")
}
let current_grid : Array[Int64] = []
let maximum_grid : Array[Int64] = []
for dimension in 0.. 0 {
dimension = dimension - 1
coordinates[dimension] = remaining % current_grid[dimension]
remaining = remaining / current_grid[dimension]
offsets[dimension] = (coordinates[dimension] *
layout.chunk_dimensions[dimension].to_int64()).reinterpret_as_uint64()
}
let mut stored_index = 0L
for dimension in 0..
raise InvalidField("expected direct chunk index")
}
}