diff options
| author | levlam <levlam@telegram.org> | 2024-05-20 13:46:32 +0300 |
|---|---|---|
| committer | levlam <levlam@telegram.org> | 2024-05-20 13:46:32 +0300 |
| commit | 53c3e791976c20fdc835c4c196ee78fc812f321a (patch) | |
| tree | 49f0f56c3e5f7c8561650636aa06365b408c73c8 /tdutils | |
| parent | 699707a09bdcd37a3ef1739d512fe03d5f186b30 (diff) | |
Move class HttpDate to tdutils.
Diffstat (limited to 'tdutils')
| -rw-r--r-- | tdutils/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | tdutils/td/utils/HttpDate.cpp | 92 | ||||
| -rw-r--r-- | tdutils/td/utils/HttpDate.h | 34 |
3 files changed, 128 insertions, 0 deletions
diff --git a/tdutils/CMakeLists.txt b/tdutils/CMakeLists.txt index 1240682fc..f63bd90e5 100644 --- a/tdutils/CMakeLists.txt +++ b/tdutils/CMakeLists.txt @@ -107,6 +107,7 @@ set(TDUTILS_SOURCE td/utils/Gzip.cpp td/utils/GzipByteFlow.cpp td/utils/Hints.cpp + td/utils/HttpDate.cpp td/utils/HttpUrl.cpp td/utils/JsonBuilder.cpp td/utils/logging.cpp @@ -231,6 +232,7 @@ set(TDUTILS_SOURCE td/utils/HazardPointers.h td/utils/Heap.h td/utils/Hints.h + td/utils/HttpDate.h td/utils/HttpUrl.h td/utils/int_types.h td/utils/invoke.h diff --git a/tdutils/td/utils/HttpDate.cpp b/tdutils/td/utils/HttpDate.cpp new file mode 100644 index 000000000..da290ae3a --- /dev/null +++ b/tdutils/td/utils/HttpDate.cpp @@ -0,0 +1,92 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/utils/HttpDate.h" + +#include "td/utils/misc.h" +#include "td/utils/Parser.h" +#include "td/utils/Slice.h" + +namespace td { + +Result<int32> HttpDate::to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second) { + if (year < 1970 || year > 2037) { + return Status::Error("Invalid year"); + } + if (month < 1 || month > 12) { + return Status::Error("Invalid month"); + } + if (day < 1 || day > days_in_month(year, month)) { + return Status::Error("Invalid day"); + } + if (hour < 0 || hour >= 24) { + return Status::Error("Invalid hour"); + } + if (minute < 0 || minute >= 60) { + return Status::Error("Invalid minute"); + } + if (second < 0 || second > 60) { + return Status::Error("Invalid second"); + } + + int32 res = 0; + for (int32 y = 1970; y < year; y++) { + res += (is_leap(y) + 365) * seconds_in_day(); + } + for (int32 m = 1; m < month; m++) { + res += days_in_month(year, m) * seconds_in_day(); + } + res += (day - 1) * seconds_in_day(); + res += hour * 60 * 60; + res += minute * 60; + res += second; + return res; +} + +Result<int32> HttpDate::parse_http_date(string slice) { + Parser p(slice); + p.read_till(','); // ignore week day + p.skip(','); + p.skip_whitespaces(); + p.skip_nofail('0'); + TRY_RESULT(day, to_integer_safe<int32>(p.read_word())); + auto month_name = p.read_word(); + to_lower_inplace(month_name); + TRY_RESULT(year, to_integer_safe<int32>(p.read_word())); + p.skip_whitespaces(); + p.skip_nofail('0'); + TRY_RESULT(hour, to_integer_safe<int32>(p.read_till(':'))); + p.skip(':'); + p.skip_nofail('0'); + TRY_RESULT(minute, to_integer_safe<int32>(p.read_till(':'))); + p.skip(':'); + p.skip_nofail('0'); + TRY_RESULT(second, to_integer_safe<int32>(p.read_word())); + auto gmt = p.read_word(); + TRY_STATUS(std::move(p.status())); + if (gmt != "GMT") { + return Status::Error("Timezone must be GMT"); + } + + static Slice month_names[12] = {"jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"}; + + int month = 0; + + for (int m = 1; m <= 12; m++) { + if (month_names[m - 1] == month_name) { + month = m; + break; + } + } + + if (month == 0) { + return Status::Error("Unknown month name"); + } + + return to_unix_time(year, month, day, hour, minute, second); +} + +} // namespace td diff --git a/tdutils/td/utils/HttpDate.h b/tdutils/td/utils/HttpDate.h new file mode 100644 index 000000000..a2daf0784 --- /dev/null +++ b/tdutils/td/utils/HttpDate.h @@ -0,0 +1,34 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class HttpDate { + static bool is_leap(int32 year) { + return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); + } + + static int32 seconds_in_day() { + return 24 * 60 * 60; + } + + public: + static int32 days_in_month(int32 year, int32 month) { + static int cnt[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + return cnt[month - 1] + (month == 2 && is_leap(year)); + } + + static Result<int32> to_unix_time(int32 year, int32 month, int32 day, int32 hour, int32 minute, int32 second); + + static Result<int32> parse_http_date(string slice); +}; + +} // namespace td |
