diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp index cdcf4ef2b..413d19f8e 100644 --- a/src/libCom/osi/epicsTime.cpp +++ b/src/libCom/osi/epicsTime.cpp @@ -418,6 +418,104 @@ epicsTime::epicsTime (const aitTimeStamp &ts) *this = epicsTime (this->secPastEpoch+secAdj, this->nSec+nSecAdj); } +static const FILETIME epicsEpochInFileTime = { 0x18d64000, 0x01b41e2a }; + +static inline bool fileTimeGreaterThanOrEqual ( const FILETIME & lhs, const FILETIME & rhs ) +{ + if ( lhs.dwHighDateTime > rhs.dwHighDateTime ) { + return true; + } + else if ( lhs.dwHighDateTime < rhs.dwHighDateTime ) { + return false; + } + else if ( lhs.dwLowDateTime >= rhs.dwLowDateTime ) { + return true; + } + return false; +} + +epicsTime::operator _FILETIME () const +{ + static const DWORD dwordMax = 0xffffffff; + static const double ticksPerLowWord = + static_cast < double > ( dwordMax ) + 1; + static const double ftNanoSecPerTick = 100; + static const double ftTicksPerSec = 1e7; + + // compute the ticks past the epics epoch in file time ticks + double ftTicks = this->secPastEpoch * ftTicksPerSec + this->nSec / ftNanoSecPerTick; + FILETIME ftTicksPastEpicsEpoch; + ftTicksPastEpicsEpoch.dwHighDateTime = static_cast < DWORD > ( ftTicks / ticksPerLowWord ); + double lowPart = ftTicks - ftTicksPastEpicsEpoch.dwHighDateTime * ticksPerLowWord; + ftTicksPastEpicsEpoch.dwLowDateTime = static_cast < DWORD > ( lowPart ); + + // add the EPICS epoch offset + FILETIME result; + result.dwHighDateTime = + epicsEpochInFileTime.dwHighDateTime + ftTicksPastEpicsEpoch.dwHighDateTime; + if ( epicsEpochInFileTime.dwLowDateTime > dwordMax - ftTicksPastEpicsEpoch.dwLowDateTime ) { + // carry + result.dwHighDateTime++; + double tmp = epicsEpochInFileTime.dwLowDateTime; + tmp += ftTicksPastEpicsEpoch.dwLowDateTime; + result.dwLowDateTime = static_cast < DWORD > ( tmp - dwordMax ); + } + else { + result.dwLowDateTime = + epicsEpochInFileTime.dwLowDateTime + ftTicksPastEpicsEpoch.dwLowDateTime; + } + return result; +} + +epicsTime::epicsTime ( const _FILETIME & ts ) +{ + static const DWORD dwordMax = 0xffffffff; + + if ( fileTimeGreaterThanOrEqual ( ts , epicsEpochInFileTime ) ) { + // remove epics epoch offset from the incoming file time + FILETIME ftTicksPastEpicsEpoch; + ftTicksPastEpicsEpoch.dwHighDateTime = + ts.dwHighDateTime - epicsEpochInFileTime.dwHighDateTime; + if ( ts.dwLowDateTime >= epicsEpochInFileTime.dwLowDateTime ) { + ftTicksPastEpicsEpoch.dwLowDateTime = + ts.dwLowDateTime - epicsEpochInFileTime.dwLowDateTime; + } + else { + // borrow + ftTicksPastEpicsEpoch.dwHighDateTime--; + ftTicksPastEpicsEpoch.dwLowDateTime = + ( dwordMax - epicsEpochInFileTime.dwLowDateTime ) + + ts.dwLowDateTime + 1; + } + + // adjust between file time ticks and EPICS time ticks + static const double ticksPerLowWord = + static_cast < double > ( dwordMax ) + 1; + static const double ftTicksPerSec = 1e7; + static const double epicsTicksPerSec = 1e9; + double ftTicksPastEpicsEpochFP = + ticksPerLowWord * ftTicksPastEpicsEpoch.dwHighDateTime + + ftTicksPastEpicsEpoch.dwLowDateTime; + double epicsTicksPastEpicsEpoch = ftTicksPastEpicsEpochFP * + ( epicsTicksPerSec / ftTicksPerSec ); + this->secPastEpoch = static_cast < unsigned long > + ( epicsTicksPastEpicsEpoch / nSecPerSec ); + double nSec = epicsTicksPastEpicsEpoch - + this->secPastEpoch * epicsTime::nSecPerSec; + this->nSec = static_cast < unsigned long > ( nSec ); + } + else { + this->secPastEpoch = 0; + this->nSec = 0; + } +} + +epicsTime & epicsTime::operator = ( const _FILETIME & rhs ) +{ + *this = epicsTime ( rhs ); + return *this; +} + // // epicsTime::ntpTimeStamp () // diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h index fdae6f53b..7f5bcb7c9 100644 --- a/src/libCom/osi/epicsTime.h +++ b/src/libCom/osi/epicsTime.h @@ -86,26 +86,26 @@ public: class formatProblemWithStructTM {}; epicsTime (); - epicsTime (const epicsTime &t); + epicsTime ( const epicsTime & t ); - static epicsTime getEvent (const epicsTimeEvent &event); + static epicsTime getEvent ( const epicsTimeEvent & ); static epicsTime getCurrent (); // convert to and from EPICS epicsTimeStamp format operator epicsTimeStamp () const; - epicsTime (const epicsTimeStamp &ts); - epicsTime operator = (const epicsTimeStamp &rhs); + epicsTime ( const epicsTimeStamp & ts ); + epicsTime & operator = ( const epicsTimeStamp & ); // convert to and from ANSI time_t operator time_t_wrapper () const; - epicsTime (const time_t_wrapper &tv); - epicsTime operator = (const time_t_wrapper &rhs); + epicsTime ( const time_t_wrapper & ); + epicsTime & operator = ( const time_t_wrapper & ); // convert to and from ANSI Cs "struct tm" (with nano seconds) // adjusted for the local time zone operator local_tm_nano_sec () const; - epicsTime (const local_tm_nano_sec &ts); - epicsTime operator = (const local_tm_nano_sec &rhs); + epicsTime ( const local_tm_nano_sec & ); + epicsTime & operator = ( const local_tm_nano_sec & ); // convert to ANSI Cs "struct tm" (with nano seconds) // adjusted for GM time (UTC) @@ -113,44 +113,49 @@ public: // convert to and from POSIX RTs "struct timespec" operator struct timespec () const; - epicsTime (const struct timespec &ts); - epicsTime operator = (const struct timespec &rhs); + epicsTime ( const struct timespec & ); + epicsTime & operator = ( const struct timespec & ); // convert to and from BSDs "struct timeval" operator struct timeval () const; - epicsTime (const struct timeval &ts); - epicsTime operator = (const struct timeval &rhs); + epicsTime ( const struct timeval & ); + epicsTime & operator = ( const struct timeval & ); // convert to and from NTP timestamp format operator ntpTimeStamp () const; - epicsTime (const ntpTimeStamp &ts); - epicsTime operator = (const ntpTimeStamp &rhs); + epicsTime ( const ntpTimeStamp & ); + epicsTime & operator = ( const ntpTimeStamp & ); // convert to and from GDDs aitTimeStamp format operator aitTimeStamp () const; - epicsTime (const aitTimeStamp &ts); - epicsTime operator = (const aitTimeStamp &rhs); + epicsTime ( const aitTimeStamp & ); + epicsTime & operator = ( const aitTimeStamp & ); + + // convert to and from WIN32s FILETIME + operator struct _FILETIME () const; + epicsTime ( const struct _FILETIME & ); + epicsTime & operator = ( const struct _FILETIME & ); // arithmetic operators - double operator- (const epicsTime &rhs) const; // returns seconds - epicsTime operator+ (const double &rhs) const; // add rhs seconds - epicsTime operator- (const double &rhs) const; // subtract rhs seconds - epicsTime operator+= (const double &rhs); // add rhs seconds - epicsTime operator-= (const double &rhs); // subtract rhs seconds + double operator- ( const epicsTime & ) const; // returns seconds + epicsTime operator+ ( const double & ) const; // add rhs seconds + epicsTime operator- ( const double & ) const; // subtract rhs seconds + epicsTime operator+= ( const double & ); // add rhs seconds + epicsTime operator-= ( const double & ); // subtract rhs seconds // comparison operators - bool operator == (const epicsTime &rhs) const; - bool operator != (const epicsTime &rhs) const; - bool operator <= (const epicsTime &rhs) const; - bool operator < (const epicsTime &rhs) const; - bool operator >= (const epicsTime &rhs) const; - bool operator > (const epicsTime &rhs) const; + bool operator == ( const epicsTime & ) const; + bool operator != ( const epicsTime & ) const; + bool operator <= ( const epicsTime & ) const; + bool operator < ( const epicsTime & ) const; + bool operator >= ( const epicsTime & ) const; + bool operator > ( const epicsTime & ) const; // convert current state to user-specified string - size_t strftime (char *pBuff, size_t bufLength, const char *pFormat) const; + size_t strftime ( char * pBuff, size_t bufLength, const char * pFormat ) const; // dump current state to standard out - void show (unsigned interestLevel) const; + void show ( unsigned interestLevel ) const; // useful public constants static const unsigned secPerMin; @@ -159,8 +164,6 @@ public: static const unsigned nSecPerSec; static const unsigned nSecPerUSec; - // depricated - static void synchronize (); private: // private because: // a) application does not break when EPICS epoch is changed @@ -169,11 +172,14 @@ private: // c) it would be easy to forget which argument is nanoseconds // and which argument is seconds (no help from compiler) // - epicsTime (const unsigned long secPastEpoch, const unsigned long nSec); - void addNanoSec (long nanoSecAdjust); + epicsTime ( const unsigned long secPastEpoch, const unsigned long nSec ); + void addNanoSec ( long nanoSecAdjust ); unsigned long secPastEpoch; // seconds since O000 Jan 1, 1990 unsigned long nSec; // nanoseconds within second + +public: + static void synchronize (); // depricated }; extern "C" { @@ -189,68 +195,68 @@ extern "C" { #define epicsTimeEventDeviceTime -2 /* convert to and from ANSI C's "time_t" */ -epicsShareFunc int epicsShareAPI epicsTimeGetCurrent (epicsTimeStamp *pDest); +epicsShareFunc int epicsShareAPI epicsTimeGetCurrent ( epicsTimeStamp * pDest ); epicsShareFunc int epicsShareAPI epicsTimeGetEvent ( epicsTimeStamp *pDest, int eventNumber); /* convert to and from ANSI C's "struct tm" with nano second */ epicsShareFunc int epicsShareAPI epicsTimeToTime_t ( - time_t *pDest, const epicsTimeStamp *pSrc); + time_t * pDest, const epicsTimeStamp * pSrc ); epicsShareFunc int epicsShareAPI epicsTimeFromTime_t ( - epicsTimeStamp *pDest, time_t src); + epicsTimeStamp * pDest, time_t src ); /*convert to and from ANSI C's "struct tm" with nano seconds */ epicsShareFunc int epicsShareAPI epicsTimeToTM ( - struct tm *pDest, unsigned long *pNSecDest, const epicsTimeStamp *pSrc); + struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc ); epicsShareFunc int epicsShareAPI epicsTimeToGMTM ( - struct tm *pDest, unsigned long *pNSecDest, const epicsTimeStamp *pSrc); + struct tm * pDest, unsigned long * pNSecDest, const epicsTimeStamp * pSrc ); epicsShareFunc int epicsShareAPI epicsTimeFromTM ( - epicsTimeStamp *pDest, const struct tm *pSrc, unsigned long nSecSrc); + epicsTimeStamp * pDest, const struct tm * pSrc, unsigned long nSecSrc ); /* convert to and from POSIX RT's "struct timespec" */ epicsShareFunc int epicsShareAPI epicsTimeToTimespec ( - struct timespec *pDest, const epicsTimeStamp *pSrc); + struct timespec * pDest, const epicsTimeStamp * pSrc ); epicsShareFunc int epicsShareAPI epicsTimeFromTimespec ( - epicsTimeStamp *pDest, const struct timespec *pSrc); + epicsTimeStamp * pDest, const struct timespec * pSrc ); /* convert to and from BSD's "struct timeval" */ epicsShareFunc int epicsShareAPI epicsTimeToTimeval ( - struct timeval *pDest, const epicsTimeStamp *pSrc); + struct timeval * pDest, const epicsTimeStamp * pSrc ); epicsShareFunc int epicsShareAPI epicsTimeFromTimeval ( - epicsTimeStamp *pDest, const struct timeval *pSrc); + epicsTimeStamp * pDest, const struct timeval * pSrc ); /*arithmetic operations */ epicsShareFunc double epicsShareAPI epicsTimeDiffInSeconds ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight);/* left - right */ + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight );/* left - right */ epicsShareFunc void epicsShareAPI epicsTimeAddSeconds ( - epicsTimeStamp *pDest, double secondsToAdd); /* adds seconds to *pDest */ + epicsTimeStamp * pDest, double secondsToAdd ); /* adds seconds to *pDest */ /*comparison operations: returns (0,1) if (false,true) */ epicsShareFunc int epicsShareAPI epicsTimeEqual ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight); + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); epicsShareFunc int epicsShareAPI epicsTimeNotEqual ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight); + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); epicsShareFunc int epicsShareAPI epicsTimeLessThan ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight); /*true if left < right */ + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left < right */ epicsShareFunc int epicsShareAPI epicsTimeLessThanEqual ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight); /*true if left <= right) */ + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left <= right) */ epicsShareFunc int epicsShareAPI epicsTimeGreaterThan ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight); /*true if left < right */ + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left < right */ epicsShareFunc int epicsShareAPI epicsTimeGreaterThanEqual ( - const epicsTimeStamp *pLeft, const epicsTimeStamp *pRight); /*true if left < right */ + const epicsTimeStamp * pLeft, const epicsTimeStamp * pRight); /*true if left < right */ /*convert to ASCII string */ epicsShareFunc size_t epicsShareAPI epicsTimeToStrftime ( - char *pBuff, size_t bufLength, const char *pFormat, const epicsTimeStamp *pTS); + char * pBuff, size_t bufLength, const char * pFormat, const epicsTimeStamp * pTS ); /* dump current state to standard out */ epicsShareFunc void epicsShareAPI epicsTimeShow ( - const epicsTimeStamp *, unsigned interestLevel); + const epicsTimeStamp *, unsigned interestLevel ); /* OS dependent reentrant versions of the ANSI C interface because */ /* vxWorks gmtime_r interface does not match POSIX standards */ -int epicsTime_localtime ( const time_t *clock, struct tm *result ); -int epicsTime_gmtime ( const time_t *clock, struct tm *result ); +int epicsTime_localtime ( const time_t * clock, struct tm * result ); +int epicsTime_gmtime ( const time_t * clock, struct tm * result ); #ifdef __cplusplus } @@ -259,66 +265,66 @@ int epicsTime_gmtime ( const time_t *clock, struct tm *result ); /* epicsTime inline member functions ,*/ #ifdef __cplusplus -inline epicsTime epicsTime::operator - (const double &rhs) const +inline epicsTime epicsTime::operator - ( const double & rhs ) const { - return epicsTime::operator + (-rhs); + return epicsTime::operator + ( -rhs ); } -inline epicsTime epicsTime::operator += (const double &rhs) +inline epicsTime epicsTime::operator += ( const double & rhs ) { - *this = epicsTime::operator + (rhs); + *this = epicsTime::operator + ( rhs ); return *this; } -inline epicsTime epicsTime::operator -= (const double &rhs) +inline epicsTime epicsTime::operator -= ( const double & rhs ) { - *this = epicsTime::operator + (-rhs); + *this = epicsTime::operator + ( -rhs ); return *this; } -inline bool epicsTime::operator == (const epicsTime &rhs) const +inline bool epicsTime::operator == ( const epicsTime & rhs ) const { - if (this->secPastEpoch == rhs.secPastEpoch && this->nSec == rhs.nSec) { + if ( this->secPastEpoch == rhs.secPastEpoch && this->nSec == rhs.nSec ) { return true; } return false; } -inline bool epicsTime::operator != (const epicsTime &rhs) const +inline bool epicsTime::operator != ( const epicsTime & rhs ) const { - return !epicsTime::operator == (rhs); + return !epicsTime::operator == ( rhs ); } -inline bool epicsTime::operator >= (const epicsTime &rhs) const +inline bool epicsTime::operator >= ( const epicsTime & rhs ) const { return ! ( *this < rhs ); } -inline bool epicsTime::operator > (const epicsTime &rhs) const +inline bool epicsTime::operator > ( const epicsTime & rhs ) const { return ! ( *this <= rhs ); } -inline epicsTime epicsTime::operator = (const local_tm_nano_sec &rhs) +inline epicsTime & epicsTime::operator = ( const local_tm_nano_sec & rhs ) { - return *this = epicsTime (rhs); + return *this = epicsTime ( rhs ); } -inline epicsTime epicsTime::operator = (const struct timespec &rhs) +inline epicsTime & epicsTime::operator = ( const struct timespec & rhs ) { - *this = epicsTime (rhs); + *this = epicsTime ( rhs ); return *this; } -inline epicsTime epicsTime::operator = (const aitTimeStamp &rhs) +inline epicsTime & epicsTime::operator = ( const aitTimeStamp & rhs ) { - *this = epicsTime (rhs); + *this = epicsTime ( rhs ); return *this; } -inline epicsTime epicsTime::operator = (const epicsTimeStamp &rhs) +inline epicsTime & epicsTime::operator = ( const epicsTimeStamp & rhs ) { - *this = epicsTime (rhs); + *this = epicsTime ( rhs ); return *this; } @@ -331,16 +337,16 @@ inline epicsTime::operator epicsTimeStamp () const } #ifdef NTP_SUPPORT -inline epicsTime epicsTime::operator = (const ntpTimeStamp &rhs) +inline epicsTime epicsTime::operator = ( const ntpTimeStamp & rhs ) { *this = epicsTime (rhs); return *this; } #endif -inline epicsTime epicsTime::operator = (const time_t_wrapper &rhs) +inline epicsTime & epicsTime::operator = ( const time_t_wrapper & rhs ) { - *this = epicsTime (rhs); + *this = epicsTime ( rhs ); return *this; } #endif /* __cplusplus */ diff --git a/src/libCom/osi/os/Linux/osdTime.h b/src/libCom/osi/os/Linux/osdTime.h index 4c8bd2592..f01ab5a5f 100644 --- a/src/libCom/osi/os/Linux/osdTime.h +++ b/src/libCom/osi/os/Linux/osdTime.h @@ -19,5 +19,14 @@ * causes `struct timespec' to be defined in more than one place. */ +#include + +/* from win32 */ +typedef uint32_t DWORD; +typedef struct _FILETIME { + DWORD dwLowDateTime; /* low 32 bits */ + DWORD dwHighDateTime; /* high 32 bits */ +} FILETIME; + #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/RTEMS/osdTime.h b/src/libCom/osi/os/RTEMS/osdTime.h index 1158f80d0..0045a5b12 100644 --- a/src/libCom/osi/os/RTEMS/osdTime.h +++ b/src/libCom/osi/os/RTEMS/osdTime.h @@ -11,12 +11,18 @@ /* * $Id$ * - * Author: Jeff Hill */ #ifndef osdTimeh #define osdTimeh -/* NOOP */ +#include + +/* from win32 */ +typedef uint32_t DWORD; +typedef struct _FILETIME { + DWORD dwLowDateTime; /* low 32 bits */ + DWORD dwHighDateTime; /* high 32 bits */ +} FILETIME; #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/VMS/osdTime.h b/src/libCom/osi/os/VMS/osdTime.h index dc6b0c453..bdf7a64e1 100644 --- a/src/libCom/osi/os/VMS/osdTime.h +++ b/src/libCom/osi/os/VMS/osdTime.h @@ -17,6 +17,8 @@ #ifndef osdTimeh #define osdTimeh +#include + /* * I assume that this is never defined on VMS ? */ @@ -25,4 +27,11 @@ struct timespec { long tv_nsec; /* nanoseconds within the second */ }; +/* from win32 */ +typedef uint32_t DWORD; +typedef struct _FILETIME { + DWORD dwLowDateTime; /* low 32 bits */ + DWORD dwHighDateTime; /* high 32 bits */ +} FILETIME; + #endif /* ifndef osdTimeh */ \ No newline at end of file diff --git a/src/libCom/osi/os/WIN32/osdSock.h b/src/libCom/osi/os/WIN32/osdSock.h index a95656d6f..9fb4f5671 100644 --- a/src/libCom/osi/os/WIN32/osdSock.h +++ b/src/libCom/osi/os/WIN32/osdSock.h @@ -16,12 +16,6 @@ extern "C" { #include #include -#ifndef VC_EXTRALEAN -# define VC_EXTRALEAN -#endif -#ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -#endif #include #ifdef __cplusplus diff --git a/src/libCom/osi/os/WIN32/osdTime.h b/src/libCom/osi/os/WIN32/osdTime.h index c9594b23c..7ce9905a5 100644 --- a/src/libCom/osi/os/WIN32/osdTime.h +++ b/src/libCom/osi/os/WIN32/osdTime.h @@ -17,6 +17,8 @@ #ifndef osdTimeh #define osdTimeh +#include + struct timespec { time_t tv_sec; /* seconds since some epoch */ long tv_nsec; /* nanoseconds within the second */ diff --git a/src/libCom/osi/os/posix/osdTime.h b/src/libCom/osi/os/posix/osdTime.h index d1334abc4..a4f933ff2 100644 --- a/src/libCom/osi/os/posix/osdTime.h +++ b/src/libCom/osi/os/posix/osdTime.h @@ -34,5 +34,12 @@ epicsShareFunc void epicsShareAPI } #endif /* __cplusplus */ +/* from win32 */ +typedef uint32_t DWORD; +typedef struct _FILETIME { + DWORD dwLowDateTime; /* low 32 bits */ + DWORD dwHighDateTime; /* high 32 bits */ +} FILETIME; + #endif /* ifndef osdTimeh */ diff --git a/src/libCom/osi/os/vxWorks/osdTime.h b/src/libCom/osi/os/vxWorks/osdTime.h index aa303bbc1..e5b39f19a 100644 --- a/src/libCom/osi/os/vxWorks/osdTime.h +++ b/src/libCom/osi/os/vxWorks/osdTime.h @@ -9,3 +9,10 @@ \*************************************************************************/ /* Following needed for struct timeval */ #include + +/* from win32 */ +typedef uint32_t DWORD; +typedef struct _FILETIME { + DWORD dwLowDateTime; /* low 32 bits */ + DWORD dwHighDateTime; /* high 32 bits */ +} FILETIME;