Commit 2ca52d65 authored by Bryan Forbes's avatar Bryan Forbes Committed by Nikias Bassen

Added cython bindings.

parent 36ad4384
......@@ -17,13 +17,21 @@ ENDIF(NOT DEFINED CMAKE_INSTALL_LIBDIR)
FIND_PACKAGE( LibXml2 REQUIRED )
OPTION(ENABLE_PYTHON "Enable Python bindings (needs Swig)" ON)
OPTION(ENABLE_SWIG "Enable SWIG Python bindings (needs Swig)" ON)
OPTION(ENABLE_CYTHON "Enable Cython Python bindings (needs Cython)" ON)
IF(ENABLE_PYTHON)
IF(ENABLE_SWIG)
FIND_PACKAGE( SWIG )
ENDIF(ENABLE_SWIG)
IF(ENABLE_CYTHON)
FIND_PACKAGE( Cython )
ENDIF(ENABLE_CYTHON)
IF(ENABLE_SWIG OR ENABLE_CYTHON)
FIND_PACKAGE( PythonInterp )
FIND_PACKAGE( PythonLibs )
ENDIF(ENABLE_PYTHON)
ENDIF(ENABLE_SWIG OR ENABLE_CYTHON)
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_INCLUDE_PATH})
......@@ -52,6 +60,9 @@ ADD_SUBDIRECTORY( test )
IF ( SWIG_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND )
ADD_SUBDIRECTORY( swig )
ENDIF ( SWIG_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND )
IF ( CYTHON_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND )
ADD_SUBDIRECTORY( cython )
ENDIF ( CYTHON_FOUND AND PYTHONLIBS_FOUND AND PYTHONINTERP_FOUND )
# add uninstall target
CONFIGURE_FILE( "${CMAKE_SOURCE_DIR}/cmake/modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
......
FIND_PROGRAM(CYTHON_EXECUTABLE cython)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cython DEFAULT_MSG CYTHON_EXECUTABLE)
MARK_AS_ADVANCED(CYTHON_EXECUTABLE)
IF(CYTHON_FOUND)
SET(CYTHON_USE_FILE ${CMAKE_SOURCE_DIR}/cmake/modules/UseCython.cmake)
ENDIF(CYTHON_FOUND)
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)
cdef extern from "plist/plist.h":
ctypedef void *plist_t
ctypedef void *plist_dict_iter
cdef class Node:
cdef plist_t _c_node
cdef bool _c_managed
cpdef object __deepcopy__(self, memo=*)
cpdef bytes to_xml(self)
cpdef bytes to_bin(self)
cpdef object copy(self)
cdef class Bool(Node):
cpdef set_value(self, value)
cpdef bool get_value(self)
cdef class Integer(Node):
cpdef set_value(self, value)
cpdef int get_value(self)
cdef class Real(Node):
cpdef set_value(self, value)
cpdef float get_value(self)
cdef class String(Node):
cpdef set_value(self, unicode value)
cpdef unicode get_value(self)
cdef class Date(Node):
cpdef set_value(self, value)
cpdef object get_value(self)
cdef class Data(Node):
cpdef set_value(self, bytes value)
cpdef bytes get_value(self)
cdef class Dict(Node):
cdef dict _map
cdef void _init(self)
cpdef set_value(self, dict value)
cpdef dict get_value(self)
cpdef bool has_key(self, key)
cpdef object get(self, key, default=*)
cpdef list keys(self)
cpdef list items(self)
cpdef list values(self)
cpdef object iterkeys(self)
cpdef object iteritems(self)
cpdef object itervalues(self)
cdef class Array(Node):
cdef list _array
cdef void _init(self)
cpdef set_value(self, value)
cpdef list get_value(self)
cpdef append(self, item)
cpdef object from_xml(xml)
cpdef object from_bin(bytes bin)
cdef object plist_t_to_node(plist_t c_plist, bool managed=*)
cdef plist_t native_to_plist_t(object native)
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 python_unicode
cdef extern from *:
ctypedef enum plist_type:
PLIST_BOOLEAN,
PLIST_UINT,
PLIST_REAL,
PLIST_STRING,
PLIST_ARRAY,
PLIST_DICT,
PLIST_DATE,
PLIST_DATA,
PLIST_KEY,
PLIST_NONE
plist_t plist_new_bool(uint8_t val)
void plist_get_bool_val(plist_t node, uint8_t *val)
void plist_set_bool_val(plist_t node, uint8_t val)
plist_t plist_new_uint(uint64_t val)
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_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_string(char *val)
void plist_get_string_val(plist_t node, char **val)
void plist_set_string_val(plist_t node, char *val)
plist_t plist_new_data(char *val, uint64_t length)
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_dict()
int plist_dict_get_size(plist_t node)
plist_t plist_dict_get_item(plist_t node, char* key)
void plist_dict_set_item(plist_t node, char* key, plist_t item)
void plist_dict_insert_item(plist_t node, char* key, plist_t item)
void plist_dict_remove_item(plist_t node, char* key)
void plist_dict_new_iter(plist_t node, plist_dict_iter *iter)
void plist_dict_next_item(plist_t node, plist_dict_iter iter, char **key, plist_t *val)
plist_t plist_new_array()
uint32_t plist_array_get_size(plist_t node)
plist_t plist_array_get_item(plist_t node, uint32_t n)
uint32_t plist_array_get_item_index(plist_t node)
void plist_array_set_item(plist_t node, plist_t item, uint32_t n)
void plist_array_append_item(plist_t node, plist_t item)
void plist_array_insert_item(plist_t node, plist_t item, uint32_t n)
void plist_array_remove_item(plist_t node, uint32_t n)
void plist_free(plist_t plist)
plist_t plist_copy(plist_t plist)
void plist_to_xml(plist_t plist, char **plist_xml, uint32_t *length)
void plist_to_bin(plist_t plist, char **plist_bin, uint32_t *length)
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)
cdef extern from *:
void free(void *ptr)
cdef class Node:
def __init__(self, *args, **kwargs):
self._c_managed = True
def __dealloc__(self):
if self._c_node is not NULL and self._c_managed:
plist_free(self._c_node)
cpdef object __deepcopy__(self, memo={}):
return plist_t_to_node(plist_copy(self._c_node))
cpdef object copy(self):
cdef plist_t c_node = NULL
c_node = plist_copy(self._c_node)
return plist_t_to_node(c_node)
cpdef bytes to_xml(self):
cdef char* out = NULL
cdef uint32_t length
plist_to_xml(self._c_node, &out, &length)
return out[:length]
cpdef bytes to_bin(self):
cdef char* out = NULL
cdef uint32_t length
plist_to_bin(self._c_node, &out, &length)
return out[:length]
property parent:
def __get__(self):
cdef plist_t c_parent = NULL
cdef Node node
c_parent = plist_get_parent(self._c_node)
if c_parent == NULL:
return None
return plist_t_to_node(c_parent)
def __str__(self):
return str(self.get_value())
cdef class Bool(Node):
def __cinit__(self, value=None, *args, **kwargs):
if value is None:
self._c_node = plist_new_bool(0)
else:
self._c_node = plist_new_bool(bool(value))
def __nonzero__(self):
return self.get_value()
def __richcmp__(self, other, op):
cdef bool b = self.get_value()
if op == 0:
return b < other
if op == 1:
return b <= other
if op == 2:
return b == other
if op == 3:
return b != other
if op == 4:
return b > other
if op == 5:
return b >= other
def __repr__(self):
b = self.get_value()
return '<Bool: %s>' % b
cpdef set_value(self, value):
plist_set_bool_val(self._c_node, bool(value))
cpdef bool get_value(self):
cdef uint8_t value
plist_get_bool_val(self._c_node, &value)
return bool(value)
cdef Bool Bool_factory(plist_t c_node, bool managed=True):
cdef Bool instance = Bool.__new__(Bool)
instance._c_managed = managed
instance._c_node = c_node
return instance
cdef class Integer(Node):
def __cinit__(self, value=None, *args, **kwargs):
if value is None:
self._c_node = plist_new_uint(0)
else:
self._c_node = plist_new_uint(int(value))
def __repr__(self):
i = self.get_value()
return '<Integer: %s>' % i
def __int__(self):
return self.get_value()
def __float__(self):
return float(self.get_value())
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, 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
cdef Integer Integer_factory(plist_t c_node, bool managed=True):
cdef Integer instance = Integer.__new__(Integer)
instance._c_managed = managed
instance._c_node = c_node
return instance
cdef class Real(Node):
def __cinit__(self, value=None, *args, **kwargs):
if value is None:
self._c_node = plist_new_real(0.0)
else:
self._c_node = plist_new_real(float(value))
def __repr__(self):
r = self.get_value()
return '<Real: %s>' % r
def __float__(self):
return self.get_value()
def __int__(self):
return int(self.get_value())
def __richcmp__(self, other, op):
cdef float f = self.get_value()
if op == 0:
return f < other
if op == 1:
return f <= other
if op == 2:
return f == other
if op == 3:
return f != other
if op == 4:
return f > other
if op == 5:
return f >= other
cpdef set_value(self, value):
plist_set_real_val(self._c_node, float(value))
cpdef float get_value(self):
cdef double value
plist_get_real_val(self._c_node, &value)
return value
cdef Real Real_factory(plist_t c_node, bool managed=True):
cdef Real instance = Real.__new__(Real)
instance._c_managed = managed
instance._c_node = c_node
return instance
from python_version cimport PY_MAJOR_VERSION
cdef class String(Node):
def __cinit__(self, value=None, *args, **kwargs):
if value is None:
self._c_node = plist_new_string("")
else:
if isinstance(value, unicode):
utf8_data = value.encode('utf-8')
elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
value.decode('ascii')
utf8_data = value
else:
raise ValueError("requires text input, got %s" % type(value))
self._c_node = plist_new_string(utf8_data)
def __repr__(self):
s = self.get_value()
return '<String: %s>' % s
def __richcmp__(self, other, op):
cdef str 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, unicode value):
if value is None:
self._c_node = plist_new_string("")
else:
if isinstance(value, unicode):
utf8_data = value.encode('utf-8')
elif (PY_MAJOR_VERSION < 3) and isinstance(value, str):
value.decode('ascii')
utf8_data = value
else:
raise ValueError("requires text input, got %s" % type(value))
self._c_node = plist_new_string(utf8_data)
cpdef unicode get_value(self):
cdef char* value = NULL
plist_get_string_val(self._c_node, &value)
return python_unicode.PyUnicode_DecodeUTF8(value, len(value), 'strict')
cdef String String_factory(plist_t c_node, bool managed=True):
cdef String instance = String.__new__(String)
instance._c_managed = managed
instance._c_node = c_node
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)
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)
elif check_datetime(value):
datetime_to_ints(value, &secs, &usecs)
node = plist_new_date(secs, usecs)
return node
cdef class Date(Node):
def __cinit__(self, value=None, *args, **kwargs):
self._c_node = create_date_plist(value)
def __repr__(self):
d = self.get_value()
return '<Date: %s>' % d.ctime()
def __richcmp__(self, other, op):
d = self.get_value()
if op == 0:
return d < other
if op == 1:
return d <= other
if op == 2:
return d == other
if op == 3:
return d != other
if op == 4:
return d > other
if op == 5:
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)
cpdef set_value(self, 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 Date Date_factory(plist_t c_node, bool managed=True):
cdef Date instance = Date.__new__(Date)
instance._c_managed = managed
instance._c_node = c_node
return instance
cdef class Data(Node):
def __cinit__(self, value=None, *args, **kwargs):
if value is None:
self._c_node = plist_new_data(NULL, 0)
else:
self._c_node = plist_new_data(value, len(value))
def __repr__(self):
d = self.get_value()
return '<Data: %s>' % d
def __richcmp__(self, other, op):
cdef str d = self.get_value()
if op == 0:
return d < other
if op == 1:
return d <= other
if op == 2:
return d == other
if op == 3:
return d != other
if op == 4:
return d > other
if op == 5:
return d >= other
cpdef bytes get_value(self):
cdef char* val = NULL
cdef uint64_t length = 0
plist_get_data_val(self._c_node, &val, &length)
return val[:length]
cpdef set_value(self, bytes value):
plist_set_data_val(self._c_node, value, len(value))
cdef Data Data_factory(plist_t c_node, bool managed=True):
cdef Data instance = Data.__new__(Data)
instance._c_managed = managed
instance._c_node = c_node
return instance
cdef plist_t create_dict_plist(value=None):
cdef plist_t node = NULL
cdef plist_t c_node = NULL
node = plist_new_dict()
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)
c_node = NULL
return node
cdef class Dict(Node):
def __cinit__(self, value=None, *args, **kwargs):
self._c_node = create_dict_plist(value)
def __init__(self, value=None, *args, **kwargs):
self._init()
cdef void _init(self):
cdef plist_dict_iter it = NULL
cdef char* key = NULL
cdef plist_t subnode = NULL
self._map = {}
plist_dict_new_iter(self._c_node, &it);
plist_dict_next_item(self._c_node, it, &key, &subnode);
while subnode is not NULL:
self._map[key] = plist_t_to_node(subnode, False)
subnode = NULL
free(key)
key = NULL
plist_dict_next_item(self._c_node, it, &key, &subnode);
free(it)
def __dealloc__(self):
self._map = None
Node.__dealloc__(self)
def __richcmp__(self, other, op):
cdef dict d = self.get_value()
if op == 0:
return d < other
if op == 1:
return d <= other
if op == 2:
return d == other
if op == 3:
return d != other
if op == 4:
return d > other
if op == 5:
return d >= other
def __len__(self):
return len(self._map)
def __repr__(self):
return '<Dict: %s>' % self._map
cpdef dict get_value(self):
return dict([(key, value.get_value()) for key, value in self.items()])
cpdef set_value(self, dict value):
plist_free(self._c_node)
self._map = {}
self._c_node = NULL
self._c_node = create_dict_plist(value)
self._init()
def __iter__(self):
return self._map.__iter__()
cpdef bool has_key(self, key):
return self._map.has_key(key)
cpdef object get(self, key, default=None):
return self._map.get(key, default)
cpdef list keys(self):
return self._map.keys()
cpdef object iterkeys(self):
return self._map.iterkeys()
cpdef list items(self):
return self._map.items()
cpdef object iteritems(self):
return self._map.iteritems()
cpdef list values(self):
return self._map.values()
cpdef object itervalues(self):
return self._map.itervalues()
def __getitem__(self, key):
return self._map[key]
def __setitem__(self, key, value):
cdef Node n
if isinstance(value, Node):
n = value.copy()
else:
n = plist_t_to_node(native_to_plist_t(value), False)
plist_dict_insert_item(self._c_node, key, n._c_node)
self._map[key] = n
def __delitem__(self, key):
del self._map[key]
plist_dict_remove_item(self._c_node, key)
cdef Dict Dict_factory(plist_t c_node, bool managed=True):
cdef Dict instance = Dict.__new__(Dict)
instance._c_managed = managed
instance._c_node = c_node
instance._init()
return instance
cdef plist_t create_array_plist(value=None):
cdef plist_t node = NULL
cdef plist_t c_node = NULL
node = plist_new_array()
if value is not None and (isinstance(value, list) or isinstance(value, tuple)):
for item in value:
c_node = native_to_plist_t(item)
plist_array_append_item(node, c_node)
c_node = NULL
return node
cdef class Array(Node):
def __cinit__(self, value=None, *args, **kwargs):
self._c_node = create_array_plist(value)
def __init__(self, value=None, *args, **kwargs):
self._init()
cdef void _init(self):
cdef uint32_t size = plist_array_get_size(self._c_node)
cdef plist_t subnode = NULL
for i from 0 <= i < size:
subnode = plist_array_get_item(self._c_node, i)
self._array.append(plist_t_to_node(subnode, False))
def __richcmp__(self, other, op):
cdef list l = self.get_value()
if op == 0:
return l < other
if op == 1:
return l <= other
if op == 2:
return l == other
if op == 3:
return l != other
if op == 4:
return l > other
if op == 5:
return l >= other
def __len__(self):
return len(self._array)
def __repr__(self):
return '<Array: %s>' % self._array
cpdef list get_value(self):
return [i.get_value() for i in self]
cpdef set_value(self, value):
self._array = []
plist_free(self._c_node)
self._c_node = NULL
self._c_node = create_array_plist(value)
self._init()
def __iter__(self):
return self._array.__iter__()
def __getitem__(self, index):
return self._array[index]
def __setitem__(self, index, value):
cdef Node n
if isinstance(value, Node):
n = value.copy()
else:
n = plist_t_to_node(native_to_plist_t(value), False)
if index < 0:
index = len(self) + index
plist_array_set_item(self._c_node, n._c_node, index)
self._array[index] = n
def __delitem__(self, index):
if index < 0:
index = len(self) + index
del self._array[index]
plist_array_remove_item(self._c_node, index)
cpdef append(self, item):
cdef Node n
if isinstance(item, Node):
n = item.copy()
else:
n = plist_t_to_node(native_to_plist_t(item), False)
plist_array_append_item(self._c_node, n._c_node)
self._array.append(n)
cdef Array Array_factory(plist_t c_node, bool managed=True):
cdef Array instance = Array.__new__(Array)
instance._c_managed = managed
instance._c_node = c_node
instance._init()
return instance
cpdef object from_xml(xml):
cdef plist_t c_node = NULL
plist_from_xml(xml, len(xml), &c_node)
return plist_t_to_node(c_node)
cpdef object from_bin(bytes bin):
cdef plist_t c_node = NULL
plist_from_bin(bin, len(bin), &c_node)
return plist_t_to_node(c_node)
cdef plist_t native_to_plist_t(object native):
cdef plist_t c_node
cdef plist_t child_c_node
cdef int32_t secs = 0
cdef int32_t usecs = 0
cdef Node node
if isinstance(native, Node):
node = native
return plist_copy(node._c_node)
if isinstance(native, basestring):
return plist_new_string(native)
if isinstance(native, bool):
return plist_new_bool(native)
if isinstance(native, int) or isinstance(native, long):
return plist_new_uint(native)
if isinstance(native, float):
return plist_new_real(native)
if isinstance(native, dict):
return create_dict_plist(native)
if isinstance(native, list) or isinstance(native, tuple):
return create_array_plist(native)
if check_datetime(native):
return create_date_plist(native)
cdef object plist_t_to_node(plist_t c_plist, bool 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:
return Integer_factory(c_plist, managed)
if t == PLIST_REAL:
return Real_factory(c_plist, managed)
if t == PLIST_STRING:
return String_factory(c_plist, managed)
if t == PLIST_ARRAY:
return Array_factory(c_plist, managed)
if t == PLIST_DICT:
return Dict_factory(c_plist, managed)
if t == PLIST_DATE:
return Date_factory(c_plist, managed)
if t == PLIST_DATA:
return Data_factory(c_plist, managed)
#include "plist_util.h"
#include <time.h>
#include <datetime.h>
void datetime_to_ints(PyObject* obj, int32_t* sec, int32_t* usec) {
PyDateTime_IMPORT;
if (!PyDateTime_Check(obj)) {
PyErr_SetString(PyExc_ValueError,"Expected a datetime");
sec = NULL;
usec = NULL;
return;
}
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);
}
PyObject* ints_to_datetime(int32_t sec, int32_t usec) {
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);
}
return NULL;
}
int check_datetime(PyObject* ob) {
if(ob){
PyDateTime_IMPORT;
return PyDateTime_Check(ob);
}
return 0;
}
#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);
int check_datetime(PyObject* obj);
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