diff options
Diffstat (limited to 'cython')
-rw-r--r-- | cython/Makefile.am | 44 | ||||
-rw-r--r-- | cython/plist.pxd | 3 | ||||
-rw-r--r-- | cython/plist.pyx | 117 | ||||
-rw-r--r-- | cython/plist_util.c | 31 | ||||
-rw-r--r-- | cython/plist_util.h | 4 |
5 files changed, 130 insertions, 69 deletions
diff --git a/cython/Makefile.am b/cython/Makefile.am index bce8121..bbc51c9 100644 --- a/cython/Makefile.am +++ b/cython/Makefile.am @@ -3,24 +3,48 @@ AM_CPPFLAGS = -I$(top_srcdir)/include AM_CFLAGS = $(GLOBAL_CFLAGS) AM_LDFLAGS = $(GLOBAL_LDFLAGS) -EXTRA_DIST = plist.pyx plist.pxd +EXTRA_DIST = \ + plist.pyx \ + plist.pxd if HAVE_CYTHON BUILT_SOURCES = plist.c -PXDINCLUDES = plist.pxd $(CYTHON_PLIST_INCLUDE_DIR)/plist.pxd -CLEANFILES = \ - *.pyc \ - *.pyo \ - plist.c +PXDINCLUDES = \ + plist.pxd \ + $(CYTHON_PLIST_INCLUDE_DIR)/plist.pxd + +CLEANFILES = \ + *.pyc \ + *.pyo \ + plist.c plistdir = $(pyexecdir) plist_LTLIBRARIES = plist.la -plist_la_SOURCES = plist_util.c plist_util.h plist.pyx -plist_la_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src $(PYTHON_CPPFLAGS) $(AM_CFLAGS) -Wno-shadow -Wno-redundant-decls -Wno-switch-default -Wno-strict-aliasing -Wno-implicit-function-declaration -fvisibility=default -plist_la_LDFLAGS = -module -avoid-version $(PYTHON_LIBS) $(AM_LDFLAGS) -plist_la_LIBADD = $(top_builddir)/src/libplist.la +plist_la_SOURCES = \ + plist_util.c \ + plist_util.h \ + plist.pyx + +plist_la_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ + $(PYTHON_CPPFLAGS) \ + $(AM_CFLAGS) \ + -Wno-shadow \ + -Wno-redundant-decls \ + -Wno-switch-default \ + -Wno-strict-aliasing \ + -Wno-implicit-function-declaration \ + -fvisibility=default + +plist_la_LDFLAGS = -module -avoid-version $(PYTHON_LIBS) $(AM_LDFLAGS) -shared -export-dynamic +plist_la_LIBADD = $(top_builddir)/src/libplist-2.0.la + +if WIN32 +plist_la_LDFLAGS += -no-undefined +endif plist.c: plist.pyx $(PXDINCLUDES) $(PXIINCLUDES) diff --git a/cython/plist.pxd b/cython/plist.pxd index b11d80d..5a41bf8 100644 --- a/cython/plist.pxd +++ b/cython/plist.pxd @@ -19,7 +19,8 @@ cdef class Bool(Node): cdef class Integer(Node): cpdef set_value(self, object value) - cpdef uint64_t get_value(self) + cpdef get_value(self) + cpdef bint is_negative(self) cdef class Uid(Node): cpdef set_value(self, object value) diff --git a/cython/plist.pyx b/cython/plist.pyx index bfecf85..29c1181 100644 --- a/cython/plist.pyx +++ b/cython/plist.pyx @@ -5,7 +5,7 @@ from libc.stdint cimport * cdef extern from *: ctypedef enum plist_type: PLIST_BOOLEAN, - PLIST_UINT, + PLIST_INT, PLIST_REAL, PLIST_STRING, PLIST_ARRAY, @@ -14,6 +14,7 @@ cdef extern from *: PLIST_DATA, PLIST_KEY, PLIST_UID, + PLIST_NULL, PLIST_NONE plist_t plist_new_bool(uint8_t val) @@ -24,13 +25,17 @@ cdef extern from *: void plist_get_uint_val(plist_t node, uint64_t *val) void plist_set_uint_val(plist_t node, uint64_t val) + plist_t plist_new_int(int64_t val) + void plist_get_int_val(plist_t node, int64_t *val) + void plist_set_int_val(plist_t node, int64_t val) + plist_t plist_new_real(double val) void plist_get_real_val(plist_t node, double *val) void plist_set_real_val(plist_t node, double val) - plist_t plist_new_date(int32_t sec, int32_t usec) - void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec) - void plist_set_date_val(plist_t node, int32_t sec, int32_t usec) + plist_t plist_new_unix_date(int64_t sec) + void plist_get_unix_date_val(plist_t node, int64_t *sec) + void plist_set_unix_date_val(plist_t node, int64_t sec) void plist_get_key_val(plist_t node, char **val) void plist_set_key_val(plist_t node, char *val) @@ -47,6 +52,8 @@ cdef extern from *: void plist_get_data_val(plist_t node, char **val, uint64_t * length) void plist_set_data_val(plist_t node, char *val, uint64_t length) + plist_t plist_new_null(); + plist_t plist_new_dict() int plist_dict_get_size(plist_t node) plist_t plist_dict_get_item(plist_t node, char* key) @@ -77,6 +84,8 @@ cdef extern from *: void plist_from_xml(char *plist_xml, uint32_t length, plist_t * plist) void plist_from_bin(char *plist_bin, uint32_t length, plist_t * plist) + int plist_int_val_is_negative(plist_t node); + cdef class Node: def __init__(self, *args, **kwargs): self._c_managed = True @@ -177,19 +186,22 @@ cdef Bool Bool_factory(plist_t c_node, bint managed=True): cdef class Integer(Node): def __cinit__(self, object value=None, *args, **kwargs): if value is None: - self._c_node = plist_new_uint(0) + self._c_node = plist_new_int(0) else: - self._c_node = plist_new_uint(int(value)) + if value < 0 or value <= INT64_MAX: + self._c_node = plist_new_int(int(value)) + else: + self._c_node = plist_new_uint(int(value)) def __repr__(self): - cdef uint64_t i = self.get_value() - return '<Integer: %s>' % i + return '<Integer: %s>' % self.get_value() def __int__(self): return self.get_value() def __float__(self): - return float(self.get_value()) + v = self.get_value() + return float(v) def __richcmp__(self, other, op): cdef int i = self.get_value() @@ -209,10 +221,18 @@ cdef class Integer(Node): cpdef set_value(self, object value): plist_set_uint_val(self._c_node, int(value)) - cpdef uint64_t get_value(self): - cdef uint64_t value - plist_get_uint_val(self._c_node, &value) - return value + cpdef get_value(self): + cdef int64_t ivalue + cdef uint64_t uvalue + if self.is_negative(): + plist_get_int_val(self._c_node, &ivalue) + return int(ivalue) + else: + plist_get_uint_val(self._c_node, &uvalue) + return int(uvalue) + + cpdef bint is_negative(self): + return plist_int_val_is_negative(self._c_node); cdef Integer Integer_factory(plist_t c_node, bint managed=True): cdef Integer instance = Integer.__new__(Integer) @@ -281,7 +301,8 @@ cdef class Uid(Node): return self.get_value() def __float__(self): - return float(self.get_value()) + v = self.get_value() + return float(v) def __richcmp__(self, other, op): cdef int i = self.get_value() @@ -312,6 +333,20 @@ cdef Uid Uid_factory(plist_t c_node, bint managed=True): instance._c_node = c_node return instance +cdef class Null(Node): + def __cinit__(self, object value=None, *args, **kwargs): + self._c_node = plist_new_null() + + def __repr__(self): + cdef uint64_t i = self.get_value() + return '<Null>' + +cdef Null Null_factory(plist_t c_node, bint managed=True): + cdef Null instance = Null.__new__(Null) + instance._c_managed = managed + instance._c_node = c_node + return instance + from cpython cimport PY_MAJOR_VERSION cdef class Key(Node): @@ -453,23 +488,21 @@ cdef String String_factory(plist_t c_node, bint managed=True): instance._c_node = c_node return instance -MAC_EPOCH = 978307200 - cdef extern from "plist_util.h": - void datetime_to_ints(object obj, int32_t* sec, int32_t* usec) - object ints_to_datetime(int32_t sec, int32_t usec) + int64_t datetime_to_timestamp(object obj) + object timestamp_to_datetime(int64_t sec) int check_datetime(object obj) cdef plist_t create_date_plist(value=None): cdef plist_t node = NULL - cdef int32_t secs - cdef int32_t usecs if value is None: - node = plist_new_date(0, 0) + node = plist_new_unix_date(0) + elif isinstance(value, int): + node = plist_new_unix_date(value) + elif isinstance(value, float): + node = plist_new_unix_date(int(value)) elif check_datetime(value): - datetime_to_ints(value, &secs, &usecs) - secs -= MAC_EPOCH - node = plist_new_date(secs, usecs) + node = plist_new_unix_date(datetime_to_timestamp(value)) return node cdef class Date(Node): @@ -496,19 +529,21 @@ cdef class Date(Node): return d >= other cpdef object get_value(self): - cdef int32_t secs = 0 - cdef int32_t usecs = 0 - plist_get_date_val(self._c_node, &secs, &usecs) - secs += MAC_EPOCH - return ints_to_datetime(secs, usecs) + cdef int64_t secs = 0 + plist_get_unix_date_val(self._c_node, &secs) + return timestamp_to_datetime(secs) cpdef set_value(self, object value): - cdef int32_t secs - cdef int32_t usecs - if not check_datetime(value): - raise ValueError("Expected a datetime") - datetime_to_ints(value, &secs, &usecs) - plist_set_date_val(self._c_node, secs, usecs) + cdef int64_t secs = 0 + if isinstance(value, int): + secs = value + elif isinstance(value, float): + secs = int(value) + elif check_datetime(value): + secs = datetime_to_timestamp(value) + else: + raise ValueError("Expected int or datetime") + plist_set_unix_date_val(self._c_node, secs) cdef Date Date_factory(plist_t c_node, bint managed=True): cdef Date instance = Date.__new__(Date) @@ -683,7 +718,7 @@ cdef class Dict(Node): def __delitem__(self, key): cpython.PyDict_DelItem(self._map, key) - plist_dict_remove_item(self._c_node, key) + plist_dict_remove_item(self._c_node, key.encode('utf-8')) cdef Dict Dict_factory(plist_t c_node, bint managed=True): cdef Dict instance = Dict.__new__(Dict) @@ -816,7 +851,7 @@ cdef plist_t native_to_plist_t(object native): return plist_new_string(native) if isinstance(native, bool): return plist_new_bool(<bint>native) - if isinstance(native, int) or isinstance(native, long): + if isinstance(native, int): return plist_new_uint(native) if isinstance(native, float): return plist_new_real(native) @@ -831,7 +866,7 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True): cdef plist_type t = plist_get_node_type(c_plist) if t == PLIST_BOOLEAN: return Bool_factory(c_plist, managed) - if t == PLIST_UINT: + if t == PLIST_INT: return Integer_factory(c_plist, managed) if t == PLIST_KEY: return Key_factory(c_plist, managed) @@ -849,6 +884,8 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True): return Data_factory(c_plist, managed) if t == PLIST_UID: return Uid_factory(c_plist, managed) + if t == PLIST_NULL: + return Null_factory(c_plist, managed) if t == PLIST_NONE: return None @@ -940,8 +977,10 @@ cpdef object dumps(value, fmt=FMT_XML, sort_keys=True, skipkeys=False): node = Dict(value) elif type(value) in (list, set, tuple): node = Array(value) + else: + node = value if fmt == FMT_XML: - return node.to_xml() + return node.to_xml().encode('utf-8') return node.to_bin() diff --git a/cython/plist_util.c b/cython/plist_util.c index 4f922e5..27084fa 100644 --- a/cython/plist_util.c +++ b/cython/plist_util.c @@ -3,13 +3,11 @@ #include <time.h> #include <datetime.h> -void datetime_to_ints(PyObject* obj, int32_t* sec, int32_t* usec) { +int64_t datetime_to_timestamp(PyObject* obj) { PyDateTime_IMPORT; if (!PyDateTime_Check(obj)) { - PyErr_SetString(PyExc_ValueError,"Expected a datetime"); - sec = NULL; - usec = NULL; - return; + PyErr_SetString(PyExc_ValueError,"Expected a datetime"); + return 0; } struct tm t; memset(&t, 0, sizeof(t)); @@ -19,22 +17,21 @@ void datetime_to_ints(PyObject* obj, int32_t* sec, int32_t* usec) { t.tm_mday = PyDateTime_GET_DAY(obj); t.tm_mon = PyDateTime_GET_MONTH(obj)-1; t.tm_year = PyDateTime_GET_YEAR(obj)-1900; - *sec = (int32_t)mktime(&t); - *usec = PyDateTime_DATE_GET_MICROSECOND(obj); + return mktime(&t); } -PyObject* ints_to_datetime(int32_t sec, int32_t usec) { - time_t sec_tt = sec; +PyObject* timestamp_to_datetime(int64_t sec) { + time_t sec_tt = sec; struct tm* t = gmtime(&sec_tt); if(t){ - PyDateTime_IMPORT; - return PyDateTime_FromDateAndTime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, usec); + PyDateTime_IMPORT; + return PyDateTime_FromDateAndTime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, 0); } - return NULL; + return NULL; } int check_datetime(PyObject* ob) { - if(ob){ - PyDateTime_IMPORT; - return PyDateTime_Check(ob); - } - return 0; + if(ob){ + PyDateTime_IMPORT; + return PyDateTime_Check(ob); + } + return 0; } diff --git a/cython/plist_util.h b/cython/plist_util.h index fbf56b6..e0a84b5 100644 --- a/cython/plist_util.h +++ b/cython/plist_util.h @@ -1,5 +1,5 @@ #include <Python.h> -void datetime_to_ints(PyObject* obj, int32_t* sec, int32_t* usec); -PyObject* ints_to_datetime(int32_t sec, int32_t usec); +int64_t datetime_to_timestamp(PyObject* obj); +PyObject* timestamp_to_datetime(int64_t sec); int check_datetime(PyObject* obj); |