Author: jra
Date: 2006-08-24 01:31:00 +0000 (Thu, 24 Aug 2006)
New Revision: 17766

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=17766

Log:
Getting ready to properly expose 100ns times on
the wire. Move the internals of nt_time functions
to use struct timespecs.
Jeremy.

Modified:
   branches/SAMBA_3_0/source/lib/time.c


Changeset:
Modified: branches/SAMBA_3_0/source/lib/time.c
===================================================================
--- branches/SAMBA_3_0/source/lib/time.c        2006-08-24 01:03:42 UTC (rev 
17765)
+++ branches/SAMBA_3_0/source/lib/time.c        2006-08-24 01:31:00 UTC (rev 
17766)
@@ -178,22 +178,28 @@
  Interpret an 8 byte "filetime" structure to a time_t
  It's originally in "100ns units since jan 1st 1601"
 
- An 8 byte value of 0xffffffffffffffff will be returned as (time_t)0.
+ An 8 byte value of 0xffffffffffffffff will be returned as a timespec of
 
+       tv_sec = 0
+       tv_nsec = 0;
+
  Returns GMT.
 ****************************************************************************/
 
-time_t nt_time_to_unix(NTTIME *nt)
+struct timespec nt_time_to_unix_timespec(NTTIME *nt)
 {
        double d;
-       time_t ret;
+       struct timespec ret;
        /* The next two lines are a fix needed for the 
                broken SCO compiler. JRA. */
        time_t l_time_min = TIME_T_MIN;
        time_t l_time_max = TIME_T_MAX;
 
-       if (nt->high == 0 || (nt->high == 0xffffffff && nt->low == 0xffffffff)) 
{
-               return(0);
+       if ((nt->high == 0 && nt->low == 0 )||
+                       (nt->high == 0xffffffff && nt->low == 0xffffffff)) {
+               ret.tv_sec = 0;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
        d = ((double)nt->high)*4.0*(double)(1<<30);
@@ -204,17 +210,28 @@
        d -= TIME_FIXUP_CONSTANT;
 
        if (d <= l_time_min) {
-               return (l_time_min);
+               ret.tv_sec = l_time_min;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
        if (d >= l_time_max) {
-               return (l_time_max);
+               ret.tv_sec = l_time_max;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
-       ret = (time_t)(d+0.5);
-       return(ret);
+       ret.tv_sec = (time_t)d;
+       ret.tv_nsec = (long) ((d*1.0e9) - ((double)ret.tv_sec)*1.0e9);
+       return ret;
 }
 
+time_t nt_time_to_unix(NTTIME *nt)
+{
+       struct timespec ts = nt_time_to_unix_timespec(nt);
+       return ts.tv_sec;
+}
+
 /****************************************************************************
  Convert a NTTIME structure to a time_t.
  It's originally in "100ns units".
@@ -224,10 +241,10 @@
  if the NTTIME was 5 seconds, the time_t is 5 seconds. JFM
 ****************************************************************************/
 
-time_t nt_time_to_unix_abs(const NTTIME *nt)
+struct timespec nt_time_to_unix_abs(const NTTIME *nt)
 {
        double d;
-       time_t ret;
+       struct timespec ret;
        /* The next two lines are a fix needed for the 
           broken SCO compiler. JRA. */
        time_t l_time_min = TIME_T_MIN;
@@ -235,11 +252,15 @@
        NTTIME neg_nt;
 
        if (nt->high == 0) {
-               return(0);
+               ret.tv_sec = 0;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
        if (nt->high==0x80000000 && nt->low==0) {
-               return (time_t)-1;
+               ret.tv_sec = (time_t)-1;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
        /* reverse the time */
@@ -252,64 +273,82 @@
        d *= 1.0e-7;
   
        if (!(l_time_min <= d && d <= l_time_max)) {
-               return(0);
+               ret.tv_sec = 0;
+               ret.tv_nsec = 0;
+               return ret;
        }
 
-       ret = (time_t)(d+0.5);
-
-       return(ret);
+       ret.tv_sec = (time_t)d;
+       ret.tv_nsec = (long) ((d*1.0e9) - ((double)ret.tv_sec)*1.0e9);
+       return ret;
 }
 
 /****************************************************************************
- Interprets an nt time into a unix time_t.
+ Interprets an nt time into a unix struct timespec.
  Differs from nt_time_to_unix in that an 8 byte value of 0xffffffffffffffff
  will be returned as (time_t)-1, whereas nt_time_to_unix returns 0 in this 
case.
 ****************************************************************************/
 
-time_t interpret_long_date(char *p)
+struct timespec interpret_long_date(char *p)
 {
        NTTIME nt;
        nt.low = IVAL(p,0);
        nt.high = IVAL(p,4);
        if (nt.low == 0xFFFFFFFF && nt.high == 0xFFFFFFFF) {
-               return (time_t)-1;
+               struct timespec ret;
+               ret.tv_sec = (time_t)-1;
+               ret.tv_nsec = 0;
+               return ret;
        }
-       return nt_time_to_unix(&nt);
+       return nt_time_to_unix_timespec(&nt);
 }
 
 /****************************************************************************
- Put a 8 byte filetime from a time_t. Uses GMT.
+ Put a 8 byte filetime from a struct timespec. Uses GMT.
 ****************************************************************************/
 
-void unix_to_nt_time(NTTIME *nt, time_t t)
+void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts)
 {
        double d;
 
-       if (t==0) {
+       if (ts.tv_sec ==0 && ts.tv_nsec == 0) {
                nt->low = 0;
                nt->high = 0;
                return;
        }
-       if (t == TIME_T_MAX) {
+       if (ts.tv_sec == TIME_T_MAX) {
                nt->low = 0xffffffff;
                nt->high = 0x7fffffff;
                return;
        }               
-       if (t == (time_t)-1) {
+       if (ts.tv_sec == (time_t)-1) {
                nt->low = 0xffffffff;
                nt->high = 0xffffffff;
                return;
        }               
 
-       d = (double)(t);
+       d = (double)(ts.tv_sec);
        d += TIME_FIXUP_CONSTANT;
        d *= 1.0e7;
+       d += ((double)ts.tv_nsec / 100.0);
 
        nt->high = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
        nt->low  = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
 }
 
 /****************************************************************************
+ Put a 8 byte filetime from a time_t. Uses GMT.
+****************************************************************************/
+
+void unix_to_nt_time(NTTIME *nt, time_t t)
+{
+       struct timespec ts;
+       ts.tv_sec = t;
+       ts.tv_nsec = 0;
+       unix_timespec_to_nt_time(nt, ts);
+}
+
+/****************************************************************************
  Convert a time_t to a NTTIME structure
 
  This is an absolute version of the one above.
@@ -356,10 +395,10 @@
  pointed to by p.
 ****************************************************************************/
 
-void put_long_date(char *p, time_t t)
+void put_long_date(char *p, struct timespec ts)
 {
        NTTIME nt;
-       unix_to_nt_time(&nt, t);
+       unix_timespec_to_nt_time(&nt, ts);
        SIVAL(p, 0, nt.low);
        SIVAL(p, 4, nt.high);
 }

Reply via email to