Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #include "vinstant.h" 00009 #include "vtypes_internal.h" 00010 #include "vexception.h" 00011 00012 /* 00013 These are the platform-specific implementations of these required 00014 core time functions. 00015 */ 00016 00017 #define INSTANT_STRUCT_FORMAT "%d-%02d-%02d %02d:%02d:%02d.%03d" 00018 00019 // static 00020 Vs64 VInstantStruct::_platform_offsetFromLocalStruct(const VInstantStruct& when) { 00021 struct tm fields; 00022 00023 when.getTmStruct(fields); 00024 00025 //lint -e421 "Caution -- function 'mktime(struct tm *)' is considered dangerous [MISRA Rule 127]" 00026 Vs64 mktimeSeconds = static_cast<Vs64>( 00027 #ifdef VCOMPILER_MSVC 00028 ::_mktime64(&fields)); 00029 #else 00030 ::mktime(&fields)); 00031 #endif 00032 00033 if (mktimeSeconds == CONST_S64(-1)) { 00034 throw VStackTraceException(VSTRING_FORMAT("VInstantStruct::_platform_offsetFromLocalStruct: time value '" INSTANT_STRUCT_FORMAT "' is out of range.", 00035 when.mYear, when.mMonth, when.mDay, when.mHour, when.mMinute, when.mSecond, when.mMillisecond)); 00036 } 00037 00038 Vs64 resultOffsetMilliseconds = CONST_S64(1000) * mktimeSeconds; 00039 00040 // tm struct has no milliseconds, so restore input value milliseconds 00041 resultOffsetMilliseconds += (Vs64) when.mMillisecond; 00042 00043 return resultOffsetMilliseconds; 00044 } 00045 00046 // static 00047 void VInstantStruct::_platform_offsetToLocalStruct(Vs64 offset, VInstantStruct& when) { 00048 struct tm fields; 00049 ::memset(&fields, 0, sizeof(fields)); 00050 00051 VInstantStruct::_threadsafe_localtime(static_cast<time_t>(offset / 1000), &fields); 00052 00053 when.setFromTmStruct(fields, (int)(offset % 1000)); 00054 } 00055 00056 // static 00057 void VInstantStruct::_platform_offsetToUTCStruct(Vs64 offset, VInstantStruct& when) { 00058 struct tm fields; 00059 ::memset(&fields, 0, sizeof(fields)); 00060 00061 VInstantStruct::_threadsafe_gmtime(static_cast<time_t>(offset / 1000), &fields); 00062 00063 when.setFromTmStruct(fields, (int)(offset % 1000)); 00064 } 00065 00066 // static 00067 Vs64 VInstant::_platform_now() { 00068 #ifdef V_INSTANT_SNAPSHOT_IS_UTC 00069 00070 // This means we can get millisecond resolution for VInstant values. 00071 return VInstant::_platform_snapshot(); 00072 00073 #else 00074 00075 // This means we can only get second resolution for VInstant values. 00076 //lint -e418 -e421 "Passing null pointer to function 'time(long *)'" [OK: IEEE POSIX disagrees with lint. NULL is meaningful.] 00077 return (CONST_S64(1000) * static_cast<Vs64>(::time(NULL))); 00078 00079 #endif /* V_INSTANT_SNAPSHOT_IS_UTC */ 00080 } 00081 00082 #ifdef VCOMPILER_MSVC 00083 #include <sys/timeb.h> // required for _ftime64() 00084 00085 // static 00086 Vs64 VInstant::_platform_snapshot() { 00087 struct __timeb64 tb; 00088 ::_ftime64(&tb); 00089 00090 return (tb.time * 1000) + tb.millitm; 00091 } 00092 00093 #else 00094 00095 // static 00096 Vs64 VInstant::_platform_snapshot() { 00097 // The Windows _FILETIME structure holds a time value 00098 // with 100-ns resolution, so we can use that a snapshot 00099 // value that has the required millisecond resolution. 00100 // (Divide ns by 10,000 to get ms.) 00101 SYSTEMTIME st; 00102 GetSystemTime(&st); 00103 00104 _FILETIME ft; 00105 (void) SystemTimeToFileTime(&st, &ft); 00106 00107 Vs64 high32 = ft.dwHighDateTime; 00108 Vs64 low32 = ft.dwLowDateTime; 00109 Vs64 milliseconds = ((high32 << 32) | low32) / CONST_S64(10000); // 10000: ns to ms 00110 00111 return milliseconds; 00112 } 00113 00114 #endif 00115