Repository: mesos
Updated Branches:
  refs/heads/master 9987b4652 -> d0300e1a4


Added stream manipulators for the Time object.

Adds some manipulator classes which allows formatting Time objects to
ostreams.

Review: https://reviews.apache.org/r/34703


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2dc9f5e4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2dc9f5e4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2dc9f5e4

Branch: refs/heads/master
Commit: 2dc9f5e4e21d7c7d361b3b23b82e000152fef700
Parents: 9987b46
Author: Alexander Rojas <[email protected]>
Authored: Thu Jul 9 17:25:51 2015 +0200
Committer: Till Toenshoff <[email protected]>
Committed: Thu Jul 9 17:28:06 2015 +0200

----------------------------------------------------------------------
 3rdparty/libprocess/Makefile.am              |   1 +
 3rdparty/libprocess/include/process/time.hpp |  68 +++++++------
 3rdparty/libprocess/src/tests/time_tests.cpp |  52 ++++++++++
 3rdparty/libprocess/src/time.cpp             | 114 ++++++++++++++++++++++
 4 files changed, 205 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/2dc9f5e4/3rdparty/libprocess/Makefile.am
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/Makefile.am b/3rdparty/libprocess/Makefile.am
index 358893c..71e15f0 100644
--- a/3rdparty/libprocess/Makefile.am
+++ b/3rdparty/libprocess/Makefile.am
@@ -52,6 +52,7 @@ libprocess_la_SOURCES =               \
   src/reap.cpp                 \
   src/socket.cpp               \
   src/subprocess.cpp           \
+  src/time.cpp                 \
   src/timeseries.cpp
 
 if ENABLE_LIBEVENT

http://git-wip-us.apache.org/repos/asf/mesos/blob/2dc9f5e4/3rdparty/libprocess/include/process/time.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/time.hpp 
b/3rdparty/libprocess/include/process/time.hpp
index c5ab2a3..6a57b7b 100644
--- a/3rdparty/libprocess/include/process/time.hpp
+++ b/3rdparty/libprocess/include/process/time.hpp
@@ -1,12 +1,8 @@
 #ifndef __PROCESS_TIME_HPP__
 #define __PROCESS_TIME_HPP__
 
-#include <time.h>
-
 #include <iomanip>
 
-#include <glog/logging.h>
-
 #include <stout/duration.hpp>
 
 namespace process {
@@ -80,39 +76,51 @@ inline Time Time::epoch() { return Time(Duration::zero()); }
 inline Time Time::max() { return Time(Duration::max()); }
 
 
-// Outputs the time in RFC 3339 Format.
-inline std::ostream& operator << (std::ostream& stream, const Time& time)
+// Stream manipulator class which serializes Time objects in RFC 1123
+// format (Also known as HTTP Date format).
+// The serialization is independent from the locale and ready to be
+// used in HTTP Headers.
+// Example: Wed, 15 Nov 1995 04:58:08 GMT
+// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+// section 14.18.
+// See https://www.ietf.org/rfc/rfc1123.txt section 5.2.14
+class RFC1123
 {
-  // Round down the secs to use it with strftime and then append the
-  // fraction part.
-  long secs = static_cast<long>(time.secs());
-  char date[64];
-
-  // The RFC 3339 Format.
-  tm tm_;
-  if (gmtime_r(&secs, &tm_) == NULL) {
-    PLOG(ERROR)
-      << "Failed to convert the 'time' to a tm struct using gmtime_r()";
-    return stream;
-  }
+public:
+  explicit RFC1123(const Time& _time) : time(_time) {}
 
-  strftime(date, 64, "%Y-%m-%d %H:%M:%S", &tm_);
-  stream << date;
+private:
+  friend std::ostream& operator << (std::ostream& out, const RFC1123& format);
 
-  // Append the fraction part in nanoseconds.
-  int64_t nsecs = (time.duration() - Seconds(secs)).ns();
+  const Time time;
+};
 
-  if (nsecs != 0) {
-    char prev = stream.fill();
 
-    // 9 digits for nanosecond level precision.
-    stream << "." << std::setfill('0') << std::setw(9) << nsecs;
+std::ostream& operator << (std::ostream& out, const RFC1123& formatter);
+
+
+// Stream manipulator class which serializes Time objects in RFC 3339
+// format.
+// Example: 1996-12-19T16:39:57-08:00,234
+class RFC3339
+{
+public:
+  explicit RFC3339(const Time& _time) : time(_time) {}
+
+private:
+  friend std::ostream& operator << (std::ostream& out, const RFC3339& format);
+
+  const Time time;
+};
 
-    // Return the stream to original formatting state.
-    stream.fill(prev);
-  }
 
-  stream << "+00:00";
+std::ostream& operator << (std::ostream& out, const RFC3339& formatter);
+
+
+// Outputs the time in RFC 3339 Format.
+inline std::ostream& operator << (std::ostream& stream, const Time& time)
+{
+  stream << RFC3339(time);
   return stream;
 }
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/2dc9f5e4/3rdparty/libprocess/src/tests/time_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/time_tests.cpp 
b/3rdparty/libprocess/src/tests/time_tests.cpp
index be31418..9e1d176 100644
--- a/3rdparty/libprocess/src/tests/time_tests.cpp
+++ b/3rdparty/libprocess/src/tests/time_tests.cpp
@@ -37,6 +37,58 @@ TEST(TimeTest, Now)
 }
 
 
+// Tests stream manipulator which formats Time object into RFC 1123
+// (HTTP Date) format.
+TEST(TimeTest, RFC1123Output)
+{
+  EXPECT_EQ(
+      "Thu, 01 Jan 1970 00:00:00 GMT",
+      stringify(RFC1123(Time::epoch())));
+
+  EXPECT_EQ(
+      "Thu, 02 Mar 1989 00:00:00 GMT",
+      stringify(RFC1123(Time::epoch() + Weeks(1000))));
+
+  EXPECT_EQ(
+      "Thu, 02 Mar 1989 00:00:00 GMT",
+      stringify(RFC1123(Time::epoch() + Weeks(1000) + Nanoseconds(1))));
+
+  EXPECT_EQ(
+      "Thu, 02 Mar 1989 00:00:01 GMT",
+      stringify(RFC1123(Time::epoch() + Weeks(1000) + Seconds(1))));
+
+  EXPECT_EQ(
+      "Fri, 11 Apr 2262 23:47:16 GMT",
+      stringify(RFC1123(Time::max())));
+}
+
+
+// Tests stream manipulator which formats Time object into RFC 3339
+// format.
+TEST(TimeTest, RFC3339Output)
+{
+  EXPECT_EQ(
+      "1970-01-01 00:00:00+00:00",
+      stringify(RFC3339(Time::epoch())));
+
+  EXPECT_EQ(
+      "1989-03-02 00:00:00+00:00",
+      stringify(RFC3339(Time::epoch() + Weeks(1000))));
+
+  EXPECT_EQ(
+      "1989-03-02 00:00:00.000000001+00:00",
+      stringify(RFC3339(Time::epoch() + Weeks(1000) + Nanoseconds(1))));
+
+  EXPECT_EQ(
+      "1989-03-02 00:00:00.000001000+00:00",
+      stringify(RFC3339(Time::epoch() + Weeks(1000) + Microseconds(1))));
+
+  EXPECT_EQ(
+      "2262-04-11 23:47:16.854775807+00:00",
+      stringify(RFC3339(Time::max())));
+}
+
+
 TEST(TimeTest, Output)
 {
   EXPECT_EQ("1989-03-02 00:00:00+00:00",

http://git-wip-us.apache.org/repos/asf/mesos/blob/2dc9f5e4/3rdparty/libprocess/src/time.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/time.cpp b/3rdparty/libprocess/src/time.cpp
new file mode 100644
index 0000000..87f1f36
--- /dev/null
+++ b/3rdparty/libprocess/src/time.cpp
@@ -0,0 +1,114 @@
+/**
+ * Licensed 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
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <time.h>
+
+#include <glog/logging.h>
+
+#include <process/time.hpp>
+
+namespace process {
+
+std::ostream& operator << (std::ostream& out, const RFC1123& formatter)
+{
+  time_t secs = static_cast<time_t>(formatter.time.secs());
+
+  tm timeInfo = {};
+  if (gmtime_r(&secs, &timeInfo) == NULL) {
+    PLOG(ERROR)
+      << "Failed to convert from 'time_t' to a 'tm' struct using gmtime_r()";
+    return out;
+  }
+
+  static const char* WEEK_DAYS[] = {
+      "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+    };
+
+  static const char* MONTHS[] = {
+      "Jan",
+      "Feb",
+      "Mar",
+      "Apr",
+      "May",
+      "Jun",
+      "Jul",
+      "Aug",
+      "Sep",
+      "Oct",
+      "Nov",
+      "Dec"
+    };
+
+  char buffer[64] = {};
+
+  // 'strftime' cannot be used since it depends on the locale, which
+  // is not useful when using the RFC 1123 format in HTTP Headers.
+  if (snprintf(
+          buffer,
+          sizeof(buffer),
+          "%s, %02d %s %d %02d:%02d:%02d GMT",
+          WEEK_DAYS[timeInfo.tm_wday],
+          timeInfo.tm_mday,
+          MONTHS[timeInfo.tm_mon],
+          timeInfo.tm_year + 1900,
+          timeInfo.tm_hour,
+          timeInfo.tm_min,
+          timeInfo.tm_sec) < 0) {
+    LOG(ERROR)
+      << "Failed to format the 'time' to a string using snprintf";
+    return out;
+  }
+
+  out << buffer;
+
+  return out;
+}
+
+
+std::ostream& operator << (std::ostream& out, const RFC3339& formatter)
+{
+  // Round down the secs to use it with strftime and then append the
+  // fraction part.
+  time_t secs = static_cast<time_t>(formatter.time.secs());
+
+  // The RFC 3339 Format.
+  tm timeInfo = {};
+  if (gmtime_r(&secs, &timeInfo) == NULL) {
+    PLOG(ERROR)
+      << "Failed to convert from 'time_t' to a 'tm' struct using gmtime_r()";
+    return out;
+  }
+
+  char buffer[64] = {};
+
+  strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &timeInfo);
+  out << buffer;
+
+  // Append the fraction part in nanoseconds.
+  int64_t nanoSeconds = (formatter.time.duration() - Seconds(secs)).ns();
+  if (nanoSeconds != 0) {
+    char prev = out.fill();
+
+    // 9 digits for nanosecond level precision.
+    out << "." << std::setfill('0') << std::setw(9) << nanoSeconds;
+
+    // Return the stream to original formatting state.
+    out.fill(prev);
+  }
+
+  out << "+00:00";
+  return out;
+}
+
+} // namespace process {

Reply via email to