Commit e542163c authored by Stefan Behnel's avatar Stefan Behnel

support conversion between Python byte strings and unsigned char*

parent 0474c27a
...@@ -767,6 +767,9 @@ class StringNode(ConstNode): ...@@ -767,6 +767,9 @@ class StringNode(ConstNode):
if dst_type == PyrexTypes.c_char_ptr_type: if dst_type == PyrexTypes.c_char_ptr_type:
self.type = PyrexTypes.c_char_ptr_type self.type = PyrexTypes.c_char_ptr_type
return self return self
elif dst_type == PyrexTypes.c_uchar_ptr_type:
self.type = PyrexTypes.c_char_ptr_type
return CastNode(self, PyrexTypes.c_uchar_ptr_type)
if dst_type.is_int: if dst_type.is_int:
if not self.type.is_pyobject and len(self.value) == 1: if not self.type.is_pyobject and len(self.value) == 1:
......
...@@ -1577,6 +1577,18 @@ class CCharPtrType(CStringType, CPtrType): ...@@ -1577,6 +1577,18 @@ class CCharPtrType(CStringType, CPtrType):
CPtrType.__init__(self, c_char_type) CPtrType.__init__(self, c_char_type)
class CUCharPtrType(CStringType, CPtrType):
# C 'unsigned char *' type.
pymemberdef_typecode = "T_STRING"
to_py_function = "__Pyx_PyBytes_FromUString"
from_py_function = "__Pyx_PyBytes_AsUString"
def __init__(self):
CPtrType.__init__(self, c_uchar_type)
class UnspecifiedType(PyrexType): class UnspecifiedType(PyrexType):
# Used as a placeholder until the type can be determined. # Used as a placeholder until the type can be determined.
...@@ -1664,6 +1676,7 @@ c_double_complex_type = CComplexType(c_double_type) ...@@ -1664,6 +1676,7 @@ c_double_complex_type = CComplexType(c_double_type)
c_null_ptr_type = CNullPtrType(c_void_type) c_null_ptr_type = CNullPtrType(c_void_type)
c_char_array_type = CCharArrayType(None) c_char_array_type = CCharArrayType(None)
c_char_ptr_type = CCharPtrType() c_char_ptr_type = CCharPtrType()
c_uchar_ptr_type = CUCharPtrType()
c_utf8_char_array_type = CUTF8CharArrayType(None) c_utf8_char_array_type = CUTF8CharArrayType(None)
c_char_ptr_ptr_type = CPtrType(c_char_ptr_type) c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
c_int_ptr_type = CPtrType(c_int_type) c_int_ptr_type = CPtrType(c_int_type)
...@@ -1808,6 +1821,8 @@ def c_ptr_type(base_type): ...@@ -1808,6 +1821,8 @@ def c_ptr_type(base_type):
# Construct a C pointer type. # Construct a C pointer type.
if base_type is c_char_type: if base_type is c_char_type:
return c_char_ptr_type return c_char_ptr_type
elif base_type is c_uchar_type:
return c_uchar_ptr_type
elif base_type is error_type: elif base_type is error_type:
return error_type return error_type
else: else:
...@@ -1857,6 +1872,9 @@ type_conversion_predeclarations = """ ...@@ -1857,6 +1872,9 @@ type_conversion_predeclarations = """
#define __Pyx_PyBytes_AsString PyBytes_AsString #define __Pyx_PyBytes_AsString PyBytes_AsString
#endif #endif
#define __Pyx_PyBytes_FromUString(s) __Pyx_PyBytes_FromString((char*)s)
#define __Pyx_PyBytes_AsUString(s) ((unsigned char*) __Pyx_PyBytes_AsString(s))
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False)) #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
static INLINE int __Pyx_PyObject_IsTrue(PyObject*); static INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
......
__doc__ = u"""
>>> py_string1.decode('ASCII') == 'test toast taste'
True
>>> py_string1 == py_string2 == py_string3
True
"""
cdef unsigned char* some_c_unstring = 'test toast taste'
py_string1 = some_c_unstring
cdef unsigned char* c_unstring_from_py = py_string1
py_string2 = c_unstring_from_py
cdef char* c_string_from_py = py_string2
py_string3 = c_string_from_py
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