3
# A draft python binding for libspud
4
# You will need to compile _libspud.so
5
# by hand for now -- haven't hooked it up
15
pytype_map = {SPUD_REAL: float, SPUD_INTEGER: int, SPUD_NONE: None, SPUD_CHARACTER: str}
16
typepy_map = {float: SPUD_REAL, int: SPUD_INTEGER, None: SPUD_NONE, str: SPUD_CHARACTER}
17
ctype_map = {float: c_double, int: c_int, None: None, str: c_char_p}
24
SPUD_NEW_KEY_WARNING = -1
25
SPUD_ATTR_SET_FAILED_WARNING = -2
27
OPTION_PATH_LEN = 8192
29
class SpudKeyError(Exception):
30
def __init__(self, msg = "The specified option is not present in the dictionary."):
33
class SpudTypeError(Exception):
34
def __init__(self, msg = "The specified option has a different type from that of the option argument provided."):
37
class SpudRankError(Exception):
38
def __init__(self, msg = "The specified option has a different rank from that of the option argument provided."):
41
class SpudShapeError(Exception):
42
def __init__(self, msg = "The specified option has a different shape from that of the option argument provided."):
45
class SpudNewKeyWarning(Exception):
46
def __init__(self, msg = "The option being inserted is not already in the dictionary."):
49
class SpudAttrSetFailedWarning(Exception):
50
def __init__(self, msg = "The option being set as an attribute can not be set as an attribute."):
53
spud_exceptions = {SPUD_KEY_ERROR: SpudKeyError,
54
SPUD_TYPE_ERROR: SpudTypeError,
55
SPUD_RANK_ERROR: SpudRankError,
56
SPUD_SHAPE_ERROR: SpudShapeError,
57
SPUD_NEW_KEY_WARNING: SpudNewKeyWarning,
58
SPUD_ATTR_SET_FAILED_WARNING: SpudAttrSetFailedWarning}
60
libspud = cdll.LoadLibrary('@prefix@' + '/lib/libspud.so')
62
cclear_options = libspud.spud_clear_options
63
cclear_options.argtypes = []
64
cclear_options.restype = None
69
cload_options = libspud.spud_load_options
70
cload_options.argtypes = [c_char_p, c_int]
71
cload_options.restype = c_int
74
out = cload_options(s, c_int(len(s)))
75
if out != SPUD_NO_ERROR:
76
raise spud_exceptions[out]
78
cwrite_options = libspud.spud_write_options
79
cwrite_options.argtypes = [c_char_p, c_int]
80
cwrite_options.restype = c_int
82
def write_options(filename):
83
out = cwrite_options(filename, c_int(len(filename)))
84
if out != SPUD_NO_ERROR:
85
raise spud_exceptions[out]
87
cget_child_name = libspud.spud_get_child_name
88
cget_child_name.argtypes = [c_char_p, c_int, c_int, c_char_p, c_int]
89
cget_child_name.restype = c_int
91
def get_child_name(s, idx):
92
val = create_string_buffer(OPTION_PATH_LEN)
93
out = cget_child_name(s, c_int(len(s)), c_int(idx), val, c_int(len(val)))
95
if out != SPUD_NO_ERROR:
96
raise spud_exceptions[out]
98
return val.value.strip()
100
cget_number_of_children = libspud.spud_get_number_of_children
101
cget_number_of_children.argtypes = [c_char_p, c_int, POINTER(c_int)]
102
cget_number_of_children.restype = c_int
104
def get_number_of_children(s):
106
out = cget_number_of_children(s, c_int(len(s)), byref(val))
108
if out != SPUD_NO_ERROR:
109
raise spud_exceptions[out]
113
coption_count = libspud.spud_option_count
114
coption_count.argtypes = [c_char_p, c_int]
115
coption_count.restype = c_int
118
return coption_count(s, c_int(len(s)))
120
chave_option = libspud.spud_have_option
121
chave_option.argtypes = [c_char_p, c_int]
122
chave_option.restype = c_int
125
out = chave_option(s, c_int(len(s)))
132
cget_option_type = libspud.spud_get_option_type
133
cget_option_type.argtypes = [c_char_p, c_int, POINTER(c_int)]
134
cget_option_type.restype = c_int
136
def get_option_type(s):
138
out = cget_option_type(s, c_int(len(s)), byref(val))
140
if out != SPUD_NO_ERROR:
141
raise spud_exceptions[out]
143
return pytype_map[val.value]
145
cget_option_rank = libspud.spud_get_option_rank
146
cget_option_rank.argtypes = [c_char_p, c_int, POINTER(c_int)]
147
cget_option_rank.restype = c_int
149
def get_option_rank(s):
151
out = cget_option_rank(s, c_int(len(s)), byref(rank))
152
if out != SPUD_NO_ERROR:
153
raise spud_exceptions[out]
156
cget_option_shape = libspud.spud_get_option_shape
157
cget_option_shape.argtypes = [c_char_p, c_int, POINTER(c_int)]
158
cget_option_shape.restype = int
160
def get_option_shape(s):
161
shape_type = c_int * 2
163
out = cget_option_shape(s, c_int(len(s)), shape)
165
if out != SPUD_NO_ERROR:
166
raise spud_exceptions[out]
170
cget_option = libspud.spud_get_option
171
cget_option.argtypes = [c_char_p, c_int, c_void_p]
172
cget_option.restype = c_int
175
type = get_option_type(s)
178
strlen = get_option_shape(s)[0]
179
val = create_string_buffer(strlen+1)
181
raise spud_exceptions[SPUD_TYPE_ERROR]("No value exists at the given path")
183
val_type = ctype_map[type]
184
rank = get_option_rank(s)
185
shape = get_option_shape(s)
186
# reverse the numbering so we get a rowxcolumn list of lists
187
for i in range(rank-1, -1, -1): val_type = val_type*shape[i]
190
out = cget_option(s, c_int(len(s)), byref(val))
191
if out != SPUD_NO_ERROR:
192
raise spud_exceptions[out]
195
val_out = [[val[i][j] for j in range(shape[1])] for i in range(shape[0])]
197
val_out = [val[i] for i in range(shape[0])]
202
cadd_option = libspud.spud_add_option
203
cadd_option.argtypes = [c_char_p, c_int]
204
cadd_option.restype = c_int
207
out = cadd_option(s, c_int(len(s)))
209
if out != SPUD_NO_ERROR:
210
raise spud_exceptions[out]
214
cset_option = libspud.spud_set_option
215
cset_option.argtypes = [c_char_p, c_int, c_void_p, c_int, c_int, POINTER(c_int)]
216
cset_option.restype = c_int
218
def set_option(s, val):
220
shape_type = c_int * 2
221
shape = shape_type(1, -1)
223
if py_type not in typepy_map:
227
if type(subval) == list:
228
shape[i] = len(subval)
233
py_type = type(subval)
235
# could put numpy array handling in here
236
# (they'd be easier but didn't want to
237
# add a numpy dependency)
239
raise spud_exceptions[SPUD_TYPE_ERROR]("Unknown value type. Only know about floats, ints, strings and lists thereof.")
240
spud_code = typepy_map[py_type]
241
c_type = ctype_map[py_type]
242
# reverse the order of the shape entries as that way we end up with a rows x columns c_type
243
for i in range(rank-1, -1, -1): c_type = c_type*shape[i]
246
for i in range(shape[0]):
247
for j in range(shape[1]):
248
c_val[i][j] = val[i][j]
251
for i in range(shape[0]):
257
shape = shape_type(len(val), -1)
259
out = cset_option(s, c_int(len(s)), (c_val), c_int(spud_code), c_int(rank), shape)
261
out = cset_option(s, c_int(len(s)), byref(c_val), c_int(spud_code), c_int(rank), shape)
263
if out != SPUD_NO_ERROR:
264
raise spud_exceptions[out]
266
cset_option_attribute = libspud.spud_set_option_attribute
267
cset_option_attribute.argtypes = [c_char_p, c_int, c_char_p, c_int]
268
cset_option_attribute.restype = c_int
270
def set_option_attribute(s, val):
271
out = cset_option_attribute(s, c_int(len(s)), val, c_int(len(val)))
273
if out != SPUD_NO_ERROR:
274
raise spud_exceptions[out]
278
cdelete_option = libspud.spud_delete_option
279
cdelete_option.argtypes = [c_char_p, c_int]
280
cdelete_option.restype = c_int
282
def delete_option(s):
283
out = cdelete_option(s, c_int(len(s)))
285
if out != SPUD_NO_ERROR:
286
raise spud_exceptions[out]
290
cmove_option = libspud.spud_move_option
291
cmove_option.argtypes = [c_char_p, c_int, c_char_p, c_int]
292
cmove_option.restype = c_int
294
def move_option(s1, s2):
295
out = cmove_option(s1, c_int(len(s1)), s2, c_int(len(s2)))
297
if out != SPUD_NO_ERROR:
298
raise spud_exceptions[out]
302
cprint_options = libspud.spud_print_options
303
cprint_options.restype = None
304
cprint_options.argtypes = []