pyglue: add float2nttime() and nttime2float()
authorStefan Metzmacher <metze@samba.org>
Wed, 2 Dec 2020 14:42:10 +0000 (15:42 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 1 Mar 2021 03:50:35 +0000 (03:50 +0000)
The float value is what the native python time.time()
returns, it's basically a struct timespec converted to
double/float.

Pair-Programmed-With: Björn Baumbach <bb@sernet.de>

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Björn Baumbach <bb@sernet.de>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/pyglue.c
python/samba/__init__.py
python/samba/tests/glue.py

index 156eaf731505c70426538f3dfededdf0871639ad..ed79df10be23c91a3924091ef4e46c39c4e05644 100644 (file)
@@ -134,6 +134,49 @@ static PyObject *py_nttime2unix(PyObject *self, PyObject *args)
        return PyLong_FromLong((uint64_t)t);
 }
 
+static PyObject *py_float2nttime(PyObject *self, PyObject *args)
+{
+       double ft = 0;
+       double ft_sec = 0;
+       double ft_nsec = 0;
+       struct timespec ts;
+       NTTIME nt = 0;
+
+       if (!PyArg_ParseTuple(args, "d", &ft)) {
+               return NULL;
+       }
+
+       ft_sec = (double)(int)ft;
+       ft_nsec = (ft - ft_sec) * 1.0e+9;
+
+       ts.tv_sec = (int)ft_sec;
+       ts.tv_nsec = (int)ft_nsec;
+
+       nt = full_timespec_to_nt_time(&ts);
+
+       return PyLong_FromLongLong((uint64_t)nt);
+}
+
+static PyObject *py_nttime2float(PyObject *self, PyObject *args)
+{
+       double ft = 0;
+       struct timespec ts;
+       const struct timespec ts_zero = { .tv_sec = 0, };
+       NTTIME nt = 0;
+
+       if (!PyArg_ParseTuple(args, "K", &nt)) {
+               return NULL;
+       }
+
+       ts = nt_time_to_full_timespec(nt);
+       if (is_omit_timespec(&ts)) {
+               return PyFloat_FromDouble(1.0);
+       }
+       ft = timespec_elapsed2(&ts_zero, &ts);
+
+       return PyFloat_FromDouble(ft);
+}
+
 static PyObject *py_nttime2string(PyObject *self, PyObject *args)
 {
        PyObject *ret;
@@ -374,6 +417,10 @@ static PyMethodDef py_misc_methods[] = {
                "unix2nttime(timestamp) -> nttime" },
        { "nttime2unix", (PyCFunction)py_nttime2unix, METH_VARARGS,
                "nttime2unix(nttime) -> timestamp" },
+       { "float2nttime", (PyCFunction)py_float2nttime, METH_VARARGS,
+               "pytime2nttime(floattimestamp) -> nttime" },
+       { "nttime2float", (PyCFunction)py_nttime2float, METH_VARARGS,
+               "nttime2pytime(nttime) -> floattimestamp" },
        { "nttime2string", (PyCFunction)py_nttime2string, METH_VARARGS,
                "nttime2string(nttime) -> string" },
        { "set_debug_level", (PyCFunction)py_set_debug_level, METH_VARARGS,
index fa047a813e29c383b5fab40e1cdc1bddad580359..cabae4eaf1f5e71f29e24fa5d5e43f5b58bab538 100644 (file)
@@ -368,6 +368,8 @@ fault_setup = _glue.fault_setup
 set_debug_level = _glue.set_debug_level
 get_debug_level = _glue.get_debug_level
 unix2nttime = _glue.unix2nttime
+float2nttime = _glue.float2nttime
+nttime2float = _glue.nttime2float
 nttime2string = _glue.nttime2string
 nttime2unix = _glue.nttime2unix
 unix2nttime = _glue.unix2nttime
index 5f112f00ba07583a6a9aa863590ec80318a2132b..e5d76c5a02a295a83788634dccc8784561195e52 100644 (file)
@@ -43,6 +43,25 @@ class GlueTests(samba.tests.TestCase):
     def test_nttime2unix(self):
         self.assertEqual(_glue.nttime2unix(116444736010000000), 1)
 
+    def test_float2nttime(self):
+        self.assertEqual(_glue.float2nttime(1.0), 116444736010000000)
+        self.assertEqual(_glue.float2nttime(1611058908.0), 132555325080000000)
+        # NTTIME has a resolution of 100ns
+        self.assertEqual(_glue.float2nttime(1611058908.1234567), 132555325081234567)
+        self.assertEqual(_glue.float2nttime(1611058908.123456789), 132555325081234567)
+
+    def test_nttime2float(self):
+        self.assertEqual(_glue.nttime2float(1), -11644473600.0)
+        self.assertEqual(_glue.nttime2float(0x7fffffffffffffff), 910692730085.4775)
+        self.assertEqual(_glue.nttime2float(0x8000000000000000), 910692730085.4775)
+        self.assertEqual(_glue.nttime2float(0xf000000000000000), 910692730085.4775)
+        self.assertEqual(_glue.nttime2float(116444736010000000), 1.0)
+        self.assertEqual(_glue.nttime2float(132555325080000000), 1611058908.0)
+        self.assertEqual(_glue.nttime2float(132555325081234567), 1611058908.1234567)
+        # NTTIME_OMIT (0) and NTTIME_FREEZE (UINT64_MAX) map to SAMBA_UTIME_OMIT (1)
+        self.assertEqual(_glue.nttime2float(0), 1.0)
+        self.assertEqual(_glue.nttime2float(0xffffffffffffffff), 1.0)
+
     def test_nttime2string(self):
         string = _glue.nttime2string(116444736010000000)
         self.assertEqual(type(string), str)