diff options
Diffstat (limited to 'cython')
| -rw-r--r-- | cython/CMakeLists.txt | 30 | ||||
| -rw-r--r-- | cython/Makefile.am | 57 | ||||
| -rw-r--r-- | cython/plist.pxd | 20 | ||||
| -rw-r--r-- | cython/plist.pyx | 371 | ||||
| -rw-r--r-- | cython/plist_util.c | 48 | ||||
| -rw-r--r-- | cython/plist_util.h | 4 |
6 files changed, 413 insertions, 117 deletions
diff --git a/cython/CMakeLists.txt b/cython/CMakeLists.txt deleted file mode 100644 index eac6bee..0000000 --- a/cython/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ - -INCLUDE_DIRECTORIES( ${PYTHON_INCLUDE_PATH} ${CMAKE_CURRENT_SOURCE_DIR} ) - - -SET(plist_SRC - ${CMAKE_CURRENT_BINARY_DIR}/plist.c ) - -SET(plist_HDR - ${CMAKE_CURRENT_SOURCE_DIR}/plist.pxd ) - -ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/plist.c - COMMAND ${CYTHON_EXECUTABLE} -o ${CMAKE_CURRENT_BINARY_DIR}/plist.c ${CMAKE_CURRENT_SOURCE_DIR}/plist.pyx - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/plist.pyx ${CMAKE_CURRENT_SOURCE_DIR}/plist.pxd -) - - -EXEC_PROGRAM("${PYTHON_EXECUTABLE}" - ARGS "-c 'try:\n import distutils.sysconfig; print distutils.sysconfig.get_python_lib(1,0,\"${CMAKE_INSTALL_PREFIX}\")\nexcept: pass\n'" - OUTPUT_VARIABLE DISTUTILS_PYTHON_ILIBRARY_PATH - ) - -PYTHON_ADD_MODULE(cython_plist plist.c plist_util.c) -SET_TARGET_PROPERTIES(cython_plist PROPERTIES PREFIX "" OUTPUT_NAME plist) -TARGET_LINK_LIBRARIES(cython_plist plist ${PYTHON_LIBRARIES}) - -INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/plist${CMAKE_SHARED_MODULE_SUFFIX} - DESTINATION ${DISTUTILS_PYTHON_ILIBRARY_PATH} ) -INSTALL( FILES ${CMAKE_CURRENT_SOURCE_DIR}/plist.pxd - DESTINATION include/plist/cython COMPONENT dev) diff --git a/cython/Makefile.am b/cython/Makefile.am new file mode 100644 index 0000000..bbc51c9 --- /dev/null +++ b/cython/Makefile.am @@ -0,0 +1,57 @@ +AM_CPPFLAGS = -I$(top_srcdir)/include + +AM_CFLAGS = $(GLOBAL_CFLAGS) +AM_LDFLAGS = $(GLOBAL_LDFLAGS) + +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 + +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) -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) + +.pyx.c: + $(CYTHON) -I$(CYTHON_PLIST_INCLUDE_DIR) -I$(top_srcdir)/src -o $@ $< + +pxddir = $(includedir)/plist/cython +pxd_DATA = plist.pxd + +endif diff --git a/cython/plist.pxd b/cython/plist.pxd index a31419d..5a41bf8 100644 --- a/cython/plist.pxd +++ b/cython/plist.pxd @@ -1,3 +1,5 @@ +from libc.stdint cimport * + cdef extern from "plist/plist.h": ctypedef void *plist_t ctypedef void *plist_dict_iter @@ -14,10 +16,19 @@ cdef class Node: cdef class Bool(Node): cpdef set_value(self, object value) cpdef bint get_value(self) - + cdef class Integer(Node): cpdef set_value(self, object value) - cpdef int get_value(self) + cpdef get_value(self) + cpdef bint is_negative(self) + +cdef class Uid(Node): + cpdef set_value(self, object value) + cpdef uint64_t get_value(self) + +cdef class Key(Node): + cpdef set_value(self, object value) + cpdef unicode get_value(self) cdef class Real(Node): cpdef set_value(self, object value) @@ -59,5 +70,10 @@ cdef class Array(Node): cpdef object from_xml(xml) cpdef object from_bin(bytes bin) +cpdef object load(fp, fmt=*, use_builtin_types=*, dict_type=*) +cpdef object loads(data, fmt=*, use_builtin_types=*, dict_type=*) +cpdef object dump(value, fp, fmt=*, sort_keys=*, skipkeys=*) +cpdef object dumps(value, fmt=*, sort_keys=*, skipkeys=*) + cdef object plist_t_to_node(plist_t c_plist, bint managed=*) cdef plist_t native_to_plist_t(object native) diff --git a/cython/plist.pyx b/cython/plist.pyx index 3716a9c..73912d8 100644 --- a/cython/plist.pyx +++ b/cython/plist.pyx @@ -1,21 +1,11 @@ -cdef extern from *: - ctypedef unsigned char uint8_t - ctypedef short int int16_t - ctypedef unsigned short int uint16_t - ctypedef unsigned int uint32_t - ctypedef int int32_t -IF UNAME_MACHINE == 'x86_64': - ctypedef unsigned long int uint64_t -ELSE: - ctypedef unsigned long long int uint64_t - cimport cpython cimport libc.stdlib +from libc.stdint cimport * cdef extern from *: ctypedef enum plist_type: PLIST_BOOLEAN, - PLIST_UINT, + PLIST_INT, PLIST_REAL, PLIST_STRING, PLIST_ARRAY, @@ -23,6 +13,8 @@ cdef extern from *: PLIST_DATE, PLIST_DATA, PLIST_KEY, + PLIST_UID, + PLIST_NULL, PLIST_NONE plist_t plist_new_bool(uint8_t val) @@ -33,13 +25,24 @@ 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) + + plist_t plist_new_uid(uint64_t val) + void plist_get_uid_val(plist_t node, uint64_t *val) + void plist_set_uid_val(plist_t node, uint64_t val) plist_t plist_new_string(char *val) void plist_get_string_val(plist_t node, char **val) @@ -49,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) @@ -76,11 +81,11 @@ cdef extern from *: plist_t plist_get_parent(plist_t node) plist_type plist_get_node_type(plist_t node) - void plist_set_type(plist_t node, plist_type type) - 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 @@ -116,7 +121,7 @@ cdef class Node: plist_to_bin(self._c_node, &out, &length) try: - return cpython.PyString_FromStringAndSize(out, length) + return bytes(out[:length]) finally: if out != NULL: libc.stdlib.free(out) @@ -181,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 int 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() @@ -213,10 +221,18 @@ cdef class Integer(Node): cpdef set_value(self, object value): plist_set_uint_val(self._c_node, int(value)) - cpdef int 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) @@ -270,8 +286,139 @@ cdef Real Real_factory(plist_t c_node, bint managed=True): instance._c_node = c_node return instance +cdef class Uid(Node): + def __cinit__(self, object value=None, *args, **kwargs): + if value is None: + self._c_node = plist_new_uid(0) + else: + self._c_node = plist_new_uid(int(value)) + + def __repr__(self): + cdef uint64_t i = self.get_value() + return '<Uid: %s>' % i + + def __int__(self): + return self.get_value() + + def __float__(self): + v = self.get_value() + return float(v) + + def __richcmp__(self, other, op): + cdef int i = self.get_value() + if op == 0: + return i < other + if op == 1: + return i <= other + if op == 2: + return i == other + if op == 3: + return i != other + if op == 4: + return i > other + if op == 5: + return i >= other + + cpdef set_value(self, object value): + plist_set_uid_val(self._c_node, int(value)) + + cpdef uint64_t get_value(self): + cdef uint64_t value + plist_get_uid_val(self._c_node, &value) + return value + +cdef Uid Uid_factory(plist_t c_node, bint managed=True): + cdef Uid instance = Uid.__new__(Uid) + instance._c_managed = managed + 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): + def __cinit__(self, object value=None, *args, **kwargs): + cdef: + char* c_utf8_data = NULL + bytes utf8_data + if value is None: + raise ValueError("Requires a value") + else: + if isinstance(value, unicode): + utf8_data = value.encode('utf-8') + elif (PY_MAJOR_VERSION < 3) and isinstance(value, str): + value.encode('ascii') # trial decode + utf8_data = value.encode('ascii') + else: + raise ValueError("Requires unicode input, got %s" % type(value)) + c_utf8_data = utf8_data + self._c_node = plist_new_string("") + plist_set_key_val(self._c_node, c_utf8_data) + + def __repr__(self): + s = self.get_value() + return '<Key: %s>' % s.encode('utf-8') + + def __richcmp__(self, other, op): + cdef unicode s = self.get_value() + if op == 0: + return s < other + if op == 1: + return s <= other + if op == 2: + return s == other + if op == 3: + return s != other + if op == 4: + return s > other + if op == 5: + return s >= other + + cpdef set_value(self, object value): + cdef: + char* c_utf8_data = NULL + bytes utf8_data + if value is None: + plist_set_key_val(self._c_node, c_utf8_data) + else: + if isinstance(value, unicode): + utf8_data = value.encode('utf-8') + elif (PY_MAJOR_VERSION < 3) and isinstance(value, str): + value.encode('ascii') # trial decode + utf8_data = value.encode('ascii') + else: + raise ValueError("Requires unicode input, got %s" % type(value)) + c_utf8_data = utf8_data + plist_set_key_val(self._c_node, c_utf8_data) + + cpdef unicode get_value(self): + cdef: + char* c_value = NULL + plist_get_key_val(self._c_node, &c_value) + try: + return cpython.PyUnicode_DecodeUTF8(c_value, len(c_value), 'strict') + finally: + libc.stdlib.free(c_value) + +cdef Key Key_factory(plist_t c_node, bint managed=True): + cdef Key instance = Key.__new__(Key) + instance._c_managed = managed + instance._c_node = c_node + return instance + cdef class String(Node): def __cinit__(self, object value=None, *args, **kwargs): cdef: @@ -342,19 +489,20 @@ cdef String String_factory(plist_t c_node, bint managed=True): return instance 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) - node = plist_new_date(secs, usecs) + node = plist_new_unix_date(datetime_to_timestamp(value)) return node cdef class Date(Node): @@ -381,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 - cdef object result - plist_get_date_val(self._c_node, &secs, &usecs) - 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) @@ -434,7 +584,7 @@ cdef class Data(Node): plist_get_data_val(self._c_node, &val, &length) try: - return cpython.PyString_FromStringAndSize(val, length) + return bytes(val[:length]) finally: libc.stdlib.free(val) @@ -456,7 +606,7 @@ cdef plist_t create_dict_plist(object value=None): if value is not None and isinstance(value, dict): for key, item in value.items(): c_node = native_to_plist_t(item) - plist_dict_insert_item(node, key, c_node) + plist_dict_set_item(node, key, c_node) c_node = NULL return node @@ -480,7 +630,12 @@ cdef class Dict(Node): plist_dict_next_item(self._c_node, it, &key, &subnode); while subnode is not NULL: - cpython.PyDict_SetItem(self._map, key, plist_t_to_node(subnode, False)) + py_key = key + + if PY_MAJOR_VERSION >= 3: + py_key = py_key.decode('utf-8') + + cpython.PyDict_SetItem(self._map, py_key, plist_t_to_node(subnode, False)) subnode = NULL libc.stdlib.free(key) key = NULL @@ -512,9 +667,7 @@ cdef class Dict(Node): return '<Dict: %s>' % self._map cpdef dict get_value(self): - cdef dict result = cpython.PyDict_New() return dict([(key, value.get_value()) for key, value in self.items()]) - return result cpdef set_value(self, dict value): plist_free(self._c_node) @@ -546,7 +699,6 @@ cdef class Dict(Node): cpdef list values(self): return cpython.PyDict_Values(self._map) - return self._map.values() cpdef object itervalues(self): return self._map.itervalues() @@ -561,12 +713,12 @@ cdef class Dict(Node): else: n = plist_t_to_node(native_to_plist_t(value), False) - plist_dict_insert_item(self._c_node, key, n._c_node) + plist_dict_set_item(self._c_node, key, n._c_node) self._map[key] = n 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) @@ -598,7 +750,7 @@ cdef class Array(Node): cdef uint32_t size = plist_array_get_size(self._c_node) cdef plist_t subnode = NULL - for i from 0 <= i < size: + for i in range(size): subnode = plist_array_get_item(self._c_node, i) self._array.append(plist_t_to_node(subnode, False)) @@ -637,7 +789,10 @@ cdef class Array(Node): return self._array.__iter__() def __getitem__(self, index): - return self._array[index] + value = self._array[index] + if isinstance(value, list): + return [item.copy() for item in value] + return value.copy() def __setitem__(self, index, value): cdef Node n @@ -699,7 +854,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) @@ -714,8 +869,10 @@ 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) if t == PLIST_REAL: return Real_factory(c_plist, managed) if t == PLIST_STRING: @@ -728,5 +885,105 @@ cdef object plist_t_to_node(plist_t c_plist, bint managed=True): return Date_factory(c_plist, managed) if t == PLIST_DATA: 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 + +# This is to match up with the new plistlib API +# http://docs.python.org/dev/library/plistlib.html +# dump() and dumps() are not yet implemented +FMT_XML = 1 +FMT_BINARY = 2 + +cpdef object load(fp, fmt=None, use_builtin_types=True, dict_type=dict): + is_binary = fp.read(6) == 'bplist' + fp.seek(0) + + cdef object cb = None + + if not fmt: + if is_binary: + if 'b' not in fp.mode: + raise IOError('File handle must be opened in binary (b) mode to read binary property lists') + cb = from_bin + else: + cb = from_xml + else: + if fmt not in (FMT_XML, FMT_BINARY): + raise ValueError('Format must be constant FMT_XML or FMT_BINARY') + if fmt == FMT_BINARY: + cb = from_bin + elif fmt == FMT_XML: + cb = from_xml + + if is_binary and fmt == FMT_XML: + raise ValueError('Cannot parse binary property list as XML') + elif not is_binary and fmt == FMT_BINARY: + raise ValueError('Cannot parse XML property list as binary') + + return cb(fp.read()) + +cpdef object loads(data, fmt=None, use_builtin_types=True, dict_type=dict): + is_binary = data[0:6] == 'bplist' + + cdef object cb = None + + if fmt is not None: + if fmt not in (FMT_XML, FMT_BINARY): + raise ValueError('Format must be constant FMT_XML or FMT_BINARY') + if fmt == FMT_BINARY: + cb = from_bin + else: + cb = from_xml + else: + if is_binary: + cb = from_bin + else: + cb = from_xml + + if is_binary and fmt == FMT_XML: + raise ValueError('Cannot parse binary property list as XML') + elif not is_binary and fmt == FMT_BINARY: + raise ValueError('Cannot parse XML property list as binary') + + return cb(data) + +cpdef object dump(value, fp, fmt=FMT_XML, sort_keys=True, skipkeys=False): + fp.write(dumps(value, fmt=fmt)) + +cpdef object dumps(value, fmt=FMT_XML, sort_keys=True, skipkeys=False): + if fmt not in (FMT_XML, FMT_BINARY): + raise ValueError('Format must be constant FMT_XML or FMT_BINARY') + + if check_datetime(value): + node = Date(value) + elif isinstance(value, unicode): + node = String(value) + elif PY_MAJOR_VERSION >= 3 and isinstance(value, bytes): + node = Data(value) + elif isinstance(value, str): + # See if this is binary + try: + node = String(value) + except ValueError: + node = Data(value) + elif isinstance(value, bool): + node = Bool(value) + elif isinstance(value, int): + node = Integer(value) + elif isinstance(value, float): + node = Real(value) + elif isinstance(value, dict): + node = Dict(value) + elif type(value) in (list, set, tuple): + node = Array(value) + else: + node = value + + if fmt == FMT_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 70c5be3..27084fa 100644 --- a/cython/plist_util.c +++ b/cython/plist_util.c @@ -3,39 +3,35 @@ #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 = { - PyDateTime_DATE_GET_SECOND(obj), - PyDateTime_DATE_GET_MINUTE(obj), - PyDateTime_DATE_GET_HOUR(obj), - PyDateTime_GET_DAY(obj), - PyDateTime_GET_MONTH(obj)-1, - PyDateTime_GET_YEAR(obj)-1900, - 0,0,0 - }; - *sec = (int32_t)mktime(&t); - *usec = PyDateTime_DATE_GET_MICROSECOND(obj); + struct tm t; + memset(&t, 0, sizeof(t)); + t.tm_sec = PyDateTime_DATE_GET_SECOND(obj); + t.tm_min = PyDateTime_DATE_GET_MINUTE(obj); + t.tm_hour = PyDateTime_DATE_GET_HOUR(obj); + t.tm_mday = PyDateTime_GET_DAY(obj); + t.tm_mon = PyDateTime_GET_MONTH(obj)-1; + t.tm_year = PyDateTime_GET_YEAR(obj)-1900; + 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); |
