诸暨麻将添加redis
您不能選擇超過 %s 個話題 話題必須以字母或數字為開頭,可包含連接號 ('-') 且最長為 35 個字
 
 
 
 
 
 

508 行
17 KiB

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #include <google/protobuf/util/time_util.h>
  31. #include <google/protobuf/stubs/int128.h>
  32. #include <google/protobuf/stubs/stringprintf.h>
  33. #include <google/protobuf/stubs/strutil.h>
  34. #include <google/protobuf/stubs/time.h>
  35. #include <google/protobuf/duration.pb.h>
  36. #include <google/protobuf/timestamp.pb.h>
  37. #include <google/protobuf/port_def.inc>
  38. namespace google {
  39. namespace protobuf {
  40. namespace util {
  41. using google::protobuf::Duration;
  42. using google::protobuf::Timestamp;
  43. namespace {
  44. static const int kNanosPerSecond = 1000000000;
  45. static const int kMicrosPerSecond = 1000000;
  46. static const int kMillisPerSecond = 1000;
  47. static const int kNanosPerMillisecond = 1000000;
  48. static const int kNanosPerMicrosecond = 1000;
  49. static const int kSecondsPerMinute = 60; // Note that we ignore leap seconds.
  50. static const int kSecondsPerHour = 3600;
  51. template <typename T>
  52. T CreateNormalized(int64 seconds, int64 nanos);
  53. template <>
  54. Timestamp CreateNormalized(int64 seconds, int64 nanos) {
  55. // Make sure nanos is in the range.
  56. if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
  57. seconds += nanos / kNanosPerSecond;
  58. nanos = nanos % kNanosPerSecond;
  59. }
  60. // For Timestamp nanos should be in the range [0, 999999999]
  61. if (nanos < 0) {
  62. seconds -= 1;
  63. nanos += kNanosPerSecond;
  64. }
  65. GOOGLE_DCHECK(seconds >= TimeUtil::kTimestampMinSeconds &&
  66. seconds <= TimeUtil::kTimestampMaxSeconds);
  67. Timestamp result;
  68. result.set_seconds(seconds);
  69. result.set_nanos(static_cast<int32>(nanos));
  70. return result;
  71. }
  72. template <>
  73. Duration CreateNormalized(int64 seconds, int64 nanos) {
  74. // Make sure nanos is in the range.
  75. if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
  76. seconds += nanos / kNanosPerSecond;
  77. nanos = nanos % kNanosPerSecond;
  78. }
  79. // nanos should have the same sign as seconds.
  80. if (seconds < 0 && nanos > 0) {
  81. seconds += 1;
  82. nanos -= kNanosPerSecond;
  83. } else if (seconds > 0 && nanos < 0) {
  84. seconds -= 1;
  85. nanos += kNanosPerSecond;
  86. }
  87. GOOGLE_DCHECK(seconds >= TimeUtil::kDurationMinSeconds &&
  88. seconds <= TimeUtil::kDurationMaxSeconds);
  89. Duration result;
  90. result.set_seconds(seconds);
  91. result.set_nanos(static_cast<int32>(nanos));
  92. return result;
  93. }
  94. // Format nanoseconds with either 3, 6, or 9 digits depending on the required
  95. // precision to represent the exact value.
  96. std::string FormatNanos(int32 nanos) {
  97. if (nanos % kNanosPerMillisecond == 0) {
  98. return StringPrintf("%03d", nanos / kNanosPerMillisecond);
  99. } else if (nanos % kNanosPerMicrosecond == 0) {
  100. return StringPrintf("%06d", nanos / kNanosPerMicrosecond);
  101. } else {
  102. return StringPrintf("%09d", nanos);
  103. }
  104. }
  105. std::string FormatTime(int64 seconds, int32 nanos) {
  106. return ::google::protobuf::internal::FormatTime(seconds, nanos);
  107. }
  108. bool ParseTime(const std::string& value, int64* seconds, int32* nanos) {
  109. return ::google::protobuf::internal::ParseTime(value, seconds, nanos);
  110. }
  111. void CurrentTime(int64* seconds, int32* nanos) {
  112. return ::google::protobuf::internal::GetCurrentTime(seconds, nanos);
  113. }
  114. // Truncates the remainder part after division.
  115. int64 RoundTowardZero(int64 value, int64 divider) {
  116. int64 result = value / divider;
  117. int64 remainder = value % divider;
  118. // Before C++11, the sign of the remainder is implementation dependent if
  119. // any of the operands is negative. Here we try to enforce C++11's "rounded
  120. // toward zero" semantics. For example, for (-5) / 2 an implementation may
  121. // give -3 as the result with the remainder being 1. This function ensures
  122. // we always return -2 (closer to zero) regardless of the implementation.
  123. if (result < 0 && remainder > 0) {
  124. return result + 1;
  125. } else {
  126. return result;
  127. }
  128. }
  129. } // namespace
  130. // Actually define these static const integers. Required by C++ standard (but
  131. // some compilers don't like it).
  132. #ifndef _MSC_VER
  133. const int64 TimeUtil::kTimestampMinSeconds;
  134. const int64 TimeUtil::kTimestampMaxSeconds;
  135. const int64 TimeUtil::kDurationMaxSeconds;
  136. const int64 TimeUtil::kDurationMinSeconds;
  137. #endif // !_MSC_VER
  138. std::string TimeUtil::ToString(const Timestamp& timestamp) {
  139. return FormatTime(timestamp.seconds(), timestamp.nanos());
  140. }
  141. bool TimeUtil::FromString(const std::string& value, Timestamp* timestamp) {
  142. int64 seconds;
  143. int32 nanos;
  144. if (!ParseTime(value, &seconds, &nanos)) {
  145. return false;
  146. }
  147. *timestamp = CreateNormalized<Timestamp>(seconds, nanos);
  148. return true;
  149. }
  150. Timestamp TimeUtil::GetCurrentTime() {
  151. int64 seconds;
  152. int32 nanos;
  153. CurrentTime(&seconds, &nanos);
  154. return CreateNormalized<Timestamp>(seconds, nanos);
  155. }
  156. Timestamp TimeUtil::GetEpoch() { return Timestamp(); }
  157. std::string TimeUtil::ToString(const Duration& duration) {
  158. std::string result;
  159. int64 seconds = duration.seconds();
  160. int32 nanos = duration.nanos();
  161. if (seconds < 0 || nanos < 0) {
  162. result += "-";
  163. seconds = -seconds;
  164. nanos = -nanos;
  165. }
  166. result += StrCat(seconds);
  167. if (nanos != 0) {
  168. result += "." + FormatNanos(nanos);
  169. }
  170. result += "s";
  171. return result;
  172. }
  173. static int64 Pow(int64 x, int y) {
  174. int64 result = 1;
  175. for (int i = 0; i < y; ++i) {
  176. result *= x;
  177. }
  178. return result;
  179. }
  180. bool TimeUtil::FromString(const std::string& value, Duration* duration) {
  181. if (value.length() <= 1 || value[value.length() - 1] != 's') {
  182. return false;
  183. }
  184. bool negative = (value[0] == '-');
  185. int sign_length = (negative ? 1 : 0);
  186. // Parse the duration value as two integers rather than a float value
  187. // to avoid precision loss.
  188. std::string seconds_part, nanos_part;
  189. size_t pos = value.find_last_of(".");
  190. if (pos == std::string::npos) {
  191. seconds_part = value.substr(sign_length, value.length() - 1 - sign_length);
  192. nanos_part = "0";
  193. } else {
  194. seconds_part = value.substr(sign_length, pos - sign_length);
  195. nanos_part = value.substr(pos + 1, value.length() - pos - 2);
  196. }
  197. char* end;
  198. int64 seconds = strto64(seconds_part.c_str(), &end, 10);
  199. if (end != seconds_part.c_str() + seconds_part.length()) {
  200. return false;
  201. }
  202. int64 nanos = strto64(nanos_part.c_str(), &end, 10);
  203. if (end != nanos_part.c_str() + nanos_part.length()) {
  204. return false;
  205. }
  206. nanos = nanos * Pow(10, 9 - nanos_part.length());
  207. if (negative) {
  208. // If a Duration is negative, both seconds and nanos should be negative.
  209. seconds = -seconds;
  210. nanos = -nanos;
  211. }
  212. duration->set_seconds(seconds);
  213. duration->set_nanos(static_cast<int32>(nanos));
  214. return true;
  215. }
  216. Duration TimeUtil::NanosecondsToDuration(int64 nanos) {
  217. return CreateNormalized<Duration>(nanos / kNanosPerSecond,
  218. nanos % kNanosPerSecond);
  219. }
  220. Duration TimeUtil::MicrosecondsToDuration(int64 micros) {
  221. return CreateNormalized<Duration>(
  222. micros / kMicrosPerSecond,
  223. (micros % kMicrosPerSecond) * kNanosPerMicrosecond);
  224. }
  225. Duration TimeUtil::MillisecondsToDuration(int64 millis) {
  226. return CreateNormalized<Duration>(
  227. millis / kMillisPerSecond,
  228. (millis % kMillisPerSecond) * kNanosPerMillisecond);
  229. }
  230. Duration TimeUtil::SecondsToDuration(int64 seconds) {
  231. return CreateNormalized<Duration>(seconds, 0);
  232. }
  233. Duration TimeUtil::MinutesToDuration(int64 minutes) {
  234. return CreateNormalized<Duration>(minutes * kSecondsPerMinute, 0);
  235. }
  236. Duration TimeUtil::HoursToDuration(int64 hours) {
  237. return CreateNormalized<Duration>(hours * kSecondsPerHour, 0);
  238. }
  239. int64 TimeUtil::DurationToNanoseconds(const Duration& duration) {
  240. return duration.seconds() * kNanosPerSecond + duration.nanos();
  241. }
  242. int64 TimeUtil::DurationToMicroseconds(const Duration& duration) {
  243. return duration.seconds() * kMicrosPerSecond +
  244. RoundTowardZero(duration.nanos(), kNanosPerMicrosecond);
  245. }
  246. int64 TimeUtil::DurationToMilliseconds(const Duration& duration) {
  247. return duration.seconds() * kMillisPerSecond +
  248. RoundTowardZero(duration.nanos(), kNanosPerMillisecond);
  249. }
  250. int64 TimeUtil::DurationToSeconds(const Duration& duration) {
  251. return duration.seconds();
  252. }
  253. int64 TimeUtil::DurationToMinutes(const Duration& duration) {
  254. return RoundTowardZero(duration.seconds(), kSecondsPerMinute);
  255. }
  256. int64 TimeUtil::DurationToHours(const Duration& duration) {
  257. return RoundTowardZero(duration.seconds(), kSecondsPerHour);
  258. }
  259. Timestamp TimeUtil::NanosecondsToTimestamp(int64 nanos) {
  260. return CreateNormalized<Timestamp>(nanos / kNanosPerSecond,
  261. nanos % kNanosPerSecond);
  262. }
  263. Timestamp TimeUtil::MicrosecondsToTimestamp(int64 micros) {
  264. return CreateNormalized<Timestamp>(
  265. micros / kMicrosPerSecond,
  266. micros % kMicrosPerSecond * kNanosPerMicrosecond);
  267. }
  268. Timestamp TimeUtil::MillisecondsToTimestamp(int64 millis) {
  269. return CreateNormalized<Timestamp>(
  270. millis / kMillisPerSecond,
  271. millis % kMillisPerSecond * kNanosPerMillisecond);
  272. }
  273. Timestamp TimeUtil::SecondsToTimestamp(int64 seconds) {
  274. return CreateNormalized<Timestamp>(seconds, 0);
  275. }
  276. int64 TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) {
  277. return timestamp.seconds() * kNanosPerSecond + timestamp.nanos();
  278. }
  279. int64 TimeUtil::TimestampToMicroseconds(const Timestamp& timestamp) {
  280. return timestamp.seconds() * kMicrosPerSecond +
  281. RoundTowardZero(timestamp.nanos(), kNanosPerMicrosecond);
  282. }
  283. int64 TimeUtil::TimestampToMilliseconds(const Timestamp& timestamp) {
  284. return timestamp.seconds() * kMillisPerSecond +
  285. RoundTowardZero(timestamp.nanos(), kNanosPerMillisecond);
  286. }
  287. int64 TimeUtil::TimestampToSeconds(const Timestamp& timestamp) {
  288. return timestamp.seconds();
  289. }
  290. Timestamp TimeUtil::TimeTToTimestamp(time_t value) {
  291. return CreateNormalized<Timestamp>(static_cast<int64>(value), 0);
  292. }
  293. time_t TimeUtil::TimestampToTimeT(const Timestamp& value) {
  294. return static_cast<time_t>(value.seconds());
  295. }
  296. Timestamp TimeUtil::TimevalToTimestamp(const timeval& value) {
  297. return CreateNormalized<Timestamp>(value.tv_sec,
  298. value.tv_usec * kNanosPerMicrosecond);
  299. }
  300. timeval TimeUtil::TimestampToTimeval(const Timestamp& value) {
  301. timeval result;
  302. result.tv_sec = value.seconds();
  303. result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
  304. return result;
  305. }
  306. Duration TimeUtil::TimevalToDuration(const timeval& value) {
  307. return CreateNormalized<Duration>(value.tv_sec,
  308. value.tv_usec * kNanosPerMicrosecond);
  309. }
  310. timeval TimeUtil::DurationToTimeval(const Duration& value) {
  311. timeval result;
  312. result.tv_sec = value.seconds();
  313. result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
  314. // timeval.tv_usec's range is [0, 1000000)
  315. if (result.tv_usec < 0) {
  316. result.tv_sec -= 1;
  317. result.tv_usec += kMicrosPerSecond;
  318. }
  319. return result;
  320. }
  321. } // namespace util
  322. } // namespace protobuf
  323. } // namespace google
  324. namespace google {
  325. namespace protobuf {
  326. namespace {
  327. using ::PROTOBUF_NAMESPACE_ID::util::CreateNormalized;
  328. using ::PROTOBUF_NAMESPACE_ID::util::kNanosPerSecond;
  329. // Convert a Duration to uint128.
  330. void ToUint128(const Duration& value, uint128* result, bool* negative) {
  331. if (value.seconds() < 0 || value.nanos() < 0) {
  332. *negative = true;
  333. *result = static_cast<uint64>(-value.seconds());
  334. *result = *result * kNanosPerSecond + static_cast<uint32>(-value.nanos());
  335. } else {
  336. *negative = false;
  337. *result = static_cast<uint64>(value.seconds());
  338. *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
  339. }
  340. }
  341. void ToDuration(const uint128& value, bool negative, Duration* duration) {
  342. int64 seconds =
  343. static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
  344. int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
  345. if (negative) {
  346. seconds = -seconds;
  347. nanos = -nanos;
  348. }
  349. duration->set_seconds(seconds);
  350. duration->set_nanos(nanos);
  351. }
  352. } // namespace
  353. Duration& operator+=(Duration& d1, const Duration& d2) {
  354. d1 = CreateNormalized<Duration>(d1.seconds() + d2.seconds(),
  355. d1.nanos() + d2.nanos());
  356. return d1;
  357. }
  358. Duration& operator-=(Duration& d1, const Duration& d2) { // NOLINT
  359. d1 = CreateNormalized<Duration>(d1.seconds() - d2.seconds(),
  360. d1.nanos() - d2.nanos());
  361. return d1;
  362. }
  363. Duration& operator*=(Duration& d, int64 r) { // NOLINT
  364. bool negative;
  365. uint128 value;
  366. ToUint128(d, &value, &negative);
  367. if (r > 0) {
  368. value *= static_cast<uint64>(r);
  369. } else {
  370. negative = !negative;
  371. value *= static_cast<uint64>(-r);
  372. }
  373. ToDuration(value, negative, &d);
  374. return d;
  375. }
  376. Duration& operator*=(Duration& d, double r) { // NOLINT
  377. double result = (d.seconds() * 1.0 + 1.0 * d.nanos() / kNanosPerSecond) * r;
  378. int64 seconds = static_cast<int64>(result);
  379. int32 nanos = static_cast<int32>((result - seconds) * kNanosPerSecond);
  380. // Note that we normalize here not just because nanos can have a different
  381. // sign from seconds but also that nanos can be any arbitrary value when
  382. // overflow happens (i.e., the result is a much larger value than what
  383. // int64 can represent).
  384. d = CreateNormalized<Duration>(seconds, nanos);
  385. return d;
  386. }
  387. Duration& operator/=(Duration& d, int64 r) { // NOLINT
  388. bool negative;
  389. uint128 value;
  390. ToUint128(d, &value, &negative);
  391. if (r > 0) {
  392. value /= static_cast<uint64>(r);
  393. } else {
  394. negative = !negative;
  395. value /= static_cast<uint64>(-r);
  396. }
  397. ToDuration(value, negative, &d);
  398. return d;
  399. }
  400. Duration& operator/=(Duration& d, double r) { // NOLINT
  401. return d *= 1.0 / r;
  402. }
  403. Duration& operator%=(Duration& d1, const Duration& d2) { // NOLINT
  404. bool negative1, negative2;
  405. uint128 value1, value2;
  406. ToUint128(d1, &value1, &negative1);
  407. ToUint128(d2, &value2, &negative2);
  408. uint128 result = value1 % value2;
  409. // When negative values are involved in division, we round the division
  410. // result towards zero. With this semantics, sign of the remainder is the
  411. // same as the dividend. For example:
  412. // -5 / 10 = 0, -5 % 10 = -5
  413. // -5 / (-10) = 0, -5 % (-10) = -5
  414. // 5 / (-10) = 0, 5 % (-10) = 5
  415. ToDuration(result, negative1, &d1);
  416. return d1;
  417. }
  418. int64 operator/(const Duration& d1, const Duration& d2) {
  419. bool negative1, negative2;
  420. uint128 value1, value2;
  421. ToUint128(d1, &value1, &negative1);
  422. ToUint128(d2, &value2, &negative2);
  423. int64 result = Uint128Low64(value1 / value2);
  424. if (negative1 != negative2) {
  425. result = -result;
  426. }
  427. return result;
  428. }
  429. Timestamp& operator+=(Timestamp& t, const Duration& d) { // NOLINT
  430. t = CreateNormalized<Timestamp>(t.seconds() + d.seconds(),
  431. t.nanos() + d.nanos());
  432. return t;
  433. }
  434. Timestamp& operator-=(Timestamp& t, const Duration& d) { // NOLINT
  435. t = CreateNormalized<Timestamp>(t.seconds() - d.seconds(),
  436. t.nanos() - d.nanos());
  437. return t;
  438. }
  439. Duration operator-(const Timestamp& t1, const Timestamp& t2) {
  440. return CreateNormalized<Duration>(t1.seconds() - t2.seconds(),
  441. t1.nanos() - t2.nanos());
  442. }
  443. } // namespace protobuf
  444. } // namespace google