Better mapping of char[ANY] in python, including embedded
null chars, which are allowed in C++ and python, and proper
sizes:
you can use a shorter string to assign a char[6]:
x = "he\0l" -> x := {'h','e',0,'l',0, 0}
but you always get back in python the original size:
x := {'h','i','0','0',0, 0} -> "hi\0\0\0\0"
Better mapping of (char*)0, now you get a None in the python
side, and using None, you get a (char*)0, just like
all the other C++ pointers. Before (char*)0 was mapped
into python as "", or as seg. faults.
Better mapping of "", which is not None nor (char*)0.
Added more tests using primitive types with simple templates.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@5687 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
f2995151b1
commit
dc061e30f1
4 changed files with 298 additions and 87 deletions
|
|
@ -148,15 +148,33 @@ SPyObj_AsFloat(PyObject *obj) {
|
|||
return (float) value;
|
||||
}
|
||||
|
||||
SWIG_STATIC_INLINE void
|
||||
SPyObj_AsCharPtrAndSize(PyObject *obj, char** cptr, int* len) {
|
||||
if (obj != Py_None) {
|
||||
PyString_AsStringAndSize(obj, cptr, len);
|
||||
} else {
|
||||
*cptr = 0; *len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SWIG_STATIC_INLINE char
|
||||
SPyObj_AsChar(PyObject *obj) {
|
||||
char c = (PyString_Check(obj) && PyString_Size(obj) == 1) ?
|
||||
PyString_AsString(obj)[0]
|
||||
: (char) SPyObj_AsLongInRange(obj, CHAR_MIN, CHAR_MAX);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
PyErr_SetString(PyExc_TypeError, "a char is required");
|
||||
}
|
||||
char c;
|
||||
if (PyString_Check(obj)) {
|
||||
char* cptr; int len;
|
||||
SPyObj_AsCharPtrAndSize(obj, &cptr, &len);
|
||||
if (len == 1) {
|
||||
c = cptr[0];
|
||||
} else {
|
||||
PyErr_SetString(PyExc_OverflowError, "a char is required");
|
||||
}
|
||||
} else {
|
||||
c = (char) SPyObj_AsLongInRange(obj, CHAR_MIN, CHAR_MAX);
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
PyErr_SetString(PyExc_TypeError, "a char is required");
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
@ -165,41 +183,57 @@ SPyObj_FromChar(char c) {
|
|||
return PyString_FromStringAndSize(&c,1);
|
||||
}
|
||||
|
||||
SWIG_STATIC_INLINE PyObject *
|
||||
SPyObj_FromCharPtr(const char* cptr) {
|
||||
return cptr ? PyString_FromString(cptr) : Py_BuildValue((char*)"");
|
||||
SWIG_STATIC_INLINE char*
|
||||
SPyObj_AsCharPtr(PyObject *obj) {
|
||||
return (obj != Py_None) ? PyString_AsString(obj) : (char*) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
these two routines allows char[ANY] with '0' chars inside, ie:
|
||||
|
||||
const char def_namet[5] = {'h','o',0, 'l','a'};
|
||||
|
||||
is not truncated to "ho".
|
||||
*/
|
||||
SWIG_STATIC_INLINE PyObject *
|
||||
SPyObj_FromCharPtr(const char* cptr) {
|
||||
if (cptr) {
|
||||
return PyString_FromString(cptr);
|
||||
} else {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
}
|
||||
|
||||
SWIG_STATIC_INLINE char*
|
||||
SPyObj_AsNewCharPtr(PyObject *obj) {
|
||||
char *res = 0;
|
||||
char* cptr; int len;
|
||||
SPyObj_AsCharPtrAndSize(obj, &cptr, &len);
|
||||
if (!PyErr_Occurred() && cptr) {
|
||||
size_t size = (len && !(cptr[len - 1])) ? len : len + 1;
|
||||
#ifdef __cplusplus
|
||||
res = new char[size];
|
||||
#else
|
||||
res = malloc(size);
|
||||
#endif
|
||||
if (len) memcpy(res, cptr, len);
|
||||
res[size-1] = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
SWIG_STATIC_INLINE PyObject *
|
||||
SPyObj_FromCharArray(const char* carray, int len) {
|
||||
SPyObj_FromCharArray(const char* carray, int size) {
|
||||
/* checking the effective size backward */
|
||||
for (; len && (carray[len - 1] == 0); --len);
|
||||
|
||||
return PyString_FromStringAndSize(carray, len);
|
||||
//for (; size && (carray[size - 1] == 0); --size);
|
||||
return PyString_FromStringAndSize(carray, size);
|
||||
}
|
||||
|
||||
SWIG_STATIC_INLINE void
|
||||
SPyObj_AsCharArray(PyObject *obj, char* carray, int size) {
|
||||
int len = size;
|
||||
char* buf;
|
||||
PyString_AsStringAndSize(obj, &buf, &len);
|
||||
char* cptr; int len;
|
||||
SPyObj_AsCharPtrAndSize(obj, &cptr, &len);
|
||||
if (!PyErr_Occurred()) {
|
||||
if (len > size) {
|
||||
PyErr_SetObject(PyExc_TypeError,
|
||||
PyString_FromFormat("a string of maximum size %d is required", size));
|
||||
} else {
|
||||
memcpy(carray, buf, len);
|
||||
/* pad the string with zero chars if needed */
|
||||
if (len < size)
|
||||
memset(carray + len, 0, size - len);
|
||||
if (len) memcpy(carray, cptr, len);
|
||||
if (len < size) memset(carray + len, 0, size - len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue