/* KInterbasDB Python Package - Time Functions
 *
 * Version 3.3
 *
 * The following contributors hold Copyright (C) over their respective
 * portions of code (see license.txt for details):
 *
 * [Original Author (maintained through version 2.0-0.3.1):]
 *   1998-2001 [alex]  Alexander Kuznetsov   <alexan@users.sourceforge.net>
 * [Maintainers (after version 2.0-0.3.1):]
 *   2001-2002 [maz]   Marek Isalski         <kinterbasdb@maz.nu>
 *   2002-2007 [dsr]   David Rushby          <woodsplitter@rocketmail.com>
 * [Contributors:]
 *   2001      [eac]   Evgeny A. Cherkashin  <eugeneai@icc.ru>
 *   2001-2002 [janez] Janez Jere            <janez.jere@void.si>            */

#ifdef ENABLE_CONNECTION_TIMEOUT
static LONG_LONG time_millis(void) {
  #ifdef PLATFORM_WINDOWS
    struct _timeb tstruct;
    _ftime(&tstruct); /* _ftime doesn't return an error code */

    return (((LONG_LONG) tstruct.time) * 1000) + tstruct.millitm;
  #else
    struct timeval tstruct;
    gettimeofday(&tstruct, NULL);

    return (
          (((LONG_LONG) tstruct.tv_sec ) * 1000)
        + (((LONG_LONG) tstruct.tv_usec) / 1000)
      );
  #endif
} /* time_millis */
#endif /* ENABLE_CONNECTION_TIMEOUT */

static LONG_LONG py_seconds_to_milliseconds(PyObject *py_secs,
    PyObject *exc_type, char *err_template,
    LONG_LONG min, LONG_LONG max
  )
{
  LONG_LONG millis;

  if (py_secs == NULL) {
    goto fail;
  } else if (PyFloat_Check(py_secs)) {
    millis = (LONG_LONG) (PyFloat_AS_DOUBLE(py_secs) * 1000.0);
  } else if (PyInt_Check(py_secs)) {
    millis = PyInt_AS_LONG(py_secs) * 1000;
  } else if (PyLong_Check(py_secs)) {
    millis = PyLong_AsLongLong(py_secs);
    if (   PyErr_Occurred()
        || millis > LONG_LONG_MAX / 1000
        || millis < LONG_LONG_MIN / 1000
       )
    { goto fail; } /* overflow */
    millis *= 1000;
  } else {
    goto fail;
  }

  if (millis < min || millis > max) { goto fail; }

  return millis;

  fail:
    if (!PyErr_Occurred()) {
      PyObject *py_secs_repr =
            py_secs == NULL
          ? PyString_FromString("<NULL>")
          : PyObject_Repr(py_secs)
        ;
      if (py_secs_repr != NULL) {
        PyObject *err_msg = PyString_FromFormat(err_template,
            PyString_AS_STRING(py_secs_repr)
          );
        if (err_msg != NULL) {
          raise_exception(exc_type, PyString_AS_STRING(err_msg));
          Py_DECREF(err_msg);
        }
        Py_DECREF(py_secs_repr);
      }
    }
    assert (PyErr_Occurred());
    return 0; /* The return value is not an error code! */
} /* py_seconds_to_milliseconds */
