Vault  4.1
vinstant_platform.cpp
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 

Copyright ©1997-2014 Trygve Isaacson. All rights reserved. This documentation was generated with Doxygen.