[Libreoffice-commits] core.git: include/tools tools/inc tools/Library_tl.mk tools/source

Takeshi Abe tabe at fixedpoint.jp
Fri May 4 19:31:12 UTC 2018


 include/tools/datetime.hxx               |    2 
 tools/Library_tl.mk                      |    1 
 tools/inc/systemdatetime.hxx             |   26 +++++++
 tools/source/datetime/datetime.cxx       |   17 ++++
 tools/source/datetime/systemdatetime.cxx |  109 +++++++++++++++++++++++++++++++
 tools/source/datetime/tdate.cxx          |   35 ---------
 tools/source/datetime/ttime.cxx          |   85 +++++-------------------
 7 files changed, 175 insertions(+), 100 deletions(-)

New commits:
commit 5103c6a405e93bb05018ab7c89e7e9446c740aaa
Author: Takeshi Abe <tabe at fixedpoint.jp>
Date:   Sun Apr 29 05:20:47 2018 +0900

    tools: Avoid looking up system clock twice to get DateTime
    
    DateTime::DateTime(DateTimeInitSystem) had initialized Date and
    Time separately, which causes a slight possibility that it could
    get a wrong datetime with almost 24 hours delay when it went beyond
    midnight. E.g., the date part was of the previous day while the
    time part was 00:00:00.xxx of the next day.
    
    This also reduces duplicate code by sharing GetSystemDateTime().
    
    Change-Id: I352d90f468f5cbc70e7936a337bed97365baa06c
    Reviewed-on: https://gerrit.libreoffice.org/53612
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/include/tools/datetime.hxx b/include/tools/datetime.hxx
index 02729e6a0e1a..7b78b29bdfc5 100644
--- a/include/tools/datetime.hxx
+++ b/include/tools/datetime.hxx
@@ -40,7 +40,7 @@ public:
     };
 
                     explicit DateTime( DateTimeInitEmpty ) : Date( Date::EMPTY ), Time( Time::EMPTY ) {}
-                    explicit DateTime( DateTimeInitSystem ) : Date( Date::SYSTEM ), Time( Time::SYSTEM ) {}
+                    explicit DateTime( DateTimeInitSystem );
                     DateTime( const DateTime& rDateTime ) :
                         Date( rDateTime ), Time( rDateTime ) {}
                     DateTime( const Date& rDate ) : Date( rDate ), Time(0) {}
diff --git a/tools/Library_tl.mk b/tools/Library_tl.mk
index 2aee438fb2e9..c524a38084aa 100644
--- a/tools/Library_tl.mk
+++ b/tools/Library_tl.mk
@@ -44,6 +44,7 @@ $(eval $(call gb_Library_use_libraries,tl,\
 $(eval $(call gb_Library_add_exception_objects,tl,\
     tools/source/datetime/datetime \
     tools/source/datetime/datetimeutils \
+    tools/source/datetime/systemdatetime \
     tools/source/datetime/tdate \
     tools/source/datetime/ttime \
     tools/source/debug/debug \
diff --git a/tools/inc/systemdatetime.hxx b/tools/inc/systemdatetime.hxx
new file mode 100644
index 000000000000..cc74eae61340
--- /dev/null
+++ b/tools/inc/systemdatetime.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_TOOLS_INC_SYSTEMDATETIME_H
+#define INCLUDED_TOOLS_INC_SYSTEMDATETIME_H
+
+#include <sal/types.h>
+
+constexpr sal_Int64 SEC_MASK = SAL_CONST_INT64(1000000000);
+constexpr sal_Int64 MIN_MASK = SAL_CONST_INT64(100000000000);
+constexpr sal_Int64 HOUR_MASK = SAL_CONST_INT64(10000000000000);
+
+/** Get current local timestamp.
+    Both pDate and pTime can be null.
+    Returns true if succeeded, false otherwse.
+ */
+bool GetSystemDateTime(sal_Int32* pDate, sal_Int64* pTime);
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/tools/source/datetime/datetime.cxx b/tools/source/datetime/datetime.cxx
index e3faf45fa495..1dc2b79cb990 100644
--- a/tools/source/datetime/datetime.cxx
+++ b/tools/source/datetime/datetime.cxx
@@ -19,6 +19,23 @@
 #include <tools/datetime.hxx>
 #include <rtl/math.hxx>
 
+#include <systemdatetime.hxx>
+
+DateTime::DateTime(DateTimeInitSystem)
+    : Date( Date::EMPTY )
+    , Time( Time::EMPTY )
+{
+    sal_Int32 nD = 0;
+    sal_Int64 nT = 0;
+    if ( GetSystemDateTime( &nD, &nT ) )
+    {
+        Date::operator=( Date( nD ) );
+        SetTime( nT );
+    }
+    else
+        Date::operator=( Date( 1, 1, 1900 ) ); // Time::nTime is already 0
+}
+
 DateTime::DateTime( const css::util::DateTime& rDateTime )
   : Date( rDateTime.Day, rDateTime.Month, rDateTime.Year ),
     Time( rDateTime.Hours, rDateTime.Minutes, rDateTime.Seconds, rDateTime.NanoSeconds )
diff --git a/tools/source/datetime/systemdatetime.cxx b/tools/source/datetime/systemdatetime.cxx
new file mode 100644
index 000000000000..40e4edfd05c3
--- /dev/null
+++ b/tools/source/datetime/systemdatetime.cxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#if defined(_WIN32)
+#if !defined WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#elif defined UNX
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+#include <time.h>
+#ifdef __MACH__
+#include <mach/clock.h>
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#endif
+
+#include <rtl/math.hxx>
+#include <osl/diagnose.h>
+#include <systemdatetime.hxx>
+
+namespace
+{
+constexpr sal_Int32 ConvertYMDToInt(sal_Int32 nYear, sal_Int32 nMonth, sal_Int32 nDay)
+{
+    return (nYear * 10000) + (nMonth * 100) + nDay;
+}
+
+constexpr sal_Int64 ConvertHMSnToInt(sal_Int64 nHour, sal_Int64 nMin, sal_Int64 nSec,
+                                     sal_Int64 nNanoSec)
+{
+    return (nHour * HOUR_MASK) + (nMin * MIN_MASK) + (nSec * SEC_MASK) + nNanoSec;
+}
+}
+
+bool GetSystemDateTime(sal_Int32* pDate, sal_Int64* pTime)
+{
+#if defined(_WIN32)
+    SYSTEMTIME aDateTime;
+    GetLocalTime(&aDateTime);
+
+    if (pDate)
+        *pDate = ConvertYMDToInt(static_cast<sal_Int32>(aDateTime.wYear),
+                                 static_cast<sal_Int32>(aDateTime.wMonth),
+                                 static_cast<sal_Int32>(aDateTime.wDay));
+    if (pTime)
+        *pTime = ConvertHMSnToInt(aDateTime.wHour, aDateTime.wMinute, aDateTime.wSecond,
+                                  aDateTime.wMilliseconds * 1000000);
+
+    return true;
+#else
+    struct timespec tsTime;
+#if defined(__MACH__)
+    // OS X does not have clock_gettime, use clock_get_time
+    clock_serv_t cclock;
+    mach_timespec_t mts;
+    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
+    clock_get_time(cclock, &mts);
+    mach_port_deallocate(mach_task_self(), cclock);
+    tsTime.tv_sec = mts.tv_sec;
+    tsTime.tv_nsec = mts.tv_nsec;
+#else
+    // CLOCK_REALTIME should be supported
+    // on any modern Unix, but be extra cautious
+    if (clock_gettime(CLOCK_REALTIME, &tsTime) != 0)
+    {
+        struct timeval tvTime;
+        OSL_VERIFY(gettimeofday(&tvTime, nullptr) != 0);
+        tsTime.tv_sec = tvTime.tv_sec;
+        tsTime.tv_nsec = tvTime.tv_usec * 1000;
+    }
+#endif
+
+    struct tm aTime;
+    time_t nTmpTime = tsTime.tv_sec;
+    if (localtime_r(&nTmpTime, &aTime))
+    {
+        if (pDate)
+            *pDate = ConvertYMDToInt(static_cast<sal_Int32>(aTime.tm_year + 1900),
+                                     static_cast<sal_Int32>(aTime.tm_mon + 1),
+                                     static_cast<sal_Int32>(aTime.tm_mday));
+        if (pTime)
+            *pTime = ConvertHMSnToInt(aTime.tm_hour, aTime.tm_min, aTime.tm_sec, tsTime.tv_nsec);
+        return true;
+    }
+
+    return false;
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/tools/source/datetime/tdate.cxx b/tools/source/datetime/tdate.cxx
index 8b6076c912ce..b53072590585 100644
--- a/tools/source/datetime/tdate.cxx
+++ b/tools/source/datetime/tdate.cxx
@@ -16,19 +16,11 @@
  *   except in compliance with the License. You may obtain a copy of
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
-
-#if defined(_WIN32)
-#if !defined WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-#include <windows.h>
-#else
-#include <time.h>
-#endif
-
 #include <tools/date.hxx>
 #include <sal/log.hxx>
 
+#include <systemdatetime.hxx>
+
 static const sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
                                              31, 31, 30, 31, 30, 31 };
 
@@ -212,29 +204,8 @@ static Date lcl_DaysToDate( sal_Int32 nDays )
 
 Date::Date( DateInitSystem )
 {
-#if defined(_WIN32)
-    SYSTEMTIME aDateTime;
-    GetLocalTime( &aDateTime );
-
-    // Combine to date
-    setDateFromDMY( aDateTime.wDay, aDateTime.wMonth, aDateTime.wYear );
-#else
-    time_t     nTmpTime;
-    struct tm aTime;
-
-    // get current time
-    nTmpTime = time( nullptr );
-
-    // compute date
-    if ( localtime_r( &nTmpTime, &aTime ) )
-    {
-        setDateFromDMY( static_cast<sal_uInt16>(aTime.tm_mday),
-            static_cast<sal_uInt16>(aTime.tm_mon+1),
-            static_cast<sal_uInt16>(aTime.tm_year+1900) );
-    }
-    else
+    if ( !GetSystemDateTime( &mnDate, nullptr ) )
         setDateFromDMY( 1, 1, 1900 );
-#endif
 }
 
 Date::Date( const css::util::DateTime& rDateTime )
diff --git a/tools/source/datetime/ttime.cxx b/tools/source/datetime/ttime.cxx
index 9d12bb9208e7..231a096e09dc 100644
--- a/tools/source/datetime/ttime.cxx
+++ b/tools/source/datetime/ttime.cxx
@@ -19,8 +19,6 @@
 
 #include <sal/config.h>
 
-#include <cerrno>
-
 #if defined(_WIN32)
 #if !defined WIN32_LEAN_AND_MEAN
 # define WIN32_LEAN_AND_MEAN
@@ -29,7 +27,6 @@
 #include <mmsystem.h>
 #elif defined UNX
 #include <unistd.h>
-#include <limits.h>
 #include <math.h>
 #include <sys/time.h>
 #endif
@@ -45,16 +42,14 @@
 #include <tools/time.hxx>
 #include <osl/diagnose.h>
 
+#include <systemdatetime.hxx>
+
 #if defined(__sun) && defined(__GNUC__)
 extern long altzone;
 #endif
 
 namespace {
 
-    const sal_Int64 secMask  = SAL_CONST_INT64(1000000000);
-    const sal_Int64 minMask  = SAL_CONST_INT64(100000000000);
-    const sal_Int64 hourMask = SAL_CONST_INT64(10000000000000);
-
     const sal_Int64 nanoSecInSec = 1000000000;
     const sal_Int16 secInMin     = 60;
     const sal_Int16 minInHour    = 60;
@@ -97,52 +92,8 @@ namespace tools {
 
 Time::Time( TimeInitSystem )
 {
-#if defined(_WIN32)
-    SYSTEMTIME aDateTime;
-    GetLocalTime( &aDateTime );
-
-    // construct time
-    nTime = aDateTime.wHour         * hourMask +
-            aDateTime.wMinute       * minMask +
-            aDateTime.wSecond       * secMask +
-            aDateTime.wMilliseconds * 1000000;
-#else
-    // determine time
-    struct timespec tsTime;
-#if defined( __MACH__ )
-    // OS X does not have clock_gettime, use clock_get_time
-    clock_serv_t cclock;
-    mach_timespec_t mts;
-    host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
-    clock_get_time(cclock, &mts);
-    mach_port_deallocate(mach_task_self(), cclock);
-    tsTime.tv_sec  = mts.tv_sec;
-    tsTime.tv_nsec = mts.tv_nsec;
-#else
-    // CLOCK_REALTIME should be supported
-    // on any modern Unix, but be extra cautious
-    if (clock_gettime(CLOCK_REALTIME, &tsTime) != 0)
-    {
-        struct timeval tvTime;
-        OSL_VERIFY( gettimeofday(&tvTime, nullptr) != 0 );
-        tsTime.tv_sec  = tvTime.tv_sec;
-        tsTime.tv_nsec = tvTime.tv_usec * 1000;
-    }
-#endif // __MACH__
-
-    // construct time
-    struct tm aTime;
-    time_t nTmpTime = tsTime.tv_sec;
-    if ( localtime_r( &nTmpTime, &aTime ) )
-    {
-        nTime = aTime.tm_hour * hourMask +
-                aTime.tm_min  * minMask +
-                aTime.tm_sec  * secMask +
-                tsTime.tv_nsec;
-    }
-    else
+    if ( !GetSystemDateTime( nullptr, &nTime ) )
         nTime = 0;
-#endif // WNT
 }
 
 Time::Time( const tools::Time& rTime )
@@ -175,9 +126,9 @@ void tools::Time::init( sal_uInt32 nHour, sal_uInt32 nMin, sal_uInt32 nSec, sal_
 
     // construct time
     nTime = nNanoSec +
-            nSec  * secMask +
-            nMin  * minMask +
-            nHour * hourMask;
+            nSec  * SEC_MASK +
+            nMin  * MIN_MASK +
+            nHour * HOUR_MASK;
 }
 
 void tools::Time::SetHour( sal_uInt16 nNewHour )
@@ -189,9 +140,9 @@ void tools::Time::SetHour( sal_uInt16 nNewHour )
 
     nTime = nSign *
             ( nNanoSec +
-              nSec  * secMask +
-              nMin  * minMask +
-              nNewHour * hourMask );
+              nSec  * SEC_MASK +
+              nMin  * MIN_MASK +
+              nNewHour * HOUR_MASK );
 }
 
 void tools::Time::SetMin( sal_uInt16 nNewMin )
@@ -206,9 +157,9 @@ void tools::Time::SetMin( sal_uInt16 nNewMin )
 
     nTime = nSign *
             ( nNanoSec +
-              nSec  * secMask +
-              nNewMin  * minMask +
-              nHour * hourMask );
+              nSec  * SEC_MASK +
+              nNewMin  * MIN_MASK +
+              nHour * HOUR_MASK );
 }
 
 void tools::Time::SetSec( sal_uInt16 nNewSec )
@@ -223,9 +174,9 @@ void tools::Time::SetSec( sal_uInt16 nNewSec )
 
     nTime = nSign *
             ( nNanoSec +
-              nNewSec  * secMask +
-              nMin  * minMask +
-              nHour * hourMask );
+              nNewSec  * SEC_MASK +
+              nMin  * MIN_MASK +
+              nHour * HOUR_MASK );
 }
 
 void tools::Time::SetNanoSec( sal_uInt32 nNewNanoSec )
@@ -240,9 +191,9 @@ void tools::Time::SetNanoSec( sal_uInt32 nNewNanoSec )
 
     nTime = nSign *
             ( nNewNanoSec +
-              nSec  * secMask +
-              nMin  * minMask +
-              nHour * hourMask );
+              nSec  * SEC_MASK +
+              nMin  * MIN_MASK +
+              nHour * HOUR_MASK );
 }
 
 sal_Int64 tools::Time::GetNSFromTime() const


More information about the Libreoffice-commits mailing list