Commit 5eeddd50 authored by Karl Wette's avatar Karl Wette
Browse files

lal/swig/SWIGLALAlpha.i: add specialised input typemaps for LALDict

parent 95087765
......@@ -522,6 +522,122 @@ typedef struct {
}
%swiglal_specialised_typemaps(tagLALUnit, "swiglal_specialised_tagLALUnit");
///
/// # Specialised typemaps for <tt>LALDict</tt>
///
///
/// Specialised input typemaps for <tt>LALDict</tt>. Accepts a SWIG-wrapped <tt>LALDict</tt>, or:
///
/// - For Python, a native dictionary with keys of the form <tt>"key[:type]"</tt>, where
/// <tt>"type"</tt> specifies the type of the <tt>LALDict</tt> entry:
// <tt>"[U]INT{2,4,8}"</tt> for integer values,
/// <tt>"REAL{4,8}"</tt> for real values, and
/// <tt>"COMPLEX{8,16}"</tt> for complex values.
/// If <tt>"type"</tt> is absent, the entry is assumed to be a string.
///
%fragment("swiglal_specialised_ptr_tagLALDict", "header",
fragment="SWIG_AsCharPtr",
fragment=SWIG_AsVal_frag(uint16_t),
fragment=SWIG_AsVal_frag(int16_t),
fragment=SWIG_AsVal_frag(uint32_t),
fragment=SWIG_AsVal_frag(int32_t),
fragment=SWIG_AsVal_frag(uint64_t),
fragment=SWIG_AsVal_frag(int64_t),
fragment=SWIG_AsVal_frag(float),
fragment=SWIG_AsVal_frag(double),
fragment=SWIG_AsVal_frag(COMPLEX8),
fragment=SWIG_AsVal_frag(COMPLEX16)
)
{
int swiglal_specialised_ptr_tagLALDict(SWIG_Object in, LALDict **out) {
int res = SWIG_ValueError;
char *keyname, *valuestr = 0;
int keyalloc, valuealloc = 0;
*out = XLALCreateDict();
if (*out == NULL) {
goto fail;
}
#ifdef SWIGPYTHON
if (!PyDict_Check(in)) {
return SWIG_ValueError;
}
PyObject *key, *value;
Py_ssize_t pos = 0;
while (PyDict_Next(in, &pos, &key, &value)) {
if (!SWIG_IsOK(SWIG_AsCharPtr(key, &keyname, &keyalloc))) {
break;
}
char *keytype = strrchr(keyname, ':');
if (keytype == NULL) {
keytype = keyname + strlen(keyname);
} else {
*keytype = 0;
++keytype;
}
do {
#define SWIGLAL_LALDICT_HANDLE_TYPE(LALTYPESTR, LALTYPE, CTYPE, FMT, ...) \
if (XLALStringCaseCompare(keytype, LALTYPESTR) == 0) { \
CTYPE v = 0; \
if (SWIG_IsOK(SWIG_AsVal(CTYPE)(value, &v))) { \
if (XLALDictInsert##LALTYPE##Value(*out, keyname, v) != XLAL_SUCCESS) { \
goto fail; \
} \
XLALPrintInfo("%s: dict=%p, key=%s, type=%s, value=" FMT "\n", __func__, in, keyname, keytype, __VA_ARGS__); \
break; \
} \
}
SWIGLAL_LALDICT_HANDLE_TYPE("UINT2", UINT2, uint16_t, "%" LAL_UINT2_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("INT2", INT2, int16_t, "%" LAL_INT2_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("UINT4", UINT4, uint32_t, "%" LAL_UINT4_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("INT4", INT4, int32_t, "%" LAL_INT4_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("UINT8", UINT8, uint64_t, "%" LAL_UINT8_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("INT8", INT8, int64_t, "%" LAL_INT8_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("REAL4", REAL4, float, "%" LAL_REAL4_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("REAL8", REAL8, double, "%" LAL_REAL8_FORMAT, v);
SWIGLAL_LALDICT_HANDLE_TYPE("COMPLEX8", COMPLEX8, COMPLEX8, "(%" LAL_REAL4_FORMAT ",%" LAL_REAL4_FORMAT ")", crealf(v), cimagf(v));
SWIGLAL_LALDICT_HANDLE_TYPE("COMPLEX16", COMPLEX16, COMPLEX16, "(%" LAL_REAL8_FORMAT ",%" LAL_REAL8_FORMAT ")", creal (v), cimag (v));
#undef SWIGLAL_LALDICT_GIVEN_TYPE
if (SWIG_IsOK(SWIG_AsCharPtr(value, &valuestr, &valuealloc))) {
if (XLALDictInsertStringValue(*out, keyname, valuestr) != XLAL_SUCCESS) {
goto fail;
}
XLALPrintInfo("%s: dict=%p, key=%s, type=string, value='%s'\n", __func__, in, keyname, valuestr);
if (valuealloc == SWIG_NEWOBJ) {
%delete_array(valuestr);
valuealloc = 0;
}
} else {
XLALPrintInfo("%s: dict=%p, key=%s, type=unknown\n", __func__, in, keyname);
goto fail;
}
} while(0);
if (keyalloc == SWIG_NEWOBJ) {
%delete_array(keyname);
keyalloc = 0;
}
}
res = SWIG_OK;
#endif
fail:
if (!SWIG_IsOK(res)) {
XLALDestroyDict(*out);
*out = NULL;
}
if (keyalloc == SWIG_NEWOBJ) {
%delete_array(keyname);
}
if (valuealloc == SWIG_NEWOBJ) {
%delete_array(valuestr);
}
return res;
}
void swiglal_specialised_ptr_tagLALDict_destroy(LALDict *tmp) {
XLALDestroyDict(tmp);
}
}
%swiglal_specialised_ptr_typemaps(tagLALDict, "swiglal_specialised_ptr_tagLALDict");
// Local Variables:
// mode: c
// End:
......@@ -29,6 +29,7 @@
#endif // SWIGLAL_HAVE_LIBGSL
#include <lal/LALDatatypes.h>
#include <lal/LALDict.h>
#ifdef __cplusplus
extern "C" {
......@@ -360,6 +361,9 @@ typedef struct tagswig_lal_test_gps {
} swig_lal_test_gps;
REAL8 swig_lal_test_noptrgps(const LIGOTimeGPS gps);
// Test Python dict to LALDict typemap
int swig_lal_test_pydict_to_laldict(LALDict *laldict);
#ifdef __cplusplus
}
#endif
......
......@@ -604,3 +604,66 @@ int swig_lal_test_typemaps_string_ptrptr(
REAL8 swig_lal_test_noptrgps(const LIGOTimeGPS gps) {
return XLALGPSGetREAL8(&gps);
}
// Test Python dict to LALDict typemap
int swig_lal_test_pydict_to_laldict(LALDict *laldict) {
XLAL_CHECK( laldict != NULL, XLAL_EFAULT );
{
const char *str = XLALDictLookupStringValue(laldict, "str");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( strcmp(str, "A string value") == 0, XLAL_EFUNC );
}
{
UINT2 val = XLALDictLookupUINT2Value(laldict, "2-byte-unsigned");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == 32767, XLAL_EFUNC );
}
{
UINT4 val = XLALDictLookupUINT4Value(laldict, "4-byte-unsigned");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == 123456, XLAL_EFUNC );
}
{
UINT8 val = XLALDictLookupUINT8Value(laldict, "8-byte-unsigned");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == 9223372036854775807, XLAL_EFUNC );
}
{
INT2 val = XLALDictLookupINT2Value(laldict, "2-byte-signed");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == -32768, XLAL_EFUNC );
}
{
INT4 val = XLALDictLookupINT4Value(laldict, "4-byte-signed");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == -123456, XLAL_EFUNC );
}
{
INT8 val = XLALDictLookupINT8Value(laldict, "8-byte-signed");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == 9223372036854775807, XLAL_EFUNC );
}
{
REAL4 val = XLALDictLookupREAL4Value(laldict, "single");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == 987e6, XLAL_EFUNC );
}
{
REAL8 val = XLALDictLookupREAL8Value(laldict, "double");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( val == -543e-21, XLAL_EFUNC );
}
{
COMPLEX8 val = XLALDictLookupCOMPLEX8Value(laldict, "single complex");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( crealf(val) == 987e6, XLAL_EFUNC );
XLAL_CHECK( cimagf(val) == -123e4, XLAL_EFUNC );
}
{
COMPLEX16 val = XLALDictLookupCOMPLEX16Value(laldict, "double complex");
XLAL_CHECK( xlalErrno == 0, XLAL_EFUNC );
XLAL_CHECK( creal(val) == -543e-21, XLAL_EFUNC );
XLAL_CHECK( cimag(val) == 345e43, XLAL_EFUNC );
}
return XLAL_SUCCESS;
}
......@@ -1253,5 +1253,36 @@ if lal.swig_version >= 0x030011:
assert (a.data.data == b.data.data).all()
print("PASSED pickling (Python specific)")
# test Python dict to LALDict typemap
print("checking Python dict to LALDict typemap (Python specific) ...")
pydict = {
"str": "A string value",
"2-byte-unsigned:UINT2": 32767,
"4-byte-unsigned:UINT4": 123456,
"8-byte-unsigned:UINT8": 9223372036854775807,
"2-byte-signed:INT2": -32768,
"4-byte-signed:INT4": -123456,
"8-byte-signed:INT8": 9223372036854775807,
"single:REAL4": 987e6,
"double:REAL8": -543e-21,
"single complex:COMPLEX8": complex(987e6, -123e4),
"double complex:COMPLEX16": complex(-543e-21, 345e43)
}
laldict = lal.CreateDict()
lal.DictInsertStringValue(laldict, "str", pydict["str"])
lal.DictInsertUINT2Value(laldict, "2-byte-unsigned", pydict["2-byte-unsigned:UINT2"])
lal.DictInsertUINT4Value(laldict, "4-byte-unsigned", pydict["4-byte-unsigned:UINT4"])
lal.DictInsertUINT8Value(laldict, "8-byte-unsigned", pydict["8-byte-unsigned:UINT8"])
lal.DictInsertINT2Value(laldict, "2-byte-signed", pydict["2-byte-signed:INT2"])
lal.DictInsertINT4Value(laldict, "4-byte-signed", pydict["4-byte-signed:INT4"])
lal.DictInsertINT8Value(laldict, "8-byte-signed", pydict["8-byte-signed:INT8"])
lal.DictInsertREAL4Value(laldict, "single", pydict["single:REAL4"])
lal.DictInsertREAL8Value(laldict, "double", pydict["double:REAL8"])
lal.DictInsertCOMPLEX8Value(laldict, "single complex", pydict["single complex:COMPLEX8"])
lal.DictInsertCOMPLEX16Value(laldict, "double complex", pydict["double complex:COMPLEX16"])
lal.swig_lal_test_pydict_to_laldict(laldict)
lal.swig_lal_test_pydict_to_laldict(pydict)
print("PASSED Python dict to LALDict typemap (Python specific)")
# passed all tests!
print("PASSED all tests")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment