libutil++  1.9.3
 All Classes Functions Variables
Time.cpp
1 /*
2 ** libutil++
3 ** $Id: Time.cpp 1911 2017-09-02 17:37:35Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: Time.cpp 1911 2017-09-02 17:37:35Z sella $";
10 
11 #include "Time.h"
12 #include "../util/CommonMacro.h"
13 
14 using namespace sella::variant;
15 
16 Time::Time() throw () : Nullable(std::make_shared<int64_t>(0)) { }
17 
18 Time::Time(const std::string &value) throw (TypeCastException) : Nullable() {
19  boost::smatch matcher;
20 
21  if (boost::regex_match(value, matcher, Time::Pattern())) {
22  int64_t usec = (strtol(matcher[1].str().c_str(), NULL, 10) * 3600000000LL);
23 
24  usec += (strtol(matcher[4].str().c_str(), NULL, 10) * 60000000LL);
25  usec += ((matcher.length(6) > 0) ? (strtol(matcher[6].str().c_str(), NULL, 10) * 1000000LL) : 0);
26 
27  switch (matcher.length(8)) {
28  case 0:
29  break;
30 
31  case 1:
32  usec += (strtol(matcher[8].str().c_str(), NULL, 10) * 100000LL);
33  break;
34 
35  case 2:
36  usec += (strtol(matcher[8].str().c_str(), NULL, 10) * 10000LL);
37  break;
38 
39  case 3:
40  usec += (strtol(matcher[8].str().c_str(), NULL, 10) * 1000LL);
41  break;
42 
43  case 4:
44  usec += (strtol(matcher[8].str().c_str(), NULL, 10) * 100LL);
45  break;
46 
47  case 5:
48  usec += (strtol(matcher[8].str().c_str(), NULL, 10) * 10LL);
49  break;
50 
51  case 6:
52  usec += (strtol(matcher[8].str().c_str(), NULL, 10));
53  break;
54  }
55 
56  this->value = std::make_shared<int64_t>(usec);
57  } else {
58  THROW(TypeCastException, "unable to cast '%s' to a time value", value.c_str());
59  }
60 }
61 
62 Time::Time(int64_t value) throw () : Nullable(std::make_shared<int64_t>(value)) { }
63 
64 Time::Time(const Time &other) throw () : Nullable() {
65  if (this != &other) {
66  if (!other.isNull()) {
67  if (isNull()) {
68  this->value = std::make_shared<int64_t>(other.getUsec());
69  } else {
70  *std::static_pointer_cast<int64_t>(this->value) = *std::static_pointer_cast<int64_t>(other.value);
71  }
72  } else {
73  this->value.reset();
74  }
75  }
76 }
77 
78 Time::~Time() throw () { }
79 
80 bool Time::operator==(const Time &other) const throw () {
81  return (*std::static_pointer_cast<int64_t>(this->value) == *std::static_pointer_cast<int64_t>(other.value));
82 }
83 
84 bool Time::operator!=(const Time &other) const throw () {
85  return !(*this == other);
86 }
87 
88 bool Time::operator>(const Time &other) const throw () {
89  return (*std::static_pointer_cast<int64_t>(this->value) > *std::static_pointer_cast<int64_t>(other.value));
90 }
91 
92 bool Time::operator<(const Time &other) const throw () {
93  return (*std::static_pointer_cast<int64_t>(this->value) < *std::static_pointer_cast<int64_t>(other.value));
94 }
95 
96 Time& Time::operator=(const Time &other) throw () {
97  if (this != &other) {
98  if (!other.isNull()) {
99  if (isNull()) {
100  this->value = std::make_shared<int64_t>(other.getUsec());
101  } else {
102  *std::static_pointer_cast<int64_t>(this->value) = *std::static_pointer_cast<int64_t>(other.value);
103  }
104  } else {
105  this->value.reset();
106  }
107  }
108 
109  return *this;
110 }
111 
112 Time& Time::operator+=(int64_t value) throw () {
113  (*std::static_pointer_cast<int64_t>(this->value)) += value;
114 
115  return *this;
116 }
117 
118 Time& Time::operator-=(int64_t value) throw () {
119  (*std::static_pointer_cast<int64_t>(this->value)) -= value;
120 
121  return *this;
122 }
123 
124 Time& Time::operator*=(int64_t value) throw () {
125  (*std::static_pointer_cast<int64_t>(this->value)) *= value;
126 
127  return *this;
128 }
129 
130 Time& Time::operator/=(int64_t value) throw () {
131  (*std::static_pointer_cast<int64_t>(this->value)) /= value;
132 
133  return *this;
134 }
135 
136 Time& Time::operator^=(int64_t value) throw () {
137  (*std::static_pointer_cast<int64_t>(this->value)) = pow((*std::static_pointer_cast<int64_t>(this->value)), value);
138 
139  return *this;
140 }
141 
142 Time& Time::operator%=(int64_t value) throw () {
143  (*std::static_pointer_cast<int64_t>(this->value)) %= value;
144 
145  return *this;
146 }
147 
148 Time& Time::operator&=(int64_t value) throw () {
149  (*std::static_pointer_cast<int64_t>(this->value)) &= value;
150 
151  return *this;
152 }
153 
154 Time& Time::operator|=(int64_t value) throw () {
155  (*std::static_pointer_cast<int64_t>(this->value)) |= value;
156 
157  return *this;
158 }
159 
160 int64_t Time::getUsec() const throw (UnsupportedOperatorException) {
161  if (isNull()) {
162  THROW(UnsupportedOperatorException, "unable to take reference of null value");
163  }
164 
165  return *std::static_pointer_cast<int64_t>(this->value);
166 }
167 
168 void Time::msgpack(sella::util::MessagePack &mpack, uint32_t &offset) const throw (TypeCastException) {
169  uint32_t c;
170 
171  if (UNLIKELY(this->isNull())) {
172  c = mpack.append(offset);
173  } else {
174  c = mpack.append(offset, this->str(JSON));
175  }
176 
177  offset += c;
178 
179  if (UNLIKELY(c == 0)) {
180  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
181  }
182 }
183 
184 void Time::msgpackBufferSize(size_t &size) const throw () {
185  if (UNLIKELY(isNull())) {
186  size += 1;
187 
188  return;
189  }
190 
191  size += 9;
192 }
193 
194 std::string Time::str(int type) const throw () {
195  if (UNLIKELY(this->isNull())) {
196  return "null";
197  }
198 
199  char buffer[4096];
200  time_t epoch = this->getUsec() / 1000000LL;
201  struct tm human;
202 
203  gmtime_r(&epoch, &human);
204  snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d.%06lld", human.tm_hour, human.tm_min, human.tm_sec, this->getUsec() % 1000000LL);
205 
206  return buffer;
207 }
208 
209 bool Time::isType(const char *value, size_t size) throw () {
210  return (size > 7 && value[2] == ':' && value [5] == ':' && boost::regex_match(std::string(value, size), Pattern()));
211 }
212 
213 /*
214 ** vim: noet ts=3 sw=3
215 */