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:
Marcelo Matus 2004-01-25 09:45:18 +00:00
commit dc061e30f1
4 changed files with 298 additions and 87 deletions

View file

@ -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);
}
}
}