forked from h5py/h5py
/
h5o.pyx
366 lines (261 loc) · 10.1 KB
/
h5o.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# This file is part of h5py, a Python interface to the HDF5 library.
#
# http://www.h5py.org
#
# Copyright 2008-2013 Andrew Collette and contributors
#
# License: Standard 3-clause BSD; see "license.txt" for full license terms
# and contributor agreement.
"""
Module for HDF5 "H5O" functions.
"""
include 'config.pxi'
# Pyrex compile-time imports
from _objects cimport ObjectID, pdefault
from h5g cimport GroupID
from h5i cimport wrap_identifier
from h5p cimport PropID
from utils cimport emalloc, efree
from ._objects import phil, with_phil
# === Public constants ========================================================
TYPE_GROUP = H5O_TYPE_GROUP
TYPE_DATASET = H5O_TYPE_DATASET
TYPE_NAMED_DATATYPE = H5O_TYPE_NAMED_DATATYPE
COPY_SHALLOW_HIERARCHY_FLAG = H5O_COPY_SHALLOW_HIERARCHY_FLAG
COPY_EXPAND_SOFT_LINK_FLAG = H5O_COPY_EXPAND_SOFT_LINK_FLAG
COPY_EXPAND_EXT_LINK_FLAG = H5O_COPY_EXPAND_EXT_LINK_FLAG
COPY_EXPAND_REFERENCE_FLAG = H5O_COPY_EXPAND_REFERENCE_FLAG
COPY_WITHOUT_ATTR_FLAG = H5O_COPY_WITHOUT_ATTR_FLAG
COPY_PRESERVE_NULL_FLAG = H5O_COPY_PRESERVE_NULL_FLAG
# === Giant H5O_info_t structure ==============================================
cdef class _ObjInfoBase:
cdef H5O_info_t *istr
cdef class _OHdrMesg(_ObjInfoBase):
property present:
def __get__(self):
return self.istr[0].hdr.mesg.present
property shared:
def __get__(self):
return self.istr[0].hdr.mesg.shared
def _hash(self):
return hash((self.present, self.shared))
cdef class _OHdrSpace(_ObjInfoBase):
property total:
def __get__(self):
return self.istr[0].hdr.space.total
property meta:
def __get__(self):
return self.istr[0].hdr.space.meta
property mesg:
def __get__(self):
return self.istr[0].hdr.space.mesg
property free:
def __get__(self):
return self.istr[0].hdr.space.free
def _hash(self):
return hash((self.total, self.meta, self.mesg, self.free))
cdef class _OHdr(_ObjInfoBase):
cdef public _OHdrSpace space
cdef public _OHdrMesg mesg
property version:
def __get__(self):
return self.istr[0].hdr.version
property nmesgs:
def __get__(self):
return self.istr[0].hdr.nmesgs
def __init__(self):
self.space = _OHdrSpace()
self.mesg = _OHdrMesg()
def _hash(self):
return hash((self.version, self.nmesgs, self.space, self.mesg))
cdef class _ObjInfo(_ObjInfoBase):
property fileno:
def __get__(self):
return self.istr[0].fileno
property addr:
def __get__(self):
return self.istr[0].addr
property type:
def __get__(self):
return <int>self.istr[0].type
property rc:
def __get__(self):
return self.istr[0].rc
def _hash(self):
return hash((self.fileno, self.addr, self.type, self.rc))
cdef class ObjInfo(_ObjInfo):
"""
Represents the H5O_info_t structure
"""
cdef H5O_info_t infostruct
cdef public _OHdr hdr
def __init__(self):
self.hdr = _OHdr()
self.istr = &self.infostruct
self.hdr.istr = &self.infostruct
self.hdr.space.istr = &self.infostruct
self.hdr.mesg.istr = &self.infostruct
def __copy__(self):
cdef ObjInfo newcopy
newcopy = ObjInfo()
newcopy.infostruct = self.infostruct
return newcopy
@with_phil
def get_info(ObjectID loc not None, char* name=NULL, int index=-1, *,
char* obj_name='.', int index_type=H5_INDEX_NAME, int order=H5_ITER_NATIVE,
PropID lapl=None):
"""(ObjectID loc, STRING name=, INT index=, **kwds) => ObjInfo
Get information describing an object in an HDF5 file. Provide the object
itself, or the containing group and exactly one of "name" or "index".
STRING obj_name (".")
When "index" is specified, look in this subgroup instead.
Otherwise ignored.
PropID lapl (None)
Link access property list
INT index_type (h5.INDEX_NAME)
INT order (h5.ITER_NATIVE)
"""
cdef ObjInfo info
info = ObjInfo()
if name != NULL and index >= 0:
raise TypeError("At most one of name or index may be specified")
elif name != NULL and index < 0:
H5Oget_info_by_name(loc.id, name, &info.infostruct, pdefault(lapl))
elif name == NULL and index >= 0:
H5Oget_info_by_idx(loc.id, obj_name, <H5_index_t>index_type,
<H5_iter_order_t>order, index, &info.infostruct, pdefault(lapl))
else:
H5Oget_info(loc.id, &info.infostruct)
return info
IF HDF5_VERSION >= (1, 8, 5):
@with_phil
def exists_by_name(ObjectID loc not None, char *name, PropID lapl=None):
""" (ObjectID loc, STRING name, PropID lapl=None) => BOOL exists
Determines whether a link resolves to an actual object.
"""
return <bint>H5Oexists_by_name(loc.id, name, pdefault(lapl))
# === General object operations ===============================================
@with_phil
def open(ObjectID loc not None, char* name, PropID lapl=None):
"""(ObjectID loc, STRING name, PropID lapl=None) => ObjectID
Open a group, dataset, or named datatype attached to an existing group.
"""
return wrap_identifier(H5Oopen(loc.id, name, pdefault(lapl)))
@with_phil
def link(ObjectID obj not None, GroupID loc not None, char* name,
PropID lcpl=None, PropID lapl=None):
"""(ObjectID obj, GroupID loc, STRING name, PropID lcpl=None,
PropID lapl=None)
Create a new hard link to an object. Useful for objects created with
h5g.create_anon() or h5d.create_anon().
"""
H5Olink(obj.id, loc.id, name, pdefault(lcpl), pdefault(lapl))
@with_phil
def copy(ObjectID src_loc not None, char* src_name, GroupID dst_loc not None,
char* dst_name, PropID copypl=None, PropID lcpl=None):
"""(ObjectID src_loc, STRING src_name, GroupID dst_loc, STRING dst_name,
PropID copypl=None, PropID lcpl=None)
Copy a group, dataset or named datatype from one location to another. The
source and destination need not be in the same file.
The default behavior is a recursive copy of the object and all objects
below it. This behavior is modified via the "copypl" property list.
"""
H5Ocopy(src_loc.id, src_name, dst_loc.id, dst_name, pdefault(copypl),
pdefault(lcpl))
@with_phil
def set_comment(ObjectID loc not None, char* comment, *, char* obj_name=".",
PropID lapl=None):
"""(ObjectID loc, STRING comment, **kwds)
Set the comment for any-file resident object. Keywords:
STRING obj_name (".")
Set comment on this group member instead
PropID lapl (None)
Link access property list
"""
H5Oset_comment_by_name(loc.id, obj_name, comment, pdefault(lapl))
@with_phil
def get_comment(ObjectID loc not None, char* comment, *, char* obj_name=".",
PropID lapl=None):
"""(ObjectID loc, STRING comment, **kwds)
Get the comment for any-file resident object. Keywords:
STRING obj_name (".")
Set comment on this group member instead
PropID lapl (None)
Link access property list
"""
cdef ssize_t size
cdef char* buf
size = H5Oget_comment_by_name(loc.id, obj_name, NULL, 0, pdefault(lapl))
buf = <char*>emalloc(size+1)
try:
H5Oget_comment_by_name(loc.id, obj_name, buf, size+1, pdefault(lapl))
pstring = buf
finally:
efree(buf)
return pstring
# === Visit routines ==========================================================
cdef class _ObjectVisitor:
cdef object func
cdef object retval
cdef ObjInfo objinfo
def __init__(self, func):
self.func = func
self.retval = None
self.objinfo = ObjInfo()
cdef herr_t cb_obj_iterate(hid_t obj, const char* name, const H5O_info_t *info, void* data) except 2:
cdef _ObjectVisitor visit
# HDF5 doesn't respect callback return for ".", so skip it
if strcmp(name, ".") == 0:
return 0
visit = <_ObjectVisitor>data
visit.objinfo.infostruct = info[0]
visit.retval = visit.func(name, visit.objinfo)
if visit.retval is not None:
return 1
return 0
cdef herr_t cb_obj_simple(hid_t obj, const char* name, const H5O_info_t *info, void* data) except 2:
cdef _ObjectVisitor visit
# Not all versions of HDF5 respect callback value for ".", so skip it
if strcmp(name, ".") == 0:
return 0
visit = <_ObjectVisitor>data
visit.retval = visit.func(name)
if visit.retval is not None:
return 1
return 0
@with_phil
def visit(ObjectID loc not None, object func, *,
int idx_type=H5_INDEX_NAME, int order=H5_ITER_NATIVE,
char* obj_name=".", PropID lapl=None, bint info=0):
"""(ObjectID loc, CALLABLE func, **kwds) => <Return value from func>
Iterate a function or callable object over all objects below the
specified one. Your callable should conform to the signature::
func(STRING name) => Result
or if the keyword argument "info" is True::
func(STRING name, ObjInfo info) => Result
Returning None continues iteration; returning anything else aborts
iteration and returns that value. Keywords:
BOOL info (False)
Callback is func(STRING, Objinfo)
STRING obj_name (".")
Visit a subgroup of "loc" instead
PropLAID lapl (None)
Control how "obj_name" is interpreted
INT idx_type (h5.INDEX_NAME)
What indexing strategy to use
INT order (h5.ITER_NATIVE)
Order in which iteration occurs
Compatibility note: No callback is executed for the starting path ("."),
as some versions of HDF5 don't correctly handle a return value for this
case. This differs from the behavior of the native H5Ovisit, which
provides a literal "." as the first value.
"""
cdef _ObjectVisitor visit = _ObjectVisitor(func)
cdef H5O_iterate_t cfunc
if info:
cfunc = cb_obj_iterate
else:
cfunc = cb_obj_simple
H5Ovisit_by_name(loc.id, obj_name, <H5_index_t>idx_type,
<H5_iter_order_t>order, cfunc, <void*>visit, pdefault(lapl))
return visit.retval