summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/tdutils
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdutils')
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/CMakeLists.txt29
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/generate/auto/extension_to_mime_type.cpp19
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/generate/auto/mime_type_to_extension.cpp19
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/BufferedFd.h10
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/ByteFlow.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/ChainScheduler.h47
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/ConcurrentHashTable.h5
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/FileLog.cpp4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMap.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMapChunks.h19
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashSet.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashTable.h14
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/FloodControlStrict.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.cpp7
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.h3
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/Hash.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/HashTableUtils.h10
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/Hints.cpp4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.cpp92
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.h34
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.cpp367
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.h93
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/MapNode.h12
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/MpmcQueue.h6
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/ObjectPool.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/Promise.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h12
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp20
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.h36
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/TlStorerToString.h140
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/WaitFreeHashSet.h7
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/algorithm.h69
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/check.h10
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/crypto.cpp61
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/emoji.cpp4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.cpp6
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.h5
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/format.h38
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/logging.cpp5
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/misc.cpp100
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/optional.h5
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/FileFd.cpp20
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/FromApp.h9
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.cpp10
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.h5
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.cpp12
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.h5
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.cpp58
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.cpp43
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.h7
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/platform.h4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/port/uname.cpp4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.cpp22
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.h23
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/unicode.cpp381
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/ChainScheduler.cpp8
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/ConcurrentHashMap.cpp38
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp3
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/StealingQueue.cpp12
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/hashset_benchmark.cpp4
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/json.cpp211
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/misc.cpp110
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/test/pq.cpp6
64 files changed, 1498 insertions, 841 deletions
diff --git a/protocols/Telegram/tdlib/td/tdutils/CMakeLists.txt b/protocols/Telegram/tdlib/td/tdutils/CMakeLists.txt
index e7b4b788a7..4760aab011 100644
--- a/protocols/Telegram/tdlib/td/tdutils/CMakeLists.txt
+++ b/protocols/Telegram/tdlib/td/tdutils/CMakeLists.txt
@@ -3,12 +3,13 @@ if ((CMAKE_MAJOR_VERSION LESS 3) OR (CMAKE_VERSION VERSION_LESS "3.0.2"))
endif()
option(TDUTILS_MIME_TYPE "Generate MIME types conversion; requires gperf" ON)
+option(TDUTILS_USE_EXTERNAL_DEPENDENCIES "Use external libraries if available" ON)
if (NOT DEFINED CMAKE_INSTALL_LIBDIR)
set(CMAKE_INSTALL_LIBDIR "lib")
endif()
-if (NOT ZLIB_FOUND)
+if (NOT ZLIB_FOUND AND TDUTILS_USE_EXTERNAL_DEPENDENCIES)
find_package(ZLIB)
endif()
if (ZLIB_FOUND)
@@ -24,11 +25,14 @@ if (ZLIB_FOUND)
endif()
endif()
+if (NOT CRC32C_FOUND AND TDUTILS_USE_EXTERNAL_DEPENDENCIES)
+ find_package(Crc32c QUIET)
+endif()
if (CRC32C_FOUND)
set(TD_HAVE_CRC32C 1)
endif()
-if (TD_WITH_ABSEIL)
+if (TD_WITH_ABSEIL AND TDUTILS_USE_EXTERNAL_DEPENDENCIES)
find_package(ABSL QUIET)
if (ABSL_FOUND)
set(TD_HAVE_ABSL 1)
@@ -39,7 +43,6 @@ configure_file(td/utils/config.h.in td/utils/config.h @ONLY)
add_subdirectory(generate)
-# TDUTILS
set_source_files_properties(${TDMIME_AUTO} PROPERTIES GENERATED TRUE)
if (CLANG OR GCC)
set_property(SOURCE ${TDMIME_AUTO} APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-conversion")
@@ -104,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
@@ -120,7 +124,6 @@ set(TDUTILS_SOURCE
td/utils/tests.cpp
td/utils/Time.cpp
td/utils/Timer.cpp
- td/utils/TsFileLog.cpp
td/utils/tl_parsers.cpp
td/utils/translit.cpp
td/utils/TsCerr.cpp
@@ -136,8 +139,8 @@ set(TDUTILS_SOURCE
td/utils/port/EventFdBase.h
td/utils/port/FileFd.h
td/utils/port/FromApp.h
- td/utils/port/IPAddress.h
td/utils/port/IoSlice.h
+ td/utils/port/IPAddress.h
td/utils/port/MemoryMapping.h
td/utils/port/Mutex.h
td/utils/port/path.h
@@ -210,8 +213,8 @@ set(TDUTILS_SOURCE
td/utils/ExitGuard.h
td/utils/FileLog.h
td/utils/filesystem.h
- td/utils/fixed_vector.h
td/utils/find_boundary.h
+ td/utils/fixed_vector.h
td/utils/FlatHashMap.h
td/utils/FlatHashMapChunks.h
td/utils/FlatHashSet.h
@@ -229,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
@@ -241,8 +245,8 @@ set(TDUTILS_SOURCE
td/utils/MovableValue.h
td/utils/MpmcQueue.h
td/utils/MpmcWaiter.h
- td/utils/MpscPollableQueue.h
td/utils/MpscLinkQueue.h
+ td/utils/MpscPollableQueue.h
td/utils/Named.h
td/utils/NullLog.h
td/utils/ObjectPool.h
@@ -345,7 +349,6 @@ set(TDUTILS_TEST_SOURCE
PARENT_SCOPE
)
-#LIBRARIES
add_library(tdutils STATIC ${TDUTILS_SOURCE})
if (NOT CMAKE_CROSSCOMPILING AND TDUTILS_MIME_TYPE)
@@ -401,17 +404,17 @@ if (ANDROID)
target_link_libraries(tdutils PRIVATE log)
endif()
-if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- target_link_directories(tdutils PUBLIC /usr/pkg/gcc12/x86_64--netbsd/lib /usr/pkg/gcc12/i486--netbsdelf/lib)
- target_link_libraries(tdutils PUBLIC atomic)
+find_package(Atomics REQUIRED)
+if (ATOMICS_LIBRARIES)
+ target_link_libraries(tdutils PUBLIC "${ATOMICS_LIBRARIES}")
endif()
-install(TARGETS tdutils EXPORT TdTargets
+install(TARGETS tdutils EXPORT TdStaticTargets
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
)
-if (TD_TEST_FOLLY AND ABSL_FOUND)
+if (TD_TEST_FOLLY AND ABSL_FOUND AND TDUTILS_USE_EXTERNAL_DEPENDENCIES)
find_package(benchmark QUIET)
find_package(folly QUIET)
find_package(gflags QUIET)
diff --git a/protocols/Telegram/tdlib/td/tdutils/generate/auto/extension_to_mime_type.cpp b/protocols/Telegram/tdlib/td/tdutils/generate/auto/extension_to_mime_type.cpp
index 809b73df27..f95adb7e23 100644
--- a/protocols/Telegram/tdlib/td/tdutils/generate/auto/extension_to_mime_type.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/generate/auto/extension_to_mime_type.cpp
@@ -1,5 +1,5 @@
-/* ANSI-C code produced by gperf version 3.0.1 */
-/* Command-line: 'C:\\Util\\gperf.exe' -m100 --output-file=auto/extension_to_mime_type.cpp auto/extension_to_mime_type.gperf */
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: 'W:\\Test\\td\\vcpkg\\installed\\x64-windows\\tools\\gperf\\gperf.exe' -m100 --output-file=auto/extension_to_mime_type.cpp auto/extension_to_mime_type.gperf */
/* Computed positions: -k'1-4,6,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -26,7 +26,7 @@
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
#endif
#line 12 "auto/extension_to_mime_type.gperf"
@@ -86,7 +86,7 @@ inline
#endif
#endif
static unsigned int
-extension_hash (register const char *str, register unsigned int len)
+extension_hash (register const char *str, register size_t len)
{
static const unsigned short asso_values[] =
{
@@ -122,7 +122,7 @@ extension_hash (register const char *str, register unsigned int len)
3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376,
3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376, 3376
};
- register int hval = len;
+ register unsigned int hval = len;
switch (hval)
{
@@ -146,11 +146,8 @@ extension_hash (register const char *str, register unsigned int len)
return hval + asso_values[(unsigned char)str[len - 1]];
}
-#ifdef __GNUC__
-__inline
-#endif
const struct extension_and_mime_type *
-search_extension (register const char *str, register unsigned int len)
+search_extension (register const char *str, register size_t len)
{
enum
{
@@ -3036,9 +3033,9 @@ search_extension (register const char *str, register unsigned int len)
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = extension_hash (str, len);
+ register unsigned int key = extension_hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register const char *s = wordlist[key].extension;
diff --git a/protocols/Telegram/tdlib/td/tdutils/generate/auto/mime_type_to_extension.cpp b/protocols/Telegram/tdlib/td/tdutils/generate/auto/mime_type_to_extension.cpp
index c2e8686590..1138cd050a 100644
--- a/protocols/Telegram/tdlib/td/tdutils/generate/auto/mime_type_to_extension.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/generate/auto/mime_type_to_extension.cpp
@@ -1,5 +1,5 @@
-/* ANSI-C code produced by gperf version 3.0.1 */
-/* Command-line: 'C:\\Util\\gperf.exe' -m100 --output-file=auto/mime_type_to_extension.cpp auto/mime_type_to_extension.gperf */
+/* ANSI-C code produced by gperf version 3.1 */
+/* Command-line: 'W:\\Test\\td\\vcpkg\\installed\\x64-windows\\tools\\gperf\\gperf.exe' -m100 --output-file=auto/mime_type_to_extension.cpp auto/mime_type_to_extension.gperf */
/* Computed positions: -k'1,6-7,9-10,13-18,20,23,25-26,31,36,$' */
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
@@ -26,7 +26,7 @@
&& ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
&& ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
/* The character set is not based on ISO-646. */
-#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
+#error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gperf@gnu.org>."
#endif
#line 12 "auto/mime_type_to_extension.gperf"
@@ -86,7 +86,7 @@ inline
#endif
#endif
static unsigned int
-mime_type_hash (register const char *str, register unsigned int len)
+mime_type_hash (register const char *str, register size_t len)
{
static const unsigned short asso_values[] =
{
@@ -117,7 +117,7 @@ mime_type_hash (register const char *str, register unsigned int len)
4686, 4686, 4686, 4686, 4686, 4686, 4686, 4686, 4686, 4686,
4686, 4686, 4686, 4686, 4686, 4686
};
- register int hval = len;
+ register unsigned int hval = len;
switch (hval)
{
@@ -195,11 +195,8 @@ mime_type_hash (register const char *str, register unsigned int len)
return hval + asso_values[(unsigned char)str[len - 1]];
}
-#ifdef __GNUC__
-__inline
-#endif
const struct mime_type_and_extension *
-search_mime_type (register const char *str, register unsigned int len)
+search_mime_type (register const char *str, register size_t len)
{
enum
{
@@ -3010,9 +3007,9 @@ search_mime_type (register const char *str, register unsigned int len)
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
{
- register int key = mime_type_hash (str, len);
+ register unsigned int key = mime_type_hash (str, len);
- if (key <= MAX_HASH_VALUE && key >= 0)
+ if (key <= MAX_HASH_VALUE)
{
register const char *s = wordlist[key].mime_type;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/BufferedFd.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/BufferedFd.h
index 17bef41ffb..4270829cb4 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/BufferedFd.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/BufferedFd.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -24,7 +24,7 @@ template <class FdT>
class BufferedFdBase : public FdT {
public:
BufferedFdBase() = default;
- explicit BufferedFdBase(FdT &&fd_);
+ explicit BufferedFdBase(FdT &&fd);
// TODO: make move constructor and move assignment safer
Result<size_t> flush_read(size_t max_read = std::numeric_limits<size_t>::max()) TD_WARN_UNUSED_RESULT;
@@ -65,7 +65,7 @@ class BufferedFd final : public BufferedFdBase<FdT> {
public:
BufferedFd();
- explicit BufferedFd(FdT &&fd_);
+ explicit BufferedFd(FdT &&fd);
BufferedFd(BufferedFd &&) noexcept;
BufferedFd &operator=(BufferedFd &&) noexcept;
BufferedFd(const BufferedFd &) = delete;
@@ -93,7 +93,7 @@ class BufferedFd final : public BufferedFdBase<FdT> {
/*** BufferedFd ***/
template <class FdT>
-BufferedFdBase<FdT>::BufferedFdBase(FdT &&fd_) : FdT(std::move(fd_)) {
+BufferedFdBase<FdT>::BufferedFdBase(FdT &&fd) : FdT(std::move(fd)) {
}
template <class FdT>
@@ -166,7 +166,7 @@ BufferedFd<FdT>::BufferedFd() {
}
template <class FdT>
-BufferedFd<FdT>::BufferedFd(FdT &&fd_) : Parent(std::move(fd_)) {
+BufferedFd<FdT>::BufferedFd(FdT &&fd) : Parent(std::move(fd)) {
init();
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/ByteFlow.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/ByteFlow.h
index 0d228abcf4..5a685f5e11 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/ByteFlow.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/ByteFlow.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -25,6 +25,7 @@ class ByteFlowInterface {
virtual size_t get_write_size() = 0;
virtual void reset_need_size() {
}
+
ByteFlowInterface() = default;
ByteFlowInterface(const ByteFlowInterface &) = delete;
ByteFlowInterface &operator=(const ByteFlowInterface &) = delete;
@@ -139,6 +140,7 @@ class ByteFlowBaseCommon : public ByteFlowInterface {
bool can_read{true};
bool can_write{true};
Options options_;
+
void finish(Status status) {
stop_flag_ = true;
need_size_ = 0;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/ChainScheduler.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/ChainScheduler.h
index a7624bb97b..d30b1a062b 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/ChainScheduler.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/ChainScheduler.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -9,8 +9,8 @@
#include "td/utils/algorithm.h"
#include "td/utils/common.h"
#include "td/utils/Container.h"
+#include "td/utils/FlatHashMap.h"
#include "td/utils/FlatHashSet.h"
-#include "td/utils/HashTableUtils.h"
#include "td/utils/List.h"
#include "td/utils/logging.h"
#include "td/utils/optional.h"
@@ -19,7 +19,6 @@
#include "td/utils/VectorQueue.h"
#include <functional>
-#include <unordered_map>
namespace td {
@@ -50,7 +49,7 @@ class ChainScheduler final : public ChainSchedulerBase {
template <class F>
void for_each(F &&f) {
- tasks_.for_each([&f](auto, Task &task) { f(task.extra); });
+ tasks_.for_each([&f](uint64, Task &task) { f(task.extra); });
}
template <class F>
@@ -141,11 +140,19 @@ class ChainScheduler final : public ChainSchedulerBase {
vector<TaskChainInfo> chains;
ExtraT extra;
};
- std::unordered_map<ChainId, ChainInfo, Hash<ChainId>> chains_;
- std::unordered_map<ChainId, TaskId, Hash<ChainId>> limited_tasks_;
+ FlatHashMap<ChainId, unique_ptr<ChainInfo>> chains_;
+ FlatHashMap<ChainId, TaskId> limited_tasks_;
Container<Task> tasks_;
VectorQueue<TaskId> pending_tasks_;
+ ChainInfo &get_chain_info(ChainId chain_id) {
+ auto &chain = chains_[chain_id];
+ if (chain == nullptr) {
+ chain = make_unique<ChainInfo>();
+ }
+ return *chain;
+ }
+
void try_start_task(TaskId task_id) {
auto *task = tasks_.get(task_id);
CHECK(task != nullptr);
@@ -172,7 +179,7 @@ class ChainScheduler final : public ChainSchedulerBase {
void do_start_task(TaskId task_id, Task *task) {
for (TaskChainInfo &task_chain_info : task->chains) {
- ChainInfo &chain_info = chains_[task_chain_info.chain_id];
+ ChainInfo &chain_info = get_chain_info(task_chain_info.chain_id);
chain_info.active_tasks++;
task_chain_info.chain_node.generation = chain_info.generation;
}
@@ -255,14 +262,14 @@ class ChainScheduler final : public ChainSchedulerBase {
};
template <class ExtraT>
-typename ChainScheduler<ExtraT>::TaskId ChainScheduler<ExtraT>::create_task(Span<ChainScheduler::ChainId> chains,
- ExtraT extra) {
+typename ChainScheduler<ExtraT>::TaskId ChainScheduler<ExtraT>::create_task(Span<ChainId> chains, ExtraT extra) {
auto task_id = tasks_.create();
Task &task = *tasks_.get(task_id);
task.extra = std::move(extra);
- task.chains = transform(chains, [&](auto chain_id) {
+ task.chains = transform(chains, [&](ChainId chain_id) {
+ CHECK(chain_id != 0);
TaskChainInfo task_chain_info;
- ChainInfo &chain_info = chains_[chain_id];
+ ChainInfo &chain_info = get_chain_info(chain_id);
task_chain_info.chain_id = chain_id;
task_chain_info.chain_info = &chain_info;
task_chain_info.chain_node.task_id = task_id;
@@ -281,7 +288,7 @@ typename ChainScheduler<ExtraT>::TaskId ChainScheduler<ExtraT>::create_task(Span
// TODO: return reference
template <class ExtraT>
-ExtraT *ChainScheduler<ExtraT>::get_task_extra(ChainScheduler::TaskId task_id) { // may return nullptr
+ExtraT *ChainScheduler<ExtraT>::get_task_extra(TaskId task_id) { // may return nullptr
auto *task = tasks_.get(task_id);
if (task == nullptr) {
return nullptr;
@@ -310,7 +317,7 @@ optional<ChainSchedulerBase::TaskWithParents> ChainScheduler<ExtraT>::start_next
}
template <class ExtraT>
-void ChainScheduler<ExtraT>::finish_task(ChainScheduler::TaskId task_id) {
+void ChainScheduler<ExtraT>::finish_task(TaskId task_id) {
auto *task = tasks_.get(task_id);
CHECK(task != nullptr);
CHECK(to_start_.empty());
@@ -328,7 +335,7 @@ void ChainScheduler<ExtraT>::finish_task(ChainScheduler::TaskId task_id) {
}
template <class ExtraT>
-void ChainScheduler<ExtraT>::reset_task(ChainScheduler::TaskId task_id) {
+void ChainScheduler<ExtraT>::reset_task(TaskId task_id) {
CHECK(to_start_.empty());
auto *task = tasks_.get(task_id);
CHECK(task != nullptr);
@@ -351,15 +358,17 @@ StringBuilder &operator<<(StringBuilder &sb, ChainScheduler<ExtraT> &scheduler)
// 1 print chains
sb << '\n';
for (auto &it : scheduler.chains_) {
+ CHECK(it.second != nullptr);
sb << "ChainId{" << it.first << "}";
- sb << " active_cnt = " << it.second.active_tasks;
- sb << " g = " << it.second.generation;
+ sb << " active_cnt = " << it.second->active_tasks;
+ sb << " g = " << it.second->generation;
sb << ':';
- it.second.chain.foreach(
- [&](auto task_id, auto generation) { sb << ' ' << *scheduler.get_task_extra(task_id) << ':' << generation; });
+ it.second->chain.foreach([&](typename ChainScheduler<ExtraT>::TaskId task_id, uint64 generation) {
+ sb << ' ' << *scheduler.get_task_extra(task_id) << ':' << generation;
+ });
sb << '\n';
}
- scheduler.tasks_.for_each([&](auto id, auto &task) {
+ scheduler.tasks_.for_each([&](uint64, typename ChainScheduler<ExtraT>::Task &task) {
sb << "Task: " << task.extra;
sb << " state = " << static_cast<int>(task.state);
for (auto &task_chain_info : task.chains) {
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/ConcurrentHashTable.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/ConcurrentHashTable.h
index 86752ed599..0dfbbe34a5 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/ConcurrentHashTable.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/ConcurrentHashTable.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -113,7 +113,7 @@ class ConcurrentHashMap {
}
static std::string get_name() {
- return "ConcurrrentHashMap";
+ return "ConcurrentHashMap";
}
static KeyT empty_key() {
@@ -308,7 +308,6 @@ class ConcurrentHashMap {
continue;
}
auto node_key = node.key.load(std::memory_order_relaxed);
- //LOG(ERROR) << node_key << " " << node_key;
auto ok = migrate_to_hash_map_->with_value(
node_key, true, [&](auto &node_value) { node_value.store(old_value, std::memory_order_relaxed); });
LOG_CHECK(ok) << "Migration overflow";
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/FileLog.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/FileLog.cpp
index b89edcfa48..150a2906a5 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/FileLog.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/FileLog.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -98,7 +98,7 @@ void FileLog::do_append(int log_level, CSlice slice) {
auto total_time = Time::now() - start_time;
if (total_time >= 0.1 && log_level >= 1) {
auto thread_id = get_thread_id();
- auto r_size = fd_.write(PSLICE() << "[ 1][t" << (0 <= thread_id && thread_id < 10 ? " " : "") << thread_id
+ auto r_size = fd_.write(PSLICE() << "[ 2][t" << (0 <= thread_id && thread_id < 10 ? " " : "") << thread_id
<< "] !!! Previous logging took " << total_time << " seconds !!!\n");
r_size.ignore();
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMap.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMap.h
index aa3392831f..6ea919a476 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMap.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMap.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -17,7 +17,7 @@
namespace td {
template <class KeyT, class ValueT, class HashT = Hash<KeyT>, class EqT = std::equal_to<KeyT>>
-using FlatHashMap = FlatHashTable<MapNode<KeyT, ValueT>, HashT, EqT>;
+using FlatHashMap = FlatHashTable<MapNode<KeyT, ValueT, EqT>, HashT, EqT>;
//using FlatHashMap = FlatHashMapChunks<KeyT, ValueT, HashT, EqT>;
//using FlatHashMap = std::unordered_map<KeyT, ValueT, HashT, EqT>;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMapChunks.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMapChunks.h
index af43ebbae2..fcf9d89d60 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMapChunks.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashMapChunks.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -257,7 +257,7 @@ class FlatHashTableChunks {
}
Iterator find(const KeyT &key) {
- if (empty() || is_hash_table_key_empty(key)) {
+ if (empty() || is_hash_table_key_empty<EqT>(key)) {
return end();
}
const auto hash = calc_hash(key);
@@ -326,7 +326,7 @@ class FlatHashTableChunks {
template <class... ArgsT>
std::pair<Iterator, bool> emplace(KeyT key, ArgsT &&...args) {
- CHECK(!is_hash_table_key_empty(key));
+ CHECK(!is_hash_table_key_empty<EqT>(key));
auto it = find(key);
if (it != end()) {
return {it, false};
@@ -399,13 +399,16 @@ class FlatHashTableChunks {
}
template <class F>
- void remove_if(F &&f) {
+ bool remove_if(F &&f) {
+ bool is_removed = false;
for (auto it = nodes_.begin(), end = nodes_.end(); it != end; ++it) {
if (!it->empty() && f(it->get_public())) {
erase_node(it);
+ is_removed = true;
}
}
try_shrink();
+ return is_removed;
}
private:
@@ -562,14 +565,14 @@ class FlatHashTableChunks {
};
template <class KeyT, class ValueT, class HashT = Hash<KeyT>, class EqT = std::equal_to<KeyT>>
-using FlatHashMapChunks = FlatHashTableChunks<MapNode<KeyT, ValueT>, HashT, EqT>;
+using FlatHashMapChunks = FlatHashTableChunks<MapNode<KeyT, ValueT, EqT>, HashT, EqT>;
template <class KeyT, class HashT = Hash<KeyT>, class EqT = std::equal_to<KeyT>>
-using FlatHashSetChunks = FlatHashTableChunks<SetNode<KeyT>, HashT, EqT>;
+using FlatHashSetChunks = FlatHashTableChunks<SetNode<KeyT, EqT>, HashT, EqT>;
template <class NodeT, class HashT, class EqT, class FuncT>
-void table_remove_if(FlatHashTableChunks<NodeT, HashT, EqT> &table, FuncT &&func) {
- table.remove_if(func);
+bool table_remove_if(FlatHashTableChunks<NodeT, HashT, EqT> &table, FuncT &&func) {
+ return table.remove_if(func);
}
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashSet.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashSet.h
index 80fe5137eb..ca4398fd5d 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashSet.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashSet.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -17,7 +17,7 @@
namespace td {
template <class KeyT, class HashT = Hash<KeyT>, class EqT = std::equal_to<KeyT>>
-using FlatHashSet = FlatHashTable<SetNode<KeyT>, HashT, EqT>;
+using FlatHashSet = FlatHashTable<SetNode<KeyT, EqT>, HashT, EqT>;
//using FlatHashSet = FlatHashSetChunks<KeyT, HashT, EqT>;
//using FlatHashSet = std::unordered_set<KeyT, HashT, EqT>;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashTable.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashTable.h
index da12cf98e8..cd7e7509ae 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashTable.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/FlatHashTable.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -308,7 +308,7 @@ class FlatHashTable {
template <class... ArgsT>
std::pair<NodePointer, bool> emplace(KeyT key, ArgsT &&...args) {
- CHECK(!is_hash_table_key_empty(key));
+ CHECK(!is_hash_table_key_empty<EqT>(key));
if (unlikely(bucket_count_mask_ == 0)) {
CHECK(used_node_count_ == 0);
resize(8);
@@ -385,9 +385,9 @@ class FlatHashTable {
}
template <class F>
- void remove_if(F &&f) {
+ bool remove_if(F &&f) {
if (empty()) {
- return;
+ return false;
}
auto it = begin_impl();
@@ -401,9 +401,11 @@ class FlatHashTable {
} while (!it->empty());
}
auto first_empty = it;
+ bool is_removed = false;
while (it != end) {
if (!it->empty() && f(it->get_public())) {
erase_node(it);
+ is_removed = true;
} else {
++it;
}
@@ -411,11 +413,13 @@ class FlatHashTable {
for (it = nodes_; it != first_empty;) {
if (!it->empty() && f(it->get_public())) {
erase_node(it);
+ is_removed = true;
} else {
++it;
}
}
try_shrink();
+ return is_removed;
}
private:
@@ -447,7 +451,7 @@ class FlatHashTable {
}
NodeT *find_impl(const KeyT &key) {
- if (unlikely(nodes_ == nullptr) || is_hash_table_key_empty(key)) {
+ if (unlikely(nodes_ == nullptr) || is_hash_table_key_empty<EqT>(key)) {
return nullptr;
}
auto bucket = calc_bucket(key);
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/FloodControlStrict.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/FloodControlStrict.h
index e21688717f..ba5be8272f 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/FloodControlStrict.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/FloodControlStrict.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -12,7 +12,7 @@
namespace td {
-// More strict implementaions of flood control than FloodControlFast.
+// More strict implementations of flood control than FloodControlFast.
// Should be just fine for small counters.
class FloodControlStrict {
public:
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.cpp
index d837b7ae26..d4ad3c51f8 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -35,12 +35,11 @@ bool GzipByteFlow::loop() {
auto r_state = gzip_.run();
auto output_size = gzip_.flush_output();
if (output_size) {
- uncommitted_size_ += output_size;
- total_output_size_ += output_size;
- if (total_output_size_ > max_output_size_) {
+ if (output_size > max_output_size_ || total_output_size_ > max_output_size_ - output_size) {
finish(Status::Error("Max output size limit exceeded"));
return false;
}
+ total_output_size_ += output_size;
output_.confirm_append(output_size);
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.h
index 77ea62855d..c6611bec3e 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/GzipByteFlow.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -38,7 +38,6 @@ class GzipByteFlow final : public ByteFlowBase {
private:
Gzip gzip_;
- size_t uncommitted_size_ = 0;
size_t total_output_size_ = 0;
size_t max_output_size_ = std::numeric_limits<size_t>::max();
};
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/Hash.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/Hash.h
index 58c10a73ba..969773018f 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/Hash.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/Hash.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -15,7 +15,7 @@
#include <utility>
namespace td {
-// A simple wrapper for absl::flat_hash_map, std::unordered_map and probably some our implementaion of hash map in
+// A simple wrapper for absl::flat_hash_map, std::unordered_map and probably some our implementation of hash map in
// the future
// We will introduce out own Hashing utility like an absl one.
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/HashTableUtils.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/HashTableUtils.h
index 8e11f9840f..21d4104daf 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/HashTableUtils.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/HashTableUtils.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -13,9 +13,9 @@
namespace td {
-template <class KeyT>
+template <class EqT, class KeyT>
bool is_hash_table_key_empty(const KeyT &key) {
- return key == KeyT();
+ return EqT()(key, KeyT());
}
inline uint32 randomize_hash(uint32 h) {
@@ -69,4 +69,8 @@ inline uint32 Hash<string>::operator()(const string &value) const {
return static_cast<uint32>(std::hash<string>()(value));
}
+inline uint32 combine_hashes(uint32 first_hash, uint32 second_hash) {
+ return first_hash * 2023654985u + second_hash;
+}
+
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/Hints.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/Hints.cpp
index e6ddc69e37..4ef7865aa7 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/Hints.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/Hints.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -115,7 +115,7 @@ void Hints::add_search_results(vector<KeyT> &results, const string &word,
LOG(DEBUG) << "Search for word " << word;
auto it = word_to_keys.lower_bound(word);
while (it != word_to_keys.end() && begins_with(it->first, word)) {
- results.insert(results.end(), it->second.begin(), it->second.end());
+ append(results, it->second);
++it;
}
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.cpp
new file mode 100644
index 0000000000..da290ae3a7
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/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/protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.h
new file mode 100644
index 0000000000..a2daf0784f
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/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
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.cpp
index ad721f497c..a0aebb61c3 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -9,8 +9,7 @@
#include "td/utils/misc.h"
#include "td/utils/ScopeGuard.h"
#include "td/utils/SliceBuilder.h"
-
-#include <cstring>
+#include "td/utils/utf8.h"
namespace td {
@@ -140,44 +139,26 @@ Result<MutableSlice> json_string_decode(Parser &parser) {
if (!parser.try_skip('"')) {
return Status::Error("Opening '\"' expected");
}
- auto *cur_src = parser.data().data();
- auto *end_src = parser.data().end();
- auto *end = cur_src;
- while (end < end_src && end[0] != '"') {
- if (end[0] == '\\') {
- end++;
- }
- end++;
- }
- if (end >= end_src) {
- return Status::Error("Closing '\"' not found");
- }
- parser.advance(end + 1 - cur_src);
- end_src = end;
-
- auto *cur_dest = cur_src;
- auto *begin_dest = cur_src;
-
- while (cur_src != end_src) {
- auto *slash = static_cast<char *>(std::memchr(cur_src, '\\', end_src - cur_src));
- if (slash == nullptr) {
- slash = end_src;
+ auto data = parser.data();
+ auto *result_start = data.ubegin();
+ auto *cur_src = result_start;
+ auto *cur_dest = result_start;
+ auto *end = data.uend();
+
+ while (true) {
+ if (cur_src == end) {
+ return Status::Error("Closing '\"' not found");
+ }
+ if (*cur_src == '"') {
+ parser.advance(cur_src + 1 - result_start);
+ return data.substr(0, cur_dest - result_start);
}
- std::memmove(cur_dest, cur_src, slash - cur_src);
- cur_dest += slash - cur_src;
- cur_src = slash;
- if (cur_src != end_src) {
+ if (*cur_src == '\\') {
cur_src++;
- if (cur_src == end_src) {
- // TODO UNREACHABLE();
- return Status::Error("Unexpected end of string");
+ if (cur_src == end) {
+ return Status::Error("Closing '\"' not found");
}
switch (*cur_src) {
- case '"':
- case '\\':
- case '/':
- *cur_dest++ = *cur_src++;
- break;
case 'b':
*cur_dest++ = '\b';
cur_src++;
@@ -200,10 +181,10 @@ Result<MutableSlice> json_string_decode(Parser &parser) {
break;
case 'u': {
cur_src++;
- if (cur_src + 4 > end_src) {
+ if (cur_src + 4 > end) {
return Status::Error("\\u has less than 4 symbols");
}
- int num = 0;
+ uint32 num = 0;
for (int i = 0; i < 4; i++, cur_src++) {
int d = hex_to_int(*cur_src);
if (d == 16) {
@@ -212,7 +193,7 @@ Result<MutableSlice> json_string_decode(Parser &parser) {
num = num * 16 + d;
}
if (0xD7FF < num && num < 0xE000) {
- if (cur_src + 6 <= end_src && cur_src[0] == '\\' && cur_src[1] == 'u') {
+ if (cur_src + 6 <= end && cur_src[0] == '\\' && cur_src[1] == 'u') {
cur_src += 2;
int new_num = 0;
for (int i = 0; i < 4; i++, cur_src++) {
@@ -230,76 +211,46 @@ Result<MutableSlice> json_string_decode(Parser &parser) {
}
}
- if (num < 128) {
- *cur_dest++ = static_cast<char>(num);
- } else if (num < 0x800) {
- *cur_dest++ = static_cast<char>(0xc0 + (num >> 6));
- *cur_dest++ = static_cast<char>(0x80 + (num & 63));
- } else if (num <= 0xffff) {
- *cur_dest++ = static_cast<char>(0xe0 + (num >> 12));
- *cur_dest++ = static_cast<char>(0x80 + ((num >> 6) & 63));
- *cur_dest++ = static_cast<char>(0x80 + (num & 63));
- } else {
- *cur_dest++ = static_cast<char>(0xf0 + (num >> 18));
- *cur_dest++ = static_cast<char>(0x80 + ((num >> 12) & 63));
- *cur_dest++ = static_cast<char>(0x80 + ((num >> 6) & 63));
- *cur_dest++ = static_cast<char>(0x80 + (num & 63));
- }
+ cur_dest = append_utf8_character_unsafe(cur_dest, num);
break;
}
+ default:
+ *cur_dest++ = *cur_src++;
+ break;
}
+ } else {
+ *cur_dest++ = *cur_src++;
}
}
- CHECK(cur_dest <= end_src);
- return MutableSlice(begin_dest, cur_dest);
+ UNREACHABLE();
+ return {};
}
Status json_string_skip(Parser &parser) {
if (!parser.try_skip('"')) {
return Status::Error("Opening '\"' expected");
}
- auto *begin_src = parser.data().data();
- auto *cur_src = begin_src;
- auto *end_src = parser.data().end();
- auto *end = cur_src;
- while (end < end_src && *end != '"') {
- if (*end == '\\') {
- end++;
- }
- end++;
- }
- if (end >= end_src) {
- return Status::Error("Closing '\"' not found");
- }
- parser.advance(end + 1 - cur_src);
- end_src = end;
+ auto data = parser.data();
+ auto *cur_src = data.ubegin();
+ auto *end = data.uend();
- while (cur_src != end_src) {
- auto *slash = static_cast<char *>(std::memchr(cur_src, '\\', end_src - cur_src));
- if (slash == nullptr) {
- slash = end_src;
+ while (true) {
+ if (cur_src == end) {
+ return Status::Error("Closing '\"' not found");
+ }
+ if (*cur_src == '"') {
+ parser.advance(cur_src + 1 - data.ubegin());
+ return Status::OK();
}
- cur_src = slash;
- if (cur_src != end_src) {
+ if (*cur_src == '\\') {
cur_src++;
- if (cur_src == end_src) {
- // TODO UNREACHABLE();
- return Status::Error("Unexpected end of string");
+ if (cur_src == end) {
+ return Status::Error("Closing '\"' not found");
}
switch (*cur_src) {
- case '"':
- case '\\':
- case '/':
- case 'b':
- case 'f':
- case 'n':
- case 'r':
- case 't':
- cur_src++;
- break;
case 'u': {
cur_src++;
- if (cur_src + 4 > end_src) {
+ if (cur_src + 4 > end) {
return Status::Error("\\u has less than 4 symbols");
}
int num = 0;
@@ -311,7 +262,7 @@ Status json_string_skip(Parser &parser) {
num = num * 16 + d;
}
if (0xD7FF < num && num < 0xE000) {
- if (cur_src + 6 <= end_src && cur_src[0] == '\\' && cur_src[1] == 'u') {
+ if (cur_src + 6 <= end && cur_src[0] == '\\' && cur_src[1] == 'u') {
cur_src += 2;
int new_num = 0;
for (int i = 0; i < 4; i++, cur_src++) {
@@ -330,9 +281,15 @@ Status json_string_skip(Parser &parser) {
}
break;
}
+ default:
+ cur_src++;
+ break;
}
+ } else {
+ cur_src++;
}
}
+ UNREACHABLE();
return Status::OK();
}
@@ -365,7 +322,7 @@ Result<JsonValue> do_json_decode(Parser &parser, int32 max_depth) {
case '[': {
parser.skip('[');
parser.skip_whitespaces();
- std::vector<JsonValue> res;
+ vector<JsonValue> res;
if (parser.try_skip(']')) {
return JsonValue::create_array(std::move(res));
}
@@ -394,21 +351,21 @@ Result<JsonValue> do_json_decode(Parser &parser, int32 max_depth) {
case '{': {
parser.skip('{');
parser.skip_whitespaces();
- std::vector<std::pair<MutableSlice, JsonValue>> res;
if (parser.try_skip('}')) {
- return JsonValue::make_object(std::move(res));
+ return JsonValue::make_object(JsonObject());
}
+ vector<std::pair<Slice, JsonValue>> field_values;
while (true) {
if (parser.empty()) {
return Status::Error("Unexpected string end");
}
- TRY_RESULT(key, json_string_decode(parser));
+ TRY_RESULT(field, json_string_decode(parser));
parser.skip_whitespaces();
if (!parser.try_skip(':')) {
return Status::Error("':' expected");
}
TRY_RESULT(value, do_json_decode(parser, max_depth - 1));
- res.emplace_back(key, std::move(value));
+ field_values.emplace_back(field, std::move(value));
parser.skip_whitespaces();
if (parser.try_skip('}')) {
@@ -423,7 +380,7 @@ Result<JsonValue> do_json_decode(Parser &parser, int32 max_depth) {
}
return Status::Error("Unexpected symbol while parsing JSON Object");
}
- return JsonValue::make_object(std::move(res));
+ return JsonValue::make_object(JsonObject(std::move(field_values)));
}
case '-':
case '+':
@@ -585,26 +542,38 @@ Slice JsonValue::get_type_name(Type type) {
}
}
-bool has_json_object_field(const JsonObject &object, Slice name) {
- for (auto &field_value : object) {
+JsonObject::JsonObject(vector<std::pair<Slice, JsonValue>> &&field_values) : field_values_(std::move(field_values)) {
+}
+
+size_t JsonObject::field_count() const {
+ return field_values_.size();
+}
+
+JsonValue JsonObject::extract_field(Slice name) {
+ for (auto &field_value : field_values_) {
if (field_value.first == name) {
- return true;
+ return std::move(field_value.second);
}
}
- return false;
+ return JsonValue();
}
-JsonValue get_json_object_field_force(JsonObject &object, Slice name) {
- for (auto &field_value : object) {
+Result<JsonValue> JsonObject::extract_optional_field(Slice name, JsonValueType type) {
+ for (auto &field_value : field_values_) {
if (field_value.first == name) {
+ if (type != JsonValue::Type::Null && field_value.second.type() != type) {
+ return Status::Error(400, PSLICE()
+ << "Field \"" << name << "\" must be of type " << JsonValue::get_type_name(type));
+ }
+
return std::move(field_value.second);
}
}
return JsonValue();
}
-Result<JsonValue> get_json_object_field(JsonObject &object, Slice name, JsonValue::Type type, bool is_optional) {
- for (auto &field_value : object) {
+Result<JsonValue> JsonObject::extract_required_field(Slice name, JsonValueType type) {
+ for (auto &field_value : field_values_) {
if (field_value.first == name) {
if (type != JsonValue::Type::Null && field_value.second.type() != type) {
return Status::Error(400, PSLICE()
@@ -614,83 +583,163 @@ Result<JsonValue> get_json_object_field(JsonObject &object, Slice name, JsonValu
return std::move(field_value.second);
}
}
- if (!is_optional) {
- return Status::Error(400, PSLICE() << "Can't find field \"" << name << "\"");
+ return Status::Error(400, PSLICE() << "Can't find field \"" << name << "\"");
+}
+
+const JsonValue *JsonObject::get_field(Slice name) const {
+ for (auto &field_value : field_values_) {
+ if (field_value.first == name) {
+ return &field_value.second;
+ }
}
- return JsonValue();
+ return nullptr;
+}
+
+bool JsonObject::has_field(Slice name) const {
+ return get_field(name) != nullptr;
}
-Result<bool> get_json_object_bool_field(JsonObject &object, Slice name, bool is_optional, bool default_value) {
- TRY_RESULT(value, get_json_object_field(object, name, JsonValue::Type::Boolean, is_optional));
- if (value.type() == JsonValue::Type::Null) {
- return default_value;
+Result<bool> JsonObject::get_optional_bool_field(Slice name, bool default_value) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::Boolean) {
+ return value->get_boolean();
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type Boolean");
}
- return value.get_boolean();
+ return default_value;
}
-Result<int32> get_json_object_int_field(JsonObject &object, Slice name, bool is_optional, int32 default_value) {
- for (auto &field_value : object) {
- if (field_value.first == name) {
- if (field_value.second.type() == JsonValue::Type::String) {
- return to_integer_safe<int32>(field_value.second.get_string());
- }
- if (field_value.second.type() == JsonValue::Type::Number) {
- return to_integer_safe<int32>(field_value.second.get_number());
- }
+Result<bool> JsonObject::get_required_bool_field(Slice name) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::Boolean) {
+ return value->get_boolean();
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type Boolean");
+ }
+ return Status::Error(400, PSLICE() << "Can't find field \"" << name << '"');
+}
+
+template <class T>
+static Result<T> get_integer_field(Slice name, Slice value) {
+ auto r_int = to_integer_safe<T>(value);
+ if (r_int.is_ok()) {
+ return r_int.ok();
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be a valid Number");
+}
- return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type Number");
+Result<int32> JsonObject::get_optional_int_field(Slice name, int32 default_value) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::String) {
+ return get_integer_field<int32>(name, value->get_string());
+ }
+ if (value->type() == JsonValue::Type::Number) {
+ return get_integer_field<int32>(name, value->get_number());
}
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be a Number");
}
- if (is_optional) {
- return default_value;
+ return default_value;
+}
+
+Result<int32> JsonObject::get_required_int_field(Slice name) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::String) {
+ return get_integer_field<int32>(name, value->get_string());
+ }
+ if (value->type() == JsonValue::Type::Number) {
+ return get_integer_field<int32>(name, value->get_number());
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be a Number");
}
- return Status::Error(400, PSLICE() << "Can't find field \"" << name << "\"");
+ return Status::Error(400, PSLICE() << "Can't find field \"" << name << '"');
}
-Result<int64> get_json_object_long_field(JsonObject &object, Slice name, bool is_optional, int64 default_value) {
- for (auto &field_value : object) {
- if (field_value.first == name) {
- if (field_value.second.type() == JsonValue::Type::String) {
- return to_integer_safe<int64>(field_value.second.get_string());
- }
- if (field_value.second.type() == JsonValue::Type::Number) {
- return to_integer_safe<int64>(field_value.second.get_number());
- }
+Result<int64> JsonObject::get_optional_long_field(Slice name, int64 default_value) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::String) {
+ return get_integer_field<int64>(name, value->get_string());
+ }
+ if (value->type() == JsonValue::Type::Number) {
+ return get_integer_field<int64>(name, value->get_number());
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be a Number");
+ }
+ return default_value;
+}
- return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be a Number");
+Result<int64> JsonObject::get_required_long_field(Slice name) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::String) {
+ return get_integer_field<int64>(name, value->get_string());
+ }
+ if (value->type() == JsonValue::Type::Number) {
+ return get_integer_field<int64>(name, value->get_number());
}
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be a Number");
}
- if (is_optional) {
- return default_value;
+ return Status::Error(400, PSLICE() << "Can't find field \"" << name << '"');
+}
+
+Result<double> JsonObject::get_optional_double_field(Slice name, double default_value) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::Number) {
+ return to_double(value->get_number());
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type Number");
}
- return Status::Error(400, PSLICE() << "Can't find field \"" << name << "\"");
+ return default_value;
}
-Result<double> get_json_object_double_field(JsonObject &object, Slice name, bool is_optional, double default_value) {
- TRY_RESULT(value, get_json_object_field(object, name, JsonValue::Type::Number, is_optional));
- if (value.type() == JsonValue::Type::Null) {
- return default_value;
+Result<double> JsonObject::get_required_double_field(Slice name) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::Number) {
+ return to_double(value->get_number());
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type Number");
}
- return to_double(value.get_number());
+ return Status::Error(400, PSLICE() << "Can't find field \"" << name << '"');
}
-Result<string> get_json_object_string_field(JsonObject &object, Slice name, bool is_optional, string default_value) {
- for (auto &field_value : object) {
- if (field_value.first == name) {
- if (field_value.second.type() == JsonValue::Type::String) {
- return field_value.second.get_string().str();
- }
- if (field_value.second.type() == JsonValue::Type::Number) {
- return field_value.second.get_number().str();
- }
+Result<string> JsonObject::get_optional_string_field(Slice name, string default_value) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::String) {
+ return value->get_string().str();
+ }
+ if (value->type() == JsonValue::Type::Number) {
+ return value->get_number().str();
+ }
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type String");
+ }
+ return std::move(default_value);
+}
- return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type String");
+Result<string> JsonObject::get_required_string_field(Slice name) const {
+ auto value = get_field(name);
+ if (value != nullptr) {
+ if (value->type() == JsonValue::Type::String) {
+ return value->get_string().str();
+ }
+ if (value->type() == JsonValue::Type::Number) {
+ return value->get_number().str();
}
+ return Status::Error(400, PSLICE() << "Field \"" << name << "\" must be of type String");
}
- if (is_optional) {
- return default_value;
+ return Status::Error(400, PSLICE() << "Can't find field \"" << name << '"');
+}
+
+void JsonObject::foreach(const std::function<void(Slice name, const JsonValue &value)> &callback) const {
+ for (auto &field_value : field_values_) {
+ callback(field_value.first, field_value.second);
}
- return Status::Error(400, PSLICE() << "Can't find field \"" << name << "\"");
}
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.h
index 053f4a0266..3989cf76e7 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/JsonBuilder.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -14,6 +14,7 @@
#include "td/utils/Status.h"
#include "td/utils/StringBuilder.h"
+#include <functional>
#include <new>
#include <type_traits>
#include <utility>
@@ -401,7 +402,7 @@ class JsonObjectScope final : public JsonScope {
*sb_ << "}";
}
template <class T>
- JsonObjectScope &operator()(Slice key, T &&value) {
+ JsonObjectScope &operator()(Slice field, T &&value) {
CHECK(is_active());
if (is_first_) {
*sb_ << ",";
@@ -409,7 +410,7 @@ class JsonObjectScope final : public JsonScope {
is_first_ = true;
}
jb_->print_offset();
- jb_->enter_value() << key;
+ jb_->enter_value() << field;
if (jb_->is_pretty()) {
*sb_ << " : ";
} else {
@@ -418,10 +419,10 @@ class JsonObjectScope final : public JsonScope {
jb_->enter_value() << value;
return *this;
}
- JsonObjectScope &operator<<(const JsonRaw &key_value) {
+ JsonObjectScope &operator<<(const JsonRaw &field_value) {
CHECK(is_active());
is_first_ = true;
- jb_->enter_value() << key_value;
+ jb_->enter_value() << field_value;
return *this;
}
@@ -451,12 +452,62 @@ inline JsonArrayScope JsonBuilder::enter_array() {
class JsonValue;
-using JsonObject = vector<std::pair<MutableSlice, JsonValue>>;
+enum class JsonValueType { Null, Number, Boolean, String, Array, Object };
+
using JsonArray = vector<JsonValue>;
+class JsonObject {
+ const JsonValue *get_field(Slice name) const;
+
+ public:
+ vector<std::pair<Slice, JsonValue>> field_values_;
+
+ JsonObject() = default;
+
+ explicit JsonObject(vector<std::pair<Slice, JsonValue>> &&field_values);
+
+ JsonObject(const JsonObject &) = delete;
+ JsonObject &operator=(const JsonObject &) = delete;
+ JsonObject(JsonObject &&) = default;
+ JsonObject &operator=(JsonObject &&) = default;
+ ~JsonObject() = default;
+
+ size_t field_count() const;
+
+ JsonValue extract_field(Slice name);
+
+ Result<JsonValue> extract_optional_field(Slice name, JsonValueType type);
+
+ Result<JsonValue> extract_required_field(Slice name, JsonValueType type);
+
+ bool has_field(Slice name) const;
+
+ Result<bool> get_optional_bool_field(Slice name, bool default_value = false) const;
+
+ Result<bool> get_required_bool_field(Slice name) const;
+
+ Result<int32> get_optional_int_field(Slice name, int32 default_value = 0) const;
+
+ Result<int32> get_required_int_field(Slice name) const;
+
+ Result<int64> get_optional_long_field(Slice name, int64 default_value = 0) const;
+
+ Result<int64> get_required_long_field(Slice name) const;
+
+ Result<double> get_optional_double_field(Slice name, double default_value = 0.0) const;
+
+ Result<double> get_required_double_field(Slice name) const;
+
+ Result<string> get_optional_string_field(Slice name, string default_value = string()) const;
+
+ Result<string> get_required_string_field(Slice name) const;
+
+ void foreach(const std::function<void(Slice name, const JsonValue &value)> &callback) const;
+};
+
class JsonValue final : private Jsonable {
public:
- enum class Type { Null, Number, Boolean, String, Array, Object };
+ using Type = JsonValueType;
static Slice get_type_name(Type type);
@@ -584,8 +635,8 @@ class JsonValue final : private Jsonable {
}
case Type::Object: {
auto object = scope->enter_object();
- for (auto &key_value : get_object()) {
- object(key_value.first, key_value.second);
+ for (auto &field_value : get_object().field_values_) {
+ object(field_value.first, field_value.second);
}
break;
}
@@ -664,7 +715,7 @@ class JsonValue final : private Jsonable {
array_.~vector<JsonValue>();
break;
case Type::Object:
- object_.~vector<std::pair<MutableSlice, JsonValue>>();
+ object_.~JsonObject();
break;
}
type_ = Type::Null;
@@ -841,26 +892,4 @@ auto json_array(const A &a, F &&f) {
});
}
-bool has_json_object_field(const JsonObject &object, Slice name);
-
-JsonValue get_json_object_field_force(JsonObject &object, Slice name) TD_WARN_UNUSED_RESULT;
-
-Result<JsonValue> get_json_object_field(JsonObject &object, Slice name, JsonValue::Type type,
- bool is_optional = true) TD_WARN_UNUSED_RESULT;
-
-Result<bool> get_json_object_bool_field(JsonObject &object, Slice name, bool is_optional = true,
- bool default_value = false) TD_WARN_UNUSED_RESULT;
-
-Result<int32> get_json_object_int_field(JsonObject &object, Slice name, bool is_optional = true,
- int32 default_value = 0) TD_WARN_UNUSED_RESULT;
-
-Result<int64> get_json_object_long_field(JsonObject &object, Slice name, bool is_optional = true,
- int64 default_value = 0) TD_WARN_UNUSED_RESULT;
-
-Result<double> get_json_object_double_field(JsonObject &object, Slice name, bool is_optional = true,
- double default_value = 0.0) TD_WARN_UNUSED_RESULT;
-
-Result<string> get_json_object_string_field(JsonObject &object, Slice name, bool is_optional = true,
- string default_value = "") TD_WARN_UNUSED_RESULT;
-
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/MapNode.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/MapNode.h
index b6c65c812c..9d87aad829 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/MapNode.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/MapNode.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -15,7 +15,7 @@
namespace td {
-template <class KeyT, class ValueT, class Enable = void>
+template <class KeyT, class ValueT, class EqT, class Enable = void>
struct MapNode {
using first_type = KeyT;
using second_type = ValueT;
@@ -72,7 +72,7 @@ struct MapNode {
}
bool empty() const {
- return is_hash_table_key_empty(first);
+ return is_hash_table_key_empty<EqT>(first);
}
void clear() {
@@ -91,8 +91,8 @@ struct MapNode {
}
};
-template <class KeyT, class ValueT>
-struct MapNode<KeyT, ValueT, typename std::enable_if_t<(sizeof(KeyT) + sizeof(ValueT) > 28 * sizeof(void *))>> {
+template <class KeyT, class ValueT, class EqT>
+struct MapNode<KeyT, ValueT, EqT, typename std::enable_if_t<(sizeof(KeyT) + sizeof(ValueT) > 28 * sizeof(void *))>> {
struct Impl {
using first_type = KeyT;
using second_type = ValueT;
@@ -105,7 +105,7 @@ struct MapNode<KeyT, ValueT, typename std::enable_if_t<(sizeof(KeyT) + sizeof(Va
template <class InputKeyT, class... ArgsT>
Impl(InputKeyT &&key, ArgsT &&...args) : first(std::forward<InputKeyT>(key)) {
new (&second) ValueT(std::forward<ArgsT>(args)...);
- DCHECK(!is_hash_table_key_empty(first));
+ DCHECK(!is_hash_table_key_empty<EqT>(first));
}
Impl(const Impl &) = delete;
Impl &operator=(const Impl &) = delete;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/MpmcQueue.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/MpmcQueue.h
index a6d1bef7f1..1a08768dd6 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/MpmcQueue.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/MpmcQueue.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -324,7 +324,7 @@ class MpmcQueueOld {
char pad2[TD_CONCURRENCY_PAD - sizeof(std::atomic<Node *>)];
size_t block_size_;
HazardPointers<Node, 1> hazard_pointers_;
- // HazardPointers is already padded
+ // HazardPointers class is already padded
};
template <class T>
@@ -454,7 +454,7 @@ class MpmcQueue {
std::atomic<Node *> read_pos_{nullptr};
char pad2[TD_CONCURRENCY_PAD - sizeof(std::atomic<Node *>)];
HazardPointers<Node, 1> hazard_pointers_;
- // HazardPointers is already padded
+ // HazardPointers class is already padded
};
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/ObjectPool.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/ObjectPool.h
index 8f6f4c28ed..2d08d28344 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/ObjectPool.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/ObjectPool.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -14,7 +14,7 @@
#include <utility>
namespace td {
-// It is draft object pool implementaion
+// It is draft object pool implementation
//
// Compared with std::shared_ptr:
// + WeakPtr are much faster. Just pointer copy. No barriers, no atomics.
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/Promise.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/Promise.h
index 247593742c..ce4365d2a4 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/Promise.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/Promise.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -116,7 +116,7 @@ class LambdaPromise : public PromiseInterface<ValueT> {
}
template <class FromT>
- explicit LambdaPromise(FromT &&func) : func_(std::forward<FromT>(func)), state_(State::Ready) {
+ LambdaPromise(FromT &&func) : func_(std::forward<FromT>(func)), state_(State::Ready) {
}
private:
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h
index cbc218329c..a637a8366f 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/SetNode.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -14,7 +14,7 @@
namespace td {
-template <class KeyT, class Enable = void>
+template <class KeyT, class EqT, class Enable = void>
struct SetNode {
using public_key_type = KeyT;
using public_type = const KeyT;
@@ -54,7 +54,7 @@ struct SetNode {
}
bool empty() const {
- return is_hash_table_key_empty(first);
+ return is_hash_table_key_empty<EqT>(first);
}
void clear() {
@@ -67,8 +67,8 @@ struct SetNode {
}
};
-template <class KeyT>
-struct SetNode<KeyT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void *))>> {
+template <class KeyT, class EqT>
+struct SetNode<KeyT, EqT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void *))>> {
struct Impl {
using second_type = KeyT;
@@ -76,7 +76,7 @@ struct SetNode<KeyT, typename std::enable_if_t<(sizeof(KeyT) > 28 * sizeof(void
template <class InputKeyT>
explicit Impl(InputKeyT &&key) : first(std::forward<InputKeyT>(key)) {
- DCHECK(!is_hash_table_key_empty(first));
+ DCHECK(!is_hash_table_key_empty<EqT>(first));
}
Impl(const Impl &) = delete;
Impl &operator=(const Impl &) = delete;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp
index 941394e191..aa39c6284e 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -8,7 +8,6 @@
#include "td/utils/misc.h"
#include "td/utils/port/thread_local.h"
-#include "td/utils/Slice.h"
#include <cstdio>
#include <cstring>
@@ -51,6 +50,23 @@ StringBuilder &StringBuilder::operator<<(Slice slice) {
return *this;
}
+void StringBuilder::append_char(size_t count, char c) {
+ if (unlikely(!reserve(count))) {
+ if (end_ptr_ < current_ptr_) {
+ on_error();
+ return;
+ }
+ auto available_size = static_cast<size_t>(end_ptr_ + RESERVED_SIZE - 1 - current_ptr_);
+ if (count > available_size) {
+ error_flag_ = true;
+ count = available_size;
+ }
+ }
+
+ MutableSlice(current_ptr_, count).fill(c);
+ current_ptr_ += count;
+}
+
template <class T>
static char *print_uint(char *current_ptr, T x) {
if (x < 100) {
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.h
index 2339ef71cb..9251ba2e85 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -13,12 +13,14 @@
#include <cstdlib>
#include <memory>
#include <type_traits>
+#include <utility>
namespace td {
class StringBuilder {
public:
explicit StringBuilder(MutableSlice slice, bool use_buffer = false);
+
StringBuilder() : StringBuilder({}, true) {
}
@@ -42,6 +44,8 @@ class StringBuilder {
*current_ptr_++ = c;
}
+ void append_char(size_t count, char c);
+
MutableCSlice as_cslice() {
if (current_ptr_ >= end_ptr_ + RESERVED_SIZE) {
std::abort(); // shouldn't happen
@@ -126,6 +130,36 @@ class StringBuilder {
StringBuilder &operator<<(const void *ptr);
+ template <class A, class B>
+ StringBuilder &operator<<(const std::pair<A, B> &p) {
+ return *this << '[' << p.first << ';' << p.second << ']';
+ }
+
+ template <class T>
+ StringBuilder &operator<<(const vector<T> &v) {
+ *this << '{';
+ if (!v.empty()) {
+ *this << v[0];
+ size_t len = v.size();
+ for (size_t i = 1; i < len; i++) {
+ *this << ", " << v[i];
+ }
+ }
+ return *this << '}';
+ }
+
+ StringBuilder &operator<<(const vector<bool> &v) {
+ *this << '{';
+ if (!v.empty()) {
+ *this << v[0];
+ size_t len = v.size();
+ for (size_t i = 1; i < len; i++) {
+ *this << ", " << static_cast<bool>(v[i]);
+ }
+ }
+ return *this << '}';
+ }
+
private:
char *begin_ptr_;
char *current_ptr_;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/TlStorerToString.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/TlStorerToString.h
index 7b4873132d..cb144fe1ee 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/TlStorerToString.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/TlStorerToString.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -9,171 +9,137 @@
#include "td/utils/common.h"
#include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h"
-#include "td/utils/SliceBuilder.h"
+#include "td/utils/StackAllocator.h"
+#include "td/utils/StringBuilder.h"
#include "td/utils/UInt.h"
namespace td {
class TlStorerToString {
- string result;
- size_t shift = 0;
-
- void store_field_begin(const char *name) {
- result.append(shift, ' ');
- if (name && name[0]) {
- result += name;
- result += " = ";
+ decltype(StackAllocator::alloc(0)) buffer_ = StackAllocator::alloc(1 << 14);
+ StringBuilder sb_ = StringBuilder(buffer_.as_slice(), true);
+ size_t shift_ = 0;
+
+ void store_field_begin(Slice name) {
+ sb_.append_char(shift_, ' ');
+ if (!name.empty()) {
+ sb_ << name << " = ";
}
}
void store_field_end() {
- result += '\n';
- }
-
- void store_long(int64 value) {
- result += (PSLICE() << value).c_str();
+ sb_.push_back('\n');
}
void store_binary(Slice data) {
static const char *hex = "0123456789ABCDEF";
- result.append("{ ", 2);
+ sb_ << "{ ";
for (auto c : data) {
unsigned char byte = c;
- result += hex[byte >> 4];
- result += hex[byte & 15];
- result += ' ';
+ sb_.push_back(hex[byte >> 4]);
+ sb_.push_back(hex[byte & 15]);
+ sb_.push_back(' ');
}
- result += '}';
+ sb_.push_back('}');
}
public:
TlStorerToString() = default;
TlStorerToString(const TlStorerToString &) = delete;
TlStorerToString &operator=(const TlStorerToString &) = delete;
+ TlStorerToString(TlStorerToString &&) = delete;
+ TlStorerToString &operator=(TlStorerToString &&) = delete;
- void store_field(const char *name, bool value) {
+ void store_field(Slice name, const string &value) {
store_field_begin(name);
- result += (value ? "true" : "false");
+ sb_.push_back('"');
+ sb_ << value;
+ sb_.push_back('"');
store_field_end();
}
- void store_field(const char *name, int32 value) {
- store_field(name, static_cast<int64>(value));
- }
-
- void store_field(const char *name, int64 value) {
+ void store_field(Slice name, const SecureString &value) {
store_field_begin(name);
- store_long(value);
- store_field_end();
- }
-
- void store_field(const char *name, double value) {
- store_field_begin(name);
- result += (PSLICE() << value).c_str();
- store_field_end();
- }
-
- void store_field(const char *name, const char *value) {
- store_field_begin(name);
- result += value;
- store_field_end();
- }
-
- void store_field(const char *name, const string &value) {
- store_field_begin(name);
- result += '"';
- result += value;
- result += '"';
- store_field_end();
- }
-
- void store_field(const char *name, const SecureString &value) {
- store_field_begin(name);
- result.append("<secret>");
+ sb_ << "<secret>";
store_field_end();
}
template <class T>
- void store_field(const char *name, const T &value) {
+ void store_field(Slice name, const T &value) {
store_field_begin(name);
- result.append(value.data(), value.size());
+ sb_ << value;
store_field_end();
}
- void store_bytes_field(const char *name, const SecureString &value) {
+ void store_bytes_field(Slice name, const SecureString &value) {
store_field_begin(name);
- result.append("<secret>");
+ sb_ << "<secret>";
store_field_end();
}
template <class BytesT>
- void store_bytes_field(const char *name, const BytesT &value) {
+ void store_bytes_field(Slice name, const BytesT &value) {
static const char *hex = "0123456789ABCDEF";
store_field_begin(name);
- result.append("bytes [");
- store_long(static_cast<int64>(value.size()));
- result.append("] { ");
+ sb_ << "bytes [" << value.size() << "] { ";
size_t len = min(static_cast<size_t>(64), value.size());
for (size_t i = 0; i < len; i++) {
int b = value[static_cast<int>(i)] & 0xff;
- result += hex[b >> 4];
- result += hex[b & 15];
- result += ' ';
+ sb_.push_back(hex[b >> 4]);
+ sb_.push_back(hex[b & 15]);
+ sb_.push_back(' ');
}
if (len < value.size()) {
- result.append("...");
+ sb_ << "...";
}
- result += '}';
+ sb_.push_back('}');
store_field_end();
}
template <class ObjectT>
- void store_object_field(const char *name, const ObjectT *value) {
+ void store_object_field(CSlice name, const ObjectT *value) {
if (value == nullptr) {
- store_field(name, "null");
+ store_field(name, Slice("null"));
} else {
- value->store(*this, name);
+ value->store(*this, name.c_str());
}
}
- void store_field(const char *name, const UInt128 &value) {
+ void store_field(Slice name, const UInt128 &value) {
store_field_begin(name);
store_binary(as_slice(value));
store_field_end();
}
- void store_field(const char *name, const UInt256 &value) {
+ void store_field(Slice name, const UInt256 &value) {
store_field_begin(name);
store_binary(as_slice(value));
store_field_end();
}
- void store_vector_begin(const char *field_name, size_t vector_size) {
+ void store_vector_begin(Slice field_name, size_t vector_size) {
store_field_begin(field_name);
- result += "vector[";
- result += (PSLICE() << vector_size).c_str();
- result += "] {\n";
- shift += 2;
+ sb_ << "vector[" << vector_size << "] {\n";
+ shift_ += 2;
}
- void store_class_begin(const char *field_name, const char *class_name) {
- store_field_begin(field_name);
- result += class_name;
- result += " {\n";
- shift += 2;
+ void store_class_begin(const char *field_name, Slice class_name) {
+ store_field_begin(Slice(field_name));
+ sb_ << class_name << " {\n";
+ shift_ += 2;
}
void store_class_end() {
- CHECK(shift >= 2);
- shift -= 2;
- result.append(shift, ' ');
- result += "}\n";
+ CHECK(shift_ >= 2);
+ shift_ -= 2;
+ sb_.append_char(shift_, ' ');
+ sb_ << "}\n";
}
string move_as_string() {
- return std::move(result);
+ return sb_.as_cslice().str();
}
};
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/WaitFreeHashSet.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/WaitFreeHashSet.h
index fdc6bd2464..ef956a8d30 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/WaitFreeHashSet.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/WaitFreeHashSet.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -56,15 +56,16 @@ class WaitFreeHashSet {
}
public:
- void insert(const KeyT &key) {
+ bool insert(const KeyT &key) {
if (wait_free_storage_ != nullptr) {
return get_wait_free_storage(key).insert(key);
}
- default_set_.insert(key);
+ auto result = default_set_.insert(key).second;
if (default_set_.size() == max_storage_size_) {
split_storage();
}
+ return result;
}
size_t count(const KeyT &key) const {
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/algorithm.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/algorithm.h
index 00aae8f640..7046c8e653 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/algorithm.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/algorithm.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -86,6 +86,54 @@ bool remove(V &v, const T &value) {
return true;
}
+template <class V, class T>
+void add_to_top(V &v, size_t max_size, T value) {
+ size_t size = v.size();
+ size_t i;
+ for (i = 0; i < size; i++) {
+ if (v[i] == value) {
+ value = std::move(v[i]);
+ break;
+ }
+ }
+ if (i == size) {
+ if (size < max_size || i == 0) {
+ v.emplace_back(value);
+ } else {
+ i--;
+ }
+ }
+ while (i > 0) {
+ v[i] = std::move(v[i - 1]);
+ i--;
+ }
+ v[0] = std::move(value);
+}
+
+template <class V, class T, class F>
+void add_to_top_if(V &v, size_t max_size, T value, const F &is_equal_to_value) {
+ size_t size = v.size();
+ size_t i;
+ for (i = 0; i < size; i++) {
+ if (is_equal_to_value(v[i])) {
+ value = std::move(v[i]);
+ break;
+ }
+ }
+ if (i == size) {
+ if (size < max_size || i == 0) {
+ v.emplace_back(value);
+ } else {
+ i--;
+ }
+ }
+ while (i > 0) {
+ v[i] = std::move(v[i - 1]);
+ i--;
+ }
+ v[0] = std::move(value);
+}
+
template <class V>
void unique(V &v) {
if (v.empty()) {
@@ -119,6 +167,16 @@ bool contains(const V &v, const T &value) {
}
template <class V, class F>
+bool any_of(const V &v, F &&f) {
+ for (const auto &x : v) {
+ if (f(x)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+template <class V, class F>
bool all_of(const V &v, F &&f) {
for (const auto &x : v) {
if (!f(x)) {
@@ -196,22 +254,25 @@ detail::reversion_wrapper<T> reversed(T &iterable) {
}
template <class TableT, class FuncT>
-void table_remove_if(TableT &table, FuncT &&func) {
+bool table_remove_if(TableT &table, FuncT &&func) {
+ bool is_removed = false;
for (auto it = table.begin(); it != table.end();) {
if (func(*it)) {
it = table.erase(it);
+ is_removed = true;
} else {
++it;
}
}
+ return is_removed;
}
template <class NodeT, class HashT, class EqT>
class FlatHashTable;
template <class NodeT, class HashT, class EqT, class FuncT>
-void table_remove_if(FlatHashTable<NodeT, HashT, EqT> &table, FuncT &&func) {
- table.remove_if(func);
+bool table_remove_if(FlatHashTable<NodeT, HashT, EqT> &table, FuncT &&func) {
+ return table.remove_if(func);
}
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/check.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/check.h
index 38769f263a..c8068090d8 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/check.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/check.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -8,11 +8,13 @@
#define TD_DUMMY_CHECK(condition) ((void)(condition))
-#define CHECK(condition) \
- if (!(condition)) { \
- ::td::detail::process_check_error(#condition, __FILE__, __LINE__); \
+#define CHECK_IMPL(condition, file, line) \
+ if (!(condition)) { \
+ ::td::detail::process_check_error(#condition, file, line); \
}
+#define CHECK(condition) CHECK_IMPL(condition, __FILE__, __LINE__)
+
// clang-format off
#ifdef NDEBUG
#define DCHECK TD_DUMMY_CHECK
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/crypto.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/crypto.cpp
index 77c8993ead..dee0e25112 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/crypto.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/crypto.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -13,6 +13,7 @@
#include "td/utils/Destructor.h"
#include "td/utils/logging.h"
#include "td/utils/misc.h"
+#include "td/utils/port/RwMutex.h"
#include "td/utils/port/thread_local.h"
#include "td/utils/Random.h"
#include "td/utils/ScopeGuard.h"
@@ -720,7 +721,7 @@ void AesCtrState::decrypt(Slice from, MutableSlice to) {
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
-static void make_digest(Slice data, MutableSlice output, const EVP_MD *evp_md) {
+static void make_digest(Slice data, MutableSlice output, const EVP_MD_CTX *evp_md_ctx) {
static TD_THREAD_LOCAL EVP_MD_CTX *ctx;
if (unlikely(ctx == nullptr)) {
ctx = EVP_MD_CTX_new();
@@ -730,7 +731,7 @@ static void make_digest(Slice data, MutableSlice output, const EVP_MD *evp_md) {
ctx = nullptr;
}));
}
- int res = EVP_DigestInit_ex(ctx, evp_md, nullptr);
+ int res = EVP_MD_CTX_copy_ex(ctx, evp_md_ctx);
LOG_IF(FATAL, res != 1);
res = EVP_DigestUpdate(ctx, data.ubegin(), data.size());
LOG_IF(FATAL, res != 1);
@@ -739,23 +740,27 @@ static void make_digest(Slice data, MutableSlice output, const EVP_MD *evp_md) {
EVP_MD_CTX_reset(ctx);
}
-static void init_thread_local_evp_md(const EVP_MD *&evp_md, const char *algorithm) {
- evp_md = EVP_MD_fetch(nullptr, algorithm, nullptr);
+static void init_thread_local_evp_md_ctx(const EVP_MD_CTX *&evp_md_ctx, const char *algorithm) {
+ EVP_MD *evp_md = EVP_MD_fetch(nullptr, algorithm, nullptr);
LOG_IF(FATAL, evp_md == nullptr);
- detail::add_thread_local_destructor(create_destructor([&evp_md]() mutable {
- EVP_MD_free(const_cast<EVP_MD *>(evp_md));
- evp_md = nullptr;
+ evp_md_ctx = EVP_MD_CTX_new();
+ int res = EVP_DigestInit_ex(const_cast<EVP_MD_CTX *>(evp_md_ctx), evp_md, nullptr);
+ LOG_IF(FATAL, res != 1);
+ EVP_MD_free(evp_md);
+ detail::add_thread_local_destructor(create_destructor([&evp_md_ctx]() mutable {
+ EVP_MD_CTX_free(const_cast<EVP_MD_CTX *>(evp_md_ctx));
+ evp_md_ctx = nullptr;
}));
}
#endif
void sha1(Slice data, unsigned char output[20]) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- static TD_THREAD_LOCAL const EVP_MD *evp_md;
- if (unlikely(evp_md == nullptr)) {
- init_thread_local_evp_md(evp_md, "sha1");
+ static TD_THREAD_LOCAL const EVP_MD_CTX *evp_md_ctx;
+ if (unlikely(evp_md_ctx == nullptr)) {
+ init_thread_local_evp_md_ctx(evp_md_ctx, "sha1");
}
- make_digest(data, MutableSlice(output, 20), evp_md);
+ make_digest(data, MutableSlice(output, 20), evp_md_ctx);
#else
auto result = SHA1(data.ubegin(), data.size(), output);
CHECK(result == output);
@@ -765,11 +770,11 @@ void sha1(Slice data, unsigned char output[20]) {
void sha256(Slice data, MutableSlice output) {
CHECK(output.size() >= 32);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- static TD_THREAD_LOCAL const EVP_MD *evp_md;
- if (unlikely(evp_md == nullptr)) {
- init_thread_local_evp_md(evp_md, "sha256");
+ static TD_THREAD_LOCAL const EVP_MD_CTX *evp_md_ctx;
+ if (unlikely(evp_md_ctx == nullptr)) {
+ init_thread_local_evp_md_ctx(evp_md_ctx, "sha256");
}
- make_digest(data, output, evp_md);
+ make_digest(data, output, evp_md_ctx);
#else
auto result = SHA256(data.ubegin(), data.size(), output.ubegin());
CHECK(result == output.ubegin());
@@ -779,11 +784,11 @@ void sha256(Slice data, MutableSlice output) {
void sha512(Slice data, MutableSlice output) {
CHECK(output.size() >= 64);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- static TD_THREAD_LOCAL const EVP_MD *evp_md;
- if (unlikely(evp_md == nullptr)) {
- init_thread_local_evp_md(evp_md, "sha512");
+ static TD_THREAD_LOCAL const EVP_MD_CTX *evp_md_ctx;
+ if (unlikely(evp_md_ctx == nullptr)) {
+ init_thread_local_evp_md_ctx(evp_md_ctx, "sha512");
}
- make_digest(data, output, evp_md);
+ make_digest(data, output, evp_md_ctx);
#else
auto result = SHA512(data.ubegin(), data.size(), output.ubegin());
CHECK(result == output.ubegin());
@@ -863,11 +868,11 @@ void Sha256State::init() {
}
CHECK(!is_inited_);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- static TD_THREAD_LOCAL const EVP_MD *evp_md;
- if (unlikely(evp_md == nullptr)) {
- init_thread_local_evp_md(evp_md, "sha256");
+ static TD_THREAD_LOCAL const EVP_MD_CTX *evp_md_ctx;
+ if (unlikely(evp_md_ctx == nullptr)) {
+ init_thread_local_evp_md_ctx(evp_md_ctx, "sha256");
}
- int err = EVP_DigestInit_ex(impl_->ctx_, evp_md, nullptr);
+ int err = EVP_MD_CTX_copy_ex(impl_->ctx_, evp_md_ctx);
#else
int err = SHA256_Init(&impl_->ctx_);
#endif
@@ -905,11 +910,11 @@ void Sha256State::extract(MutableSlice output, bool destroy) {
void md5(Slice input, MutableSlice output) {
CHECK(output.size() >= 16);
#if OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined(LIBRESSL_VERSION_NUMBER)
- static TD_THREAD_LOCAL const EVP_MD *evp_md;
- if (unlikely(evp_md == nullptr)) {
- init_thread_local_evp_md(evp_md, "md5");
+ static TD_THREAD_LOCAL const EVP_MD_CTX *evp_md_ctx;
+ if (unlikely(evp_md_ctx == nullptr)) {
+ init_thread_local_evp_md_ctx(evp_md_ctx, "md5");
}
- make_digest(input, output, evp_md);
+ make_digest(input, output, evp_md_ctx);
#else
auto result = MD5(input.ubegin(), input.size(), output.ubegin());
CHECK(result == output.ubegin());
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/emoji.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/emoji.cpp
index c3e2514876..b8b5c67342 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/emoji.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/emoji.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -141,7 +141,7 @@ static bool is_emoji_element(Slice str) {
bool is_emoji(Slice str) {
size_t i = str.substr(0, MAX_EMOJI_LENGTH + 4).find('\xE2');
- if (i == td::Slice::npos) {
+ if (i == Slice::npos) {
return is_emoji_element(str);
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.cpp
index 5a2fc0b268..80d9353a27 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -50,8 +50,8 @@ Result<T> read_file_impl(CSlice path, int64 size, int64 offset) {
size = file_size - offset;
}
auto content = create_empty<T>(narrow_cast<size_t>(size));
- TRY_RESULT(got_size, from_file.pread(as_mutable_slice(content), offset));
- if (got_size != static_cast<size_t>(size)) {
+ TRY_RESULT(read_size, from_file.pread(as_mutable_slice(content), offset));
+ if (read_size != static_cast<size_t>(size)) {
return Status::Error("Failed to read file");
}
from_file.close();
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.h
index c1d232026f..474728d3e7 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/filesystem.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -7,6 +7,7 @@
#pragma once
#include "td/utils/buffer.h"
+#include "td/utils/common.h"
#include "td/utils/SharedSlice.h"
#include "td/utils/Slice.h"
#include "td/utils/Status.h"
@@ -27,7 +28,7 @@ Status write_file(CSlice to, Slice data, WriteFileOptions options = {}) TD_WARN_
string clean_filename(CSlice name);
-// writes data to file and ensures that the file is either fully overriden, or is left intact
+// writes data to file and ensures that the file is either fully overridden, or is left intact
// uses path_tmp to temporary store data, then calls rename
Status atomic_write_file(CSlice path, Slice data, CSlice path_tmp = {});
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/format.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/format.h
index b7fdf53f2c..cb5220805b 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/format.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/format.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -216,7 +216,7 @@ struct Array {
template <class ArrayT>
StringBuilder &operator<<(StringBuilder &stream, const Array<ArrayT> &array) {
bool first = true;
- stream << Slice("{");
+ stream << '{';
for (auto &x : array.ref) {
if (!first) {
stream << Slice(", ");
@@ -224,12 +224,12 @@ StringBuilder &operator<<(StringBuilder &stream, const Array<ArrayT> &array) {
stream << x;
first = false;
}
- return stream << Slice("}");
+ return stream << '}';
}
inline StringBuilder &operator<<(StringBuilder &stream, const Array<vector<bool>> &array) {
bool first = true;
- stream << Slice("{");
+ stream << '{';
for (bool x : array.ref) {
if (!first) {
stream << Slice(", ");
@@ -237,7 +237,7 @@ inline StringBuilder &operator<<(StringBuilder &stream, const Array<vector<bool>
stream << x;
first = false;
}
- return stream << Slice("}");
+ return stream << '}';
}
template <class ArrayT>
@@ -254,7 +254,7 @@ struct Tagged {
template <class ValueT>
StringBuilder &operator<<(StringBuilder &stream, const Tagged<ValueT> &tagged) {
- return stream << "[" << tagged.tag << ":" << tagged.ref << "]";
+ return stream << '[' << tagged.tag << ':' << tagged.ref << ']';
}
template <class ValueT>
@@ -305,34 +305,8 @@ auto concat(const ArgsT &...args) {
return Concat<decltype(std::tie(args...))>{std::tie(args...)};
}
-template <class F>
-struct Lambda {
- const F &f;
-};
-
-template <class F>
-StringBuilder &operator<<(StringBuilder &sb, const Lambda<F> &f) {
- f.f(sb);
- return sb;
-}
-
-template <class LambdaT>
-Lambda<LambdaT> lambda(const LambdaT &lambda) {
- return Lambda<LambdaT>{lambda};
-}
-
} // namespace format
using format::tag;
-template <class A, class B>
-StringBuilder &operator<<(StringBuilder &sb, const std::pair<A, B> &p) {
- return sb << "[" << p.first << ";" << p.second << "]";
-}
-
-template <class T>
-StringBuilder &operator<<(StringBuilder &stream, const vector<T> &vec) {
- return stream << format::as_array(vec);
-}
-
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/logging.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/logging.cpp
index cf73f5dfb2..8ddf80643e 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/logging.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/logging.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -191,8 +191,7 @@ class DefaultLog final : public LogInterface {
#elif TD_EMSCRIPTEN
switch (log_level) {
case VERBOSITY_NAME(FATAL):
- emscripten_log(EM_LOG_ERROR | EM_LOG_CONSOLE | EM_LOG_C_STACK | EM_LOG_JS_STACK | EM_LOG_FUNC_PARAMS, "%s",
- slice.c_str());
+ emscripten_log(EM_LOG_ERROR | EM_LOG_CONSOLE | EM_LOG_C_STACK | EM_LOG_JS_STACK, "%s", slice.c_str());
EM_ASM(throw(UTF8ToString($0)), slice.c_str());
break;
case VERBOSITY_NAME(ERROR):
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/misc.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/misc.cpp
index 6976ead384..cb3dcac6ab 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/misc.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/misc.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -7,6 +7,8 @@
#include "td/utils/misc.h"
#include "td/utils/port/thread_local.h"
+#include "td/utils/StackAllocator.h"
+#include "td/utils/StringBuilder.h"
#include "td/utils/utf8.h"
#include <algorithm>
@@ -81,11 +83,11 @@ string oneline(Slice str) {
namespace detail {
Status get_to_integer_safe_error(Slice str) {
- auto status = Status::Error(PSLICE() << "Can't parse \"" << str << "\" as an integer");
- if (!check_utf8(status.message())) {
- status = Status::Error("Strings must be encoded in UTF-8");
+ auto error_message = PSTRING() << "Can't parse as an integer string \"" << str << '"';
+ if (!check_utf8(error_message)) {
+ return Status::Error("Strings must be encoded in UTF-8");
}
- return status;
+ return Status::Error(error_message);
}
} // namespace detail
@@ -201,60 +203,72 @@ string buffer_to_hex(Slice buffer) {
return res;
}
-namespace {
+string zero_encode(Slice data) {
+ auto buffer = StackAllocator::alloc(1024);
+ auto res = StringBuilder(buffer.as_slice(), true);
+ for (size_t n = data.size(), i = 0; i < n; i++) {
+ res.push_back(data[i]);
+ if (data[i] == 0) {
+ unsigned char cnt = 1;
+ while (cnt < 250 && i + cnt < n && data[i + cnt] == data[i]) {
+ cnt++;
+ }
+ res.push_back(static_cast<char>(cnt));
+ i += cnt - 1;
+ }
+ }
+ return res.as_cslice().str();
+}
-template <class F>
-string x_decode(Slice s, F &&f) {
- string res;
- for (size_t n = s.size(), i = 0; i < n; i++) {
- if (i + 1 < n && f(s[i])) {
- res.append(static_cast<unsigned char>(s[i + 1]), s[i]);
+string zero_decode(Slice data) {
+ auto buffer = StackAllocator::alloc(1024);
+ auto res = StringBuilder(buffer.as_slice(), true);
+ for (size_t n = data.size(), i = 0; i < n; i++) {
+ if (data[i] == 0 && i + 1 < n) {
+ for (int cnt = static_cast<unsigned char>(data[i + 1]); cnt > 0; cnt--) {
+ res.push_back(data[i]);
+ }
i++;
continue;
}
- res.push_back(s[i]);
+ res.push_back(data[i]);
}
- return res;
+ return res.as_cslice().str();
}
-template <class F>
-string x_encode(Slice s, F &&f) {
- string res;
- for (size_t n = s.size(), i = 0; i < n; i++) {
- res.push_back(s[i]);
- if (f(s[i])) {
+string zero_one_encode(Slice data) {
+ auto buffer = StackAllocator::alloc(1024);
+ auto res = StringBuilder(buffer.as_slice(), true);
+ for (size_t n = data.size(), i = 0; i < n; i++) {
+ res.push_back(data[i]);
+ auto c = static_cast<unsigned char>(data[i]);
+ if (c == 0 || c == 0xff) {
unsigned char cnt = 1;
- while (cnt < 250 && i + cnt < n && s[i + cnt] == s[i]) {
+ while (cnt < 250 && i + cnt < n && data[i + cnt] == data[i]) {
cnt++;
}
res.push_back(static_cast<char>(cnt));
i += cnt - 1;
}
}
- return res;
+ return res.as_cslice().str();
}
-bool is_zero(unsigned char c) {
- return c == 0;
-}
-
-bool is_zero_or_one(unsigned char c) {
- return c == 0 || c == 0xff;
-}
-
-} // namespace
-
-std::string zero_encode(Slice data) {
- return x_encode(data, is_zero);
-}
-std::string zero_decode(Slice data) {
- return x_decode(data, is_zero);
-}
-std::string zero_one_encode(Slice data) {
- return x_encode(data, is_zero_or_one);
-}
-std::string zero_one_decode(Slice data) {
- return x_decode(data, is_zero_or_one);
+string zero_one_decode(Slice data) {
+ auto buffer = StackAllocator::alloc(1024);
+ auto res = StringBuilder(buffer.as_slice(), true);
+ for (size_t n = data.size(), i = 0; i < n; i++) {
+ auto c = static_cast<unsigned char>(data[i]);
+ if ((c == 0 || c == 0xff) && i + 1 < n) {
+ for (int cnt = static_cast<unsigned char>(data[i + 1]); cnt > 0; cnt--) {
+ res.push_back(data[i]);
+ }
+ i++;
+ continue;
+ }
+ res.push_back(data[i]);
+ }
+ return res.as_cslice().str();
}
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/optional.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/optional.h
index ace463d70d..bb7e4bc813 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/optional.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/optional.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -60,6 +60,9 @@ class optional {
T &operator*() {
return value();
}
+ const T &operator*() const {
+ return value();
+ }
T unwrap() {
CHECK(*this);
auto res = std::move(value());
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FileFd.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FileFd.cpp
index 52c7ef28c5..23f7f33d2b 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FileFd.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FileFd.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -224,10 +224,18 @@ Result<FileFd> FileFd::open(CSlice filepath, int32 flags, int32 mode) {
if (flags & WinStat) {
native_flags |= FILE_FLAG_BACKUP_SEMANTICS;
}
-
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_SYSTEM)
auto handle =
CreateFile(w_filepath.c_str(), desired_access, share_mode, nullptr, creation_disposition, native_flags, nullptr);
-
+#else
+ CREATEFILE2_EXTENDED_PARAMETERS extended_parameters;
+ std::memset(&extended_parameters, 0, sizeof(extended_parameters));
+ extended_parameters.dwSize = sizeof(extended_parameters);
+ extended_parameters.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+ extended_parameters.dwFileFlags = native_flags;
+ auto handle = td::CreateFile2FromAppW(w_filepath.c_str(), desired_access, share_mode, creation_disposition,
+ &extended_parameters);
+#endif
if (handle == INVALID_HANDLE_VALUE) {
return OS_ERROR(PSLICE() << "File \"" << filepath << "\" can't be " << PrintFlags{flags});
}
@@ -595,13 +603,7 @@ Result<Stat> FileFd::stat() const {
#elif TD_PORT_WINDOWS
Stat res;
- #ifdef _WIN64
FILE_BASIC_INFO basic_info;
- #else
- struct __boo : public FILE_BASIC_INFO {
- DWORD __tmp;
- } basic_info;
- #endif
auto status = GetFileInformationByHandleEx(get_native_fd().fd(), FileBasicInfo, &basic_info, sizeof(basic_info));
if (!status) {
return OS_ERROR("Get FileBasicInfo failed");
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FromApp.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FromApp.h
index 1f72eb706c..23125b6c81 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FromApp.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/FromApp.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -53,6 +53,13 @@ T *get_from_app_function(const char *name, T *original_func) {
#endif
}
+inline HANDLE CreateFile2FromAppW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode,
+ _In_ DWORD dwCreationDisposition,
+ _In_opt_ LPCREATEFILE2_EXTENDED_PARAMETERS pCreateExParams) {
+ auto func = get_from_app_function<0>("CreateFile2FromAppW", &CreateFile2);
+ return func(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, pCreateExParams);
+}
+
inline BOOL CreateDirectoryFromAppW(_In_ LPCWSTR lpPathName, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes) {
auto func = get_from_app_function<1>("CreateDirectoryFromAppW", &CreateDirectory);
return func(lpPathName, lpSecurityAttributes);
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.cpp
index d7eca3a0d2..72578a9be8 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -369,4 +369,12 @@ Result<ServerSocketFd> ServerSocketFd::open(int32 port, CSlice addr) {
return ServerSocketFd(std::move(impl));
}
+Result<uint32> ServerSocketFd::maximize_snd_buffer(uint32 max_size) {
+ return get_native_fd().maximize_snd_buffer(max_size);
+}
+
+Result<uint32> ServerSocketFd::maximize_rcv_buffer(uint32 max_size) {
+ return get_native_fd().maximize_rcv_buffer(max_size);
+}
+
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.h
index 266e688321..dcee89917f 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/ServerSocketFd.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -33,6 +33,9 @@ class ServerSocketFd {
ServerSocketFd &operator=(ServerSocketFd &&) noexcept;
~ServerSocketFd();
+ Result<uint32> maximize_snd_buffer(uint32 max_size = 0);
+ Result<uint32> maximize_rcv_buffer(uint32 max_size = 0);
+
static Result<ServerSocketFd> open(int32 port, CSlice addr = CSlice("0.0.0.0")) TD_WARN_UNUSED_RESULT;
PollableFdInfo &get_poll_info();
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.cpp
index 68c62ad11b..ac4038c3f9 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -578,7 +578,7 @@ Status get_socket_pending_error(const NativeFd &fd, WSAOVERLAPPED *overlapped, S
DWORD flags = 0;
BOOL success = WSAGetOverlappedResult(fd.socket(), overlapped, &num_bytes, false, &flags);
if (success) {
- LOG(ERROR) << "WSAGetOverlappedResult succeded after " << iocp_error;
+ LOG(ERROR) << "WSAGetOverlappedResult succeeded after " << iocp_error;
return iocp_error;
}
return OS_SOCKET_ERROR(PSLICE() << "Error on " << fd);
@@ -717,4 +717,12 @@ Result<size_t> SocketFd::read(MutableSlice slice) {
return impl_->read(slice);
}
+Result<uint32> SocketFd::maximize_snd_buffer(uint32 max_size) {
+ return get_native_fd().maximize_snd_buffer(max_size);
+}
+
+Result<uint32> SocketFd::maximize_rcv_buffer(uint32 max_size) {
+ return get_native_fd().maximize_rcv_buffer(max_size);
+}
+
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.h
index 2c4a3746fe..40f3a9321a 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/SocketFd.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -37,6 +37,9 @@ class SocketFd {
SocketFd &operator=(SocketFd &&) noexcept;
~SocketFd();
+ Result<uint32> maximize_snd_buffer(uint32 max_size = 0);
+ Result<uint32> maximize_rcv_buffer(uint32 max_size = 0);
+
static Result<SocketFd> open(const IPAddress &address) TD_WARN_UNUSED_RESULT;
PollableFdInfo &get_poll_info();
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.cpp
index e5db2c2fb2..cd4641b188 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -790,54 +790,6 @@ const NativeFd &UdpSocketFd::get_native_fd() const {
}
#if TD_PORT_POSIX
-static Result<uint32> maximize_buffer(int socket_fd, int optname, uint32 max_size) {
- if (setsockopt(socket_fd, SOL_SOCKET, optname, &max_size, sizeof(max_size)) == 0) {
- // fast path
- return max_size;
- }
-
- /* Start with the default size. */
- uint32 old_size = 0;
- socklen_t intsize = sizeof(old_size);
- if (getsockopt(socket_fd, SOL_SOCKET, optname, &old_size, &intsize)) {
- return OS_ERROR("getsockopt() failed");
- }
-#if TD_LINUX
- old_size /= 2;
-#endif
-
- /* Binary-search for the real maximum. */
- uint32 last_good_size = old_size;
- uint32 min_size = old_size;
- while (min_size <= max_size) {
- uint32 avg_size = min_size + (max_size - min_size) / 2;
- if (setsockopt(socket_fd, SOL_SOCKET, optname, &avg_size, sizeof(avg_size)) == 0) {
- last_good_size = avg_size;
- min_size = avg_size + 1;
- } else {
- max_size = avg_size - 1;
- }
- }
- return last_good_size;
-}
-
-Result<uint32> UdpSocketFd::maximize_snd_buffer(uint32 max_size) {
- return maximize_buffer(get_native_fd().fd(), SO_SNDBUF, max_size == 0 ? DEFAULT_UDP_MAX_SND_BUFFER_SIZE : max_size);
-}
-
-Result<uint32> UdpSocketFd::maximize_rcv_buffer(uint32 max_size) {
- return maximize_buffer(get_native_fd().fd(), SO_RCVBUF, max_size == 0 ? DEFAULT_UDP_MAX_RCV_BUFFER_SIZE : max_size);
-}
-#else
-Result<uint32> UdpSocketFd::maximize_snd_buffer(uint32 max_size) {
- return 0;
-}
-Result<uint32> UdpSocketFd::maximize_rcv_buffer(uint32 max_size) {
- return 0;
-}
-#endif
-
-#if TD_PORT_POSIX
Status UdpSocketFd::send_message(const OutboundMessage &message, bool &is_sent) {
return impl_->send_message(message, is_sent);
}
@@ -870,4 +822,12 @@ bool UdpSocketFd::is_critical_read_error(const Status &status) {
return status.code() == ENOMEM || status.code() == ENOBUFS;
}
+Result<uint32> UdpSocketFd::maximize_snd_buffer(uint32 max_size) {
+ return get_native_fd().maximize_snd_buffer(max_size);
+}
+
+Result<uint32> UdpSocketFd::maximize_rcv_buffer(uint32 max_size) {
+ return get_native_fd().maximize_rcv_buffer(max_size);
+}
+
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.h
index 67cdf801ae..53d7755b69 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/UdpSocketFd.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -83,8 +83,6 @@ class UdpSocketFd {
#endif
private:
- static constexpr uint32 DEFAULT_UDP_MAX_SND_BUFFER_SIZE = (1 << 24);
- static constexpr uint32 DEFAULT_UDP_MAX_RCV_BUFFER_SIZE = (1 << 24);
std::unique_ptr<detail::UdpSocketFdImpl, detail::UdpSocketFdImplDeleter> impl_;
explicit UdpSocketFd(unique_ptr<detail::UdpSocketFdImpl> impl);
};
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.cpp
index 779a166cc0..479498ee9c 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -12,6 +12,8 @@
#if TD_PORT_POSIX
#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
#include <unistd.h>
#endif
@@ -223,6 +225,45 @@ Status NativeFd::duplicate(const NativeFd &to) const {
#endif
}
+static Result<uint32> maximize_buffer(const NativeFd::Socket &socket, int optname, uint32 max_size) {
+ if (setsockopt(socket, SOL_SOCKET, optname, reinterpret_cast<const char *>(&max_size), sizeof(max_size)) == 0) {
+ // fast path
+ return max_size;
+ }
+
+ /* Start with the default size. */
+ uint32 old_size = 0;
+ socklen_t intsize = sizeof(old_size);
+ if (getsockopt(socket, SOL_SOCKET, optname, reinterpret_cast<char *>(&old_size), &intsize)) {
+ return OS_SOCKET_ERROR("getsockopt() failed");
+ }
+#if TD_LINUX
+ old_size /= 2;
+#endif
+
+ /* Binary-search for the real maximum. */
+ uint32 last_good_size = old_size;
+ uint32 min_size = old_size;
+ while (min_size <= max_size) {
+ uint32 avg_size = min_size + (max_size - min_size) / 2;
+ if (setsockopt(socket, SOL_SOCKET, optname, reinterpret_cast<const char *>(&avg_size), sizeof(avg_size)) == 0) {
+ last_good_size = avg_size;
+ min_size = avg_size + 1;
+ } else {
+ max_size = avg_size - 1;
+ }
+ }
+ return last_good_size;
+}
+
+Result<uint32> NativeFd::maximize_snd_buffer(uint32 max_size) const {
+ return maximize_buffer(socket(), SO_SNDBUF, max_size == 0 ? DEFAULT_MAX_SND_BUFFER_SIZE : max_size);
+}
+
+Result<uint32> NativeFd::maximize_rcv_buffer(uint32 max_size) const {
+ return maximize_buffer(socket(), SO_RCVBUF, max_size == 0 ? DEFAULT_MAX_RCV_BUFFER_SIZE : max_size);
+}
+
void NativeFd::close() {
if (!*this) {
return;
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.h
index e4eaaa696b..a2af773b0f 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/detail/NativeFd.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -49,6 +49,9 @@ class NativeFd {
Status duplicate(const NativeFd &to) const;
+ Result<uint32> maximize_snd_buffer(uint32 max_size = 0) const;
+ Result<uint32> maximize_rcv_buffer(uint32 max_size = 0) const;
+
void close();
Fd release();
@@ -61,6 +64,8 @@ class NativeFd {
#if TD_PORT_WINDOWS
bool is_socket_{false};
#endif
+ static constexpr uint32 DEFAULT_MAX_SND_BUFFER_SIZE = (1 << 24);
+ static constexpr uint32 DEFAULT_MAX_RCV_BUFFER_SIZE = (1 << 24);
};
StringBuilder &operator<<(StringBuilder &sb, const NativeFd &fd);
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/platform.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/platform.h
index 5772948750..7ca7ee20d5 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/platform.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/platform.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -25,6 +25,8 @@
#define TD_DARWIN_IOS 1
#elif TARGET_OS_TV
#define TD_DARWIN_TV_OS 1
+ #elif TARGET_OS_VISION
+ #define TD_DARWIN_VISION_OS 1
#elif TARGET_OS_WATCH
#define TD_DARWIN_WATCH_OS 1
#else
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/uname.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/uname.cpp
index 6da28ee26c..5b9dc855e9 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/port/uname.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/port/uname.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -81,6 +81,8 @@ Slice get_operating_system_version() {
return "iOS" + os_version;
#elif TD_DARWIN_TV_OS
return "tvOS" + os_version;
+#elif TD_DARWIN_VISION_OS
+ return "visionOS" + os_version;
#elif TD_DARWIN_WATCH_OS
return "watchOS" + os_version;
#elif TD_DARWIN_MAC
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.cpp
index feeb907cac..9a346a2650 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.cpp
@@ -1,12 +1,15 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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/tl_parsers.h"
+#include "td/utils/format.h"
+#include "td/utils/logging.h"
#include "td/utils/misc.h"
+#include "td/utils/utf8.h"
namespace td {
@@ -55,4 +58,21 @@ BufferSlice TlBufferParser::as_buffer_slice(Slice slice) {
return BufferSlice(slice);
}
+bool TlBufferParser::is_valid_utf8(CSlice str) const {
+ if (check_utf8(str)) {
+ return true;
+ }
+ LOG(WARNING) << "Wrong UTF-8 string [[" << str << "]] in " << format::as_hex_dump<4>(parent_->as_slice());
+ return false;
+}
+
+size_t TlBufferParser::last_utf8_character_position(Slice str) {
+ CHECK(!str.empty());
+ size_t position = str.size() - 1;
+ while (position != 0 && !is_utf8_character_first_code_unit(static_cast<unsigned char>(str[position]))) {
+ position--;
+ }
+ return position;
+}
+
} // namespace td
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.h b/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.h
index b5d85cc74d..f08009b57a 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.h
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/tl_parsers.h
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -8,13 +8,10 @@
#include "td/utils/buffer.h"
#include "td/utils/common.h"
-#include "td/utils/format.h"
-#include "td/utils/logging.h"
#include "td/utils/Slice.h"
#include "td/utils/SliceBuilder.h"
#include "td/utils/Status.h"
#include "td/utils/UInt.h"
-#include "td/utils/utf8.h"
#include <array>
#include <cstring>
@@ -207,19 +204,11 @@ class TlBufferParser : public TlParser {
c = ' ';
}
}
- if (check_utf8(result)) {
+ if (is_valid_utf8(result)) {
return result;
}
- CHECK(!result.empty());
- LOG(WARNING) << "Wrong UTF-8 string [[" << result << "]] in " << format::as_hex_dump<4>(parent_->as_slice());
-
- // trying to remove last character
- size_t new_size = result.size() - 1;
- while (new_size != 0 && !is_utf8_character_first_code_unit(static_cast<unsigned char>(result[new_size]))) {
- new_size--;
- }
- result.resize(new_size);
- if (check_utf8(result)) {
+ result.resize(last_utf8_character_position(result));
+ if (is_valid_utf8(result)) {
return result;
}
@@ -235,6 +224,10 @@ class TlBufferParser : public TlParser {
const BufferSlice *parent_;
BufferSlice as_buffer_slice(Slice slice);
+
+ bool is_valid_utf8(CSlice str) const;
+
+ static size_t last_utf8_character_position(Slice str);
};
template <>
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/unicode.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/unicode.cpp
index df9a22a96b..1c0bbb8028 100644
--- a/protocols/Telegram/tdlib/td/tdutils/td/utils/unicode.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/unicode.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -12,137 +12,137 @@ namespace td {
// list of [(range_begin << 5) + range_type]
static const uint32 unicode_simple_category_ranges[] = {
- 0, 1028, 1056, 1538, 1856, 2081, 2912, 3105, 3936, 5124, 5152, 5441,
- 5472, 5699, 5760, 5793, 5824, 5923, 5953, 5984, 6019, 6112, 6145, 6880,
- 6913, 7904, 7937, 22592, 22721, 23104, 23553, 23712, 23937, 23968, 24001, 24032,
- 28161, 28320, 28353, 28416, 28481, 28608, 28641, 28672, 28865, 28896, 28929, 29024,
- 29057, 29088, 29121, 29760, 29793, 32448, 32481, 36928, 37185, 42496, 42529, 43744,
- 43809, 43840, 44033, 45344, 47617, 48480, 48609, 48736, 50177, 51552, 52226, 52544,
- 52673, 52736, 52769, 55936, 55969, 56000, 56481, 56544, 56769, 56834, 57153, 57248,
- 57313, 57344, 57857, 57888, 57921, 58880, 59809, 62656, 63009, 63040, 63490, 63809,
- 64864, 65153, 65216, 65345, 65376, 65537, 66240, 66369, 66400, 66689, 66720, 66817,
- 66848, 67585, 68384, 68609, 68960, 69121, 69888, 69921, 70112, 70657, 72000, 73857,
- 75584, 75681, 75712, 76289, 76320, 76545, 76864, 76994, 77312, 77345, 77856, 77985,
- 78240, 78305, 78368, 78433, 79136, 79169, 79392, 79425, 79456, 79553, 79680, 79777,
- 79808, 80321, 80352, 80769, 80832, 80865, 80960, 81090, 81409, 81472, 81539, 81728,
- 81793, 81824, 82081, 82272, 82401, 82464, 82529, 83232, 83265, 83488, 83521, 83584,
- 83617, 83680, 83713, 83776, 84769, 84896, 84929, 84960, 85186, 85504, 85569, 85664,
- 86177, 86464, 86497, 86592, 86625, 87328, 87361, 87584, 87617, 87680, 87713, 87872,
- 87969, 88000, 88577, 88608, 89089, 89152, 89282, 89600, 89889, 89920, 90273, 90528,
- 90593, 90656, 90721, 91424, 91457, 91680, 91713, 91776, 91809, 91968, 92065, 92096,
- 93057, 93120, 93153, 93248, 93378, 93696, 93729, 93763, 93952, 94305, 94336, 94369,
- 94560, 94657, 94752, 94785, 94912, 95009, 95072, 95105, 95136, 95169, 95232, 95329,
- 95392, 95489, 95584, 95681, 96064, 96769, 96800, 97474, 97795, 97888, 98465, 98720,
- 98753, 98848, 98881, 99616, 99649, 100160, 100257, 100288, 101121, 101216, 101281, 101312,
- 101377, 101440, 101570, 101888, 102147, 102368, 102401, 102432, 102561, 102816, 102849, 102944,
- 102977, 103712, 103745, 104064, 104097, 104256, 104353, 104384, 105377, 105440, 105473, 105536,
- 105666, 105984, 106017, 106080, 106625, 106912, 106945, 107040, 107073, 108384, 108449, 108480,
- 108993, 109024, 109185, 109280, 109315, 109537, 109632, 109762, 110083, 110368, 110401, 110592,
- 110753, 111328, 111425, 112192, 112225, 112512, 112545, 112576, 112641, 112864, 113858, 114176,
- 114721, 116256, 116289, 116352, 116737, 116960, 117250, 117568, 118817, 118880, 118913, 118944,
- 118977, 119136, 119169, 119936, 119969, 120000, 120033, 120352, 120385, 120448, 120737, 120768,
- 120833, 120992, 121025, 121056, 121346, 121664, 121729, 121856, 122881, 122912, 123906, 124227,
- 124544, 124929, 125184, 125217, 126368, 127233, 127392, 131073, 132448, 133089, 133122, 133440,
- 133633, 133824, 133953, 134080, 134177, 134208, 134305, 134368, 134593, 134688, 134817, 135232,
- 135617, 135648, 135682, 136000, 136193, 137408, 137441, 137472, 137633, 137664, 137729, 139104,
- 139137, 149792, 149825, 149952, 150017, 150240, 150273, 150304, 150337, 150464, 150529, 151840,
- 151873, 152000, 152065, 153120, 153153, 153280, 153345, 153568, 153601, 153632, 153665, 153792,
- 153857, 154336, 154369, 156192, 156225, 156352, 156417, 158560, 159011, 159648, 159745, 160256,
- 160769, 163520, 163585, 163776, 163873, 183712, 183777, 184324, 184353, 185184, 185345, 187744,
- 187843, 187937, 188192, 188417, 188992, 189409, 190016, 190465, 191040, 191489, 191904, 191937,
- 192032, 192513, 194176, 195297, 195328, 195457, 195488, 195586, 195904, 196099, 196416, 197122,
- 197440, 197633, 200480, 200705, 200864, 200929, 202016, 202049, 202080, 202241, 204480, 204801,
- 205792, 207042, 207361, 208320, 208385, 208544, 208897, 210304, 210433, 211264, 211458, 211779,
- 211808, 212993, 213728, 214017, 215712, 217090, 217408, 217602, 217920, 218337, 218368, 221345,
- 222848, 223393, 223648, 223746, 224064, 225377, 226336, 226753, 226818, 227137, 228544, 229377,
- 230528, 231426, 231744, 231841, 231938, 232257, 233408, 233473, 233760, 233985, 235360, 235425,
- 235520, 236833, 236960, 236993, 237184, 237217, 237280, 237377, 237408, 237569, 243712, 245761,
- 254656, 254721, 254912, 254977, 256192, 256257, 256448, 256513, 256768, 256801, 256832, 256865,
- 256896, 256929, 256960, 256993, 257984, 258049, 259744, 259777, 260000, 260033, 260064, 260161,
- 260256, 260289, 260512, 260609, 260736, 260801, 260992, 261121, 261536, 261697, 261792, 261825,
- 262048, 262148, 262496, 263428, 263488, 263652, 263680, 265188, 265216, 265731, 265761, 265792,
- 265859, 266048, 266209, 266243, 266560, 266753, 267168, 270401, 270432, 270561, 270592, 270657,
- 270976, 271009, 271040, 271137, 271296, 271489, 271520, 271553, 271584, 271617, 271648, 271681,
- 271808, 271841, 272192, 272257, 272384, 272545, 272704, 272833, 272864, 272899, 274529, 274595,
- 274752, 297987, 299904, 302403, 303104, 323267, 324224, 360449, 367776, 367969, 368096, 368193,
- 368256, 368547, 368576, 368641, 369856, 369889, 369920, 370081, 370112, 370177, 371968, 372193,
- 372224, 372737, 373472, 373761, 373984, 374017, 374240, 374273, 374496, 374529, 374752, 374785,
- 375008, 375041, 375264, 375297, 375520, 375553, 375776, 378337, 378368, 393220, 393248, 393377,
- 393443, 393472, 394275, 394560, 394785, 394944, 395011, 395105, 395168, 395297, 398048, 398241,
- 398336, 398369, 401248, 401281, 401408, 401569, 402944, 402977, 405984, 406083, 406208, 406529,
- 407552, 409089, 409600, 410627, 410944, 411907, 412160, 412195, 412672, 413699, 414016, 415267,
- 415744, 425985, 636928, 638977, 1348000, 1350145, 1351616, 1351681, 1360288, 1360385, 1360898, 1361217,
- 1361280, 1361921, 1363424, 1363937, 1364928, 1364993, 1367235, 1367552, 1368801, 1369088, 1369153, 1372448,
- 1372513, 1374560, 1374721, 1374784, 1374817, 1374848, 1374881, 1375040, 1375809, 1376320, 1376353, 1376448,
- 1376481, 1376608, 1376641, 1377376, 1377795, 1377984, 1378305, 1379968, 1380417, 1382016, 1382914, 1383232,
- 1384001, 1384192, 1384289, 1384320, 1384353, 1384416, 1384450, 1384769, 1385664, 1385985, 1386720, 1387521,
- 1388448, 1388673, 1390176, 1391073, 1391106, 1391424, 1391617, 1391776, 1391809, 1392130, 1392449, 1392608,
- 1392641, 1393952, 1394689, 1394784, 1394817, 1395072, 1395202, 1395520, 1395713, 1396448, 1396545, 1396576,
- 1396673, 1398272, 1398305, 1398336, 1398433, 1398496, 1398561, 1398720, 1398785, 1398816, 1398849, 1398880,
- 1399649, 1399744, 1399809, 1400160, 1400385, 1400480, 1400865, 1401056, 1401121, 1401312, 1401377, 1401568,
- 1401857, 1402080, 1402113, 1402336, 1402369, 1403744, 1403777, 1404224, 1404417, 1408096, 1408514, 1408832,
- 1409025, 1766528, 1766913, 1767648, 1767777, 1769344, 2039809, 2051520, 2051585, 2054976, 2056193, 2056416,
- 2056801, 2056960, 2057121, 2057152, 2057185, 2057504, 2057537, 2057952, 2057985, 2058144, 2058177, 2058208,
- 2058241, 2058304, 2058337, 2058400, 2058433, 2061888, 2062945, 2074560, 2075137, 2077184, 2077249, 2078976,
- 2080257, 2080640, 2084353, 2084512, 2084545, 2088864, 2089474, 2089792, 2090017, 2090848, 2091041, 2091872,
- 2092225, 2095072, 2095169, 2095360, 2095425, 2095616, 2095681, 2095872, 2095937, 2096032, 2097153, 2097536,
- 2097569, 2098400, 2098433, 2099040, 2099073, 2099136, 2099169, 2099648, 2099713, 2100160, 2101249, 2105184,
- 2105571, 2107008, 2107395, 2109216, 2109763, 2109824, 2117633, 2118560, 2118657, 2120224, 2120739, 2121600,
- 2121729, 2122755, 2122880, 2123169, 2123811, 2123841, 2124099, 2124128, 2124289, 2125504, 2125825, 2126784,
- 2126849, 2128000, 2128129, 2128384, 2128419, 2128576, 2129921, 2134976, 2135042, 2135360, 2135553, 2136704,
- 2136833, 2137984, 2138113, 2139392, 2139649, 2141312, 2141697, 2142048, 2142081, 2142560, 2142593, 2142816,
- 2142849, 2142912, 2142945, 2143296, 2143329, 2143808, 2143841, 2144064, 2144097, 2144160, 2146305, 2156256,
- 2156545, 2157248, 2157569, 2157824, 2158593, 2158784, 2158817, 2160160, 2160193, 2160480, 2162689, 2162880,
- 2162945, 2162976, 2163009, 2164416, 2164449, 2164512, 2164609, 2164640, 2164705, 2165440, 2165507, 2165761,
- 2166496, 2166563, 2166785, 2167776, 2168035, 2168320, 2169857, 2170464, 2170497, 2170560, 2170723, 2170881,
- 2171587, 2171776, 2171905, 2172736, 2174977, 2176768, 2176899, 2176961, 2177027, 2177536, 2177603, 2179073,
- 2179104, 2179585, 2179712, 2179745, 2179840, 2179873, 2180800, 2181123, 2181408, 2182145, 2183075, 2183136,
- 2183169, 2184099, 2184192, 2185217, 2185472, 2185505, 2186400, 2186595, 2186752, 2187265, 2188992, 2189313,
- 2190016, 2190083, 2190337, 2190944, 2191107, 2191361, 2191936, 2192675, 2192896, 2195457, 2197792, 2199553,
- 2201184, 2201601, 2203232, 2203459, 2203649, 2204800, 2205186, 2205504, 2214915, 2215904, 2215937, 2217280,
- 2217473, 2217536, 2220033, 2220963, 2221281, 2221312, 2221569, 2222272, 2222627, 2222752, 2223617, 2224192,
- 2225665, 2226339, 2226560, 2227201, 2227936, 2228321, 2230016, 2230851, 2231490, 2231808, 2231841, 2231904,
- 2231969, 2232000, 2232417, 2233856, 2234881, 2235680, 2235906, 2236224, 2236513, 2237664, 2238146, 2238464,
- 2238593, 2238624, 2238689, 2238720, 2238977, 2240096, 2240193, 2240224, 2240609, 2242144, 2242593, 2242720,
- 2243074, 2243393, 2243424, 2243457, 2243488, 2243619, 2244256, 2244609, 2245184, 2245217, 2246016, 2246625,
- 2246688, 2248705, 2248928, 2248961, 2248992, 2249025, 2249152, 2249185, 2249664, 2249697, 2250016, 2250241,
- 2251744, 2252290, 2252608, 2252961, 2253216, 2253281, 2253344, 2253409, 2254112, 2254145, 2254368, 2254401,
- 2254464, 2254497, 2254656, 2254753, 2254784, 2255361, 2255392, 2255777, 2255936, 2260993, 2262688, 2263265,
- 2263392, 2263554, 2263872, 2264033, 2264128, 2265089, 2266624, 2267265, 2267328, 2267361, 2267392, 2267650,
- 2267968, 2273281, 2274784, 2276097, 2276224, 2277377, 2278912, 2279553, 2279584, 2279938, 2280256, 2281473,
- 2282848, 2283265, 2283296, 2283522, 2283840, 2285569, 2286432, 2287106, 2287427, 2287488, 2287617, 2287840,
- 2293761, 2295168, 2298881, 2300930, 2301251, 2301536, 2301921, 2302176, 2302241, 2302272, 2302337, 2302592,
- 2302625, 2302688, 2302721, 2303488, 2303969, 2304000, 2304033, 2304064, 2304514, 2304832, 2307073, 2307328,
- 2307393, 2308640, 2309153, 2309184, 2309217, 2309248, 2310145, 2310176, 2310497, 2311776, 2312001, 2312032,
- 2312705, 2312736, 2313089, 2314560, 2315169, 2315200, 2315777, 2318112, 2326529, 2326816, 2326849, 2328032,
- 2328577, 2328608, 2329090, 2329411, 2330016, 2330177, 2331136, 2334721, 2334944, 2334977, 2335040, 2335073,
- 2336288, 2336961, 2336992, 2337282, 2337600, 2337793, 2337984, 2338017, 2338080, 2338113, 2339136, 2339585,
- 2339616, 2339842, 2340160, 2350081, 2350688, 2351169, 2351200, 2351233, 2351648, 2351681, 2352768, 2353666,
- 2353984, 2356737, 2356768, 2357251, 2357920, 2359297, 2388800, 2392067, 2395616, 2396161, 2402432, 2486785,
- 2489888, 2490369, 2524672, 2525217, 2525408, 2654209, 2672864, 2949121, 2967328, 2967553, 2968544, 2968578,
- 2968896, 2969089, 2971616, 2971650, 2971968, 2972161, 2973120, 2973697, 2975232, 2975745, 2975872, 2976258,
- 2976576, 2976611, 2976832, 2976865, 2977536, 2977697, 2978304, 3000321, 3002371, 3003104, 3006465, 3008864,
- 3009025, 3009056, 3011169, 3011584, 3013633, 3013696, 3013729, 3013760, 3014657, 3211008, 3211265, 3250880,
- 3252225, 3252512, 3538433, 3538560, 3538593, 3538816, 3538849, 3538912, 3538945, 3548256, 3548737, 3548768,
- 3549697, 3549792, 3549857, 3549888, 3550337, 3550464, 3550721, 3563392, 3637249, 3640672, 3640833, 3641248,
- 3641345, 3641632, 3641857, 3642176, 3823619, 3824256, 3824643, 3825280, 3828739, 3829536, 3833857, 3836576,
- 3836609, 3838880, 3838913, 3838976, 3839041, 3839072, 3839137, 3839200, 3839265, 3839392, 3839425, 3839808,
- 3839841, 3839872, 3839905, 3840128, 3840161, 3842240, 3842273, 3842400, 3842465, 3842720, 3842753, 3842976,
- 3843009, 3843904, 3843937, 3844064, 3844097, 3844256, 3844289, 3844320, 3844417, 3844640, 3844673, 3855552,
- 3855617, 3856416, 3856449, 3857248, 3857281, 3858272, 3858305, 3859104, 3859137, 3860128, 3860161, 3860960,
- 3860993, 3861984, 3862017, 3862816, 3862849, 3863840, 3863873, 3864672, 3864705, 3864960, 3865026, 3866624,
- 3923969, 3924960, 3925153, 3925344, 3933697, 3935680, 3940353, 3941792, 3942113, 3942336, 3942402, 3942720,
- 3942849, 3942880, 3953153, 3954112, 3954689, 3956096, 3956226, 3956544, 3971585, 3972480, 3972610, 3972928,
- 3996673, 3996896, 3996929, 3997056, 3997089, 3997152, 3997185, 3997664, 3997697, 4004000, 4004067, 4004352,
- 4005889, 4008064, 4008289, 4008320, 4008450, 4008768, 4034083, 4035968, 4036003, 4036096, 4036131, 4036256,
- 4038691, 4040128, 4040163, 4040640, 4046849, 4046976, 4047009, 4047872, 4047905, 4047968, 4048001, 4048032,
- 4048097, 4048128, 4048161, 4048480, 4048513, 4048640, 4048673, 4048704, 4048737, 4048768, 4048961, 4048992,
- 4049121, 4049152, 4049185, 4049216, 4049249, 4049280, 4049313, 4049408, 4049441, 4049504, 4049537, 4049568,
- 4049633, 4049664, 4049697, 4049728, 4049761, 4049792, 4049825, 4049856, 4049889, 4049920, 4049953, 4050016,
- 4050049, 4050080, 4050145, 4050272, 4050305, 4050528, 4050561, 4050688, 4050721, 4050848, 4050881, 4050912,
- 4050945, 4051264, 4051297, 4051840, 4052001, 4052096, 4052129, 4052288, 4052321, 4052864, 4071427, 4071840,
- 4161026, 4161344, 4194305, 5561344, 5562369, 5695296, 5695489, 5702592, 5702657, 5887040, 5887489, 6126624,
- 6225921, 6243264, 6291457, 6449504, 6449665, 6583808, 4294967295};
+ 0, 1028, 1056, 1538, 1856, 2081, 2912, 3105, 3936, 5124, 5152, 5441,
+ 5472, 5699, 5760, 5793, 5824, 5923, 5953, 5984, 6019, 6112, 6145, 6880,
+ 6913, 7904, 7937, 22592, 22721, 23104, 23553, 23712, 23937, 23968, 24001, 24032,
+ 28161, 28320, 28353, 28416, 28481, 28608, 28641, 28672, 28865, 28896, 28929, 29024,
+ 29057, 29088, 29121, 29760, 29793, 32448, 32481, 36928, 37185, 42496, 42529, 43744,
+ 43809, 43840, 44033, 45344, 47617, 48480, 48609, 48736, 50177, 51552, 52226, 52544,
+ 52673, 52736, 52769, 55936, 55969, 56000, 56481, 56544, 56769, 56834, 57153, 57248,
+ 57313, 57344, 57857, 57888, 57921, 58880, 59809, 62656, 63009, 63040, 63490, 63809,
+ 64864, 65153, 65216, 65345, 65376, 65537, 66240, 66369, 66400, 66689, 66720, 66817,
+ 66848, 67585, 68384, 68609, 68960, 69121, 69888, 69921, 70112, 70657, 72000, 73857,
+ 75584, 75681, 75712, 76289, 76320, 76545, 76864, 76994, 77312, 77345, 77856, 77985,
+ 78240, 78305, 78368, 78433, 79136, 79169, 79392, 79425, 79456, 79553, 79680, 79777,
+ 79808, 80321, 80352, 80769, 80832, 80865, 80960, 81090, 81409, 81472, 81539, 81728,
+ 81793, 81824, 82081, 82272, 82401, 82464, 82529, 83232, 83265, 83488, 83521, 83584,
+ 83617, 83680, 83713, 83776, 84769, 84896, 84929, 84960, 85186, 85504, 85569, 85664,
+ 86177, 86464, 86497, 86592, 86625, 87328, 87361, 87584, 87617, 87680, 87713, 87872,
+ 87969, 88000, 88577, 88608, 89089, 89152, 89282, 89600, 89889, 89920, 90273, 90528,
+ 90593, 90656, 90721, 91424, 91457, 91680, 91713, 91776, 91809, 91968, 92065, 92096,
+ 93057, 93120, 93153, 93248, 93378, 93696, 93729, 93763, 93952, 94305, 94336, 94369,
+ 94560, 94657, 94752, 94785, 94912, 95009, 95072, 95105, 95136, 95169, 95232, 95329,
+ 95392, 95489, 95584, 95681, 96064, 96769, 96800, 97474, 97795, 97888, 98465, 98720,
+ 98753, 98848, 98881, 99616, 99649, 100160, 100257, 100288, 101121, 101216, 101281, 101312,
+ 101377, 101440, 101570, 101888, 102147, 102368, 102401, 102432, 102561, 102816, 102849, 102944,
+ 102977, 103712, 103745, 104064, 104097, 104256, 104353, 104384, 105377, 105440, 105473, 105536,
+ 105666, 105984, 106017, 106080, 106625, 106912, 106945, 107040, 107073, 108384, 108449, 108480,
+ 108993, 109024, 109185, 109280, 109315, 109537, 109632, 109762, 110083, 110368, 110401, 110592,
+ 110753, 111328, 111425, 112192, 112225, 112512, 112545, 112576, 112641, 112864, 113858, 114176,
+ 114721, 116256, 116289, 116352, 116737, 116960, 117250, 117568, 118817, 118880, 118913, 118944,
+ 118977, 119136, 119169, 119936, 119969, 120000, 120033, 120352, 120385, 120448, 120737, 120768,
+ 120833, 120992, 121025, 121056, 121346, 121664, 121729, 121856, 122881, 122912, 123906, 124227,
+ 124544, 124929, 125184, 125217, 126368, 127233, 127392, 131073, 132448, 133089, 133122, 133440,
+ 133633, 133824, 133953, 134080, 134177, 134208, 134305, 134368, 134593, 134688, 134817, 135232,
+ 135617, 135648, 135682, 136000, 136193, 137408, 137441, 137472, 137633, 137664, 137729, 139104,
+ 139137, 149792, 149825, 149952, 150017, 150240, 150273, 150304, 150337, 150464, 150529, 151840,
+ 151873, 152000, 152065, 153120, 153153, 153280, 153345, 153568, 153601, 153632, 153665, 153792,
+ 153857, 154336, 154369, 156192, 156225, 156352, 156417, 158560, 159011, 159648, 159745, 160256,
+ 160769, 163520, 163585, 163776, 163873, 183712, 183777, 184324, 184353, 185184, 185345, 187744,
+ 187843, 187937, 188192, 188417, 188992, 189409, 190016, 190465, 191040, 191489, 191904, 191937,
+ 192032, 192513, 194176, 195297, 195328, 195457, 195488, 195586, 195904, 196099, 196416, 197122,
+ 197440, 197633, 200480, 200705, 200864, 200929, 202016, 202049, 202080, 202241, 204480, 204801,
+ 205792, 207042, 207361, 208320, 208385, 208544, 208897, 210304, 210433, 211264, 211458, 211779,
+ 211808, 212993, 213728, 214017, 215712, 217090, 217408, 217602, 217920, 218337, 218368, 221345,
+ 222848, 223393, 223648, 223746, 224064, 225377, 226336, 226753, 226818, 227137, 228544, 229377,
+ 230528, 231426, 231744, 231841, 231938, 232257, 233408, 233473, 233760, 233985, 235360, 235425,
+ 235520, 236833, 236960, 236993, 237184, 237217, 237280, 237377, 237408, 237569, 243712, 245761,
+ 254656, 254721, 254912, 254977, 256192, 256257, 256448, 256513, 256768, 256801, 256832, 256865,
+ 256896, 256929, 256960, 256993, 257984, 258049, 259744, 259777, 260000, 260033, 260064, 260161,
+ 260256, 260289, 260512, 260609, 260736, 260801, 260992, 261121, 261536, 261697, 261792, 261825,
+ 262048, 262148, 262496, 263428, 263488, 263652, 263680, 265188, 265216, 265731, 265761, 265792,
+ 265859, 266048, 266209, 266243, 266560, 266753, 267168, 270401, 270432, 270561, 270592, 270657,
+ 270976, 271009, 271040, 271137, 271296, 271489, 271520, 271553, 271584, 271617, 271648, 271681,
+ 271808, 271841, 272192, 272257, 272384, 272545, 272704, 272833, 272864, 272899, 274529, 274595,
+ 274752, 297987, 299904, 302403, 303104, 323267, 324224, 360449, 367776, 367969, 368096, 368193,
+ 368256, 368547, 368576, 368641, 369856, 369889, 369920, 370081, 370112, 370177, 371968, 372193,
+ 372224, 372737, 373472, 373761, 373984, 374017, 374240, 374273, 374496, 374529, 374752, 374785,
+ 375008, 375041, 375264, 375297, 375520, 375553, 375776, 378337, 378368, 393220, 393248, 393377,
+ 393443, 393472, 394275, 394560, 394785, 394944, 395011, 395105, 395168, 395297, 398048, 398241,
+ 398336, 398369, 401248, 401281, 401408, 401569, 402944, 402977, 405984, 406083, 406208, 406529,
+ 407552, 409089, 409600, 410627, 410944, 411907, 412160, 412195, 412672, 413699, 414016, 415267,
+ 415744, 425985, 636928, 638977, 1348000, 1350145, 1351616, 1351681, 1360288, 1360385, 1360898, 1361217,
+ 1361280, 1361921, 1363424, 1363937, 1364928, 1364993, 1367235, 1367552, 1368801, 1369088, 1369153, 1372448,
+ 1372513, 1374560, 1374721, 1374784, 1374817, 1374848, 1374881, 1375040, 1375809, 1376320, 1376353, 1376448,
+ 1376481, 1376608, 1376641, 1377376, 1377795, 1377984, 1378305, 1379968, 1380417, 1382016, 1382914, 1383232,
+ 1384001, 1384192, 1384289, 1384320, 1384353, 1384416, 1384450, 1384769, 1385664, 1385985, 1386720, 1387521,
+ 1388448, 1388673, 1390176, 1391073, 1391106, 1391424, 1391617, 1391776, 1391809, 1392130, 1392449, 1392608,
+ 1392641, 1393952, 1394689, 1394784, 1394817, 1395072, 1395202, 1395520, 1395713, 1396448, 1396545, 1396576,
+ 1396673, 1398272, 1398305, 1398336, 1398433, 1398496, 1398561, 1398720, 1398785, 1398816, 1398849, 1398880,
+ 1399649, 1399744, 1399809, 1400160, 1400385, 1400480, 1400865, 1401056, 1401121, 1401312, 1401377, 1401568,
+ 1401857, 1402080, 1402113, 1402336, 1402369, 1403744, 1403777, 1404224, 1404417, 1408096, 1408514, 1408832,
+ 1409025, 1766528, 1766913, 1767648, 1767777, 1769344, 2039809, 2051520, 2051585, 2054976, 2056193, 2056416,
+ 2056801, 2056960, 2057121, 2057152, 2057185, 2057504, 2057537, 2057952, 2057985, 2058144, 2058177, 2058208,
+ 2058241, 2058304, 2058337, 2058400, 2058433, 2061888, 2062945, 2074560, 2075137, 2077184, 2077249, 2078976,
+ 2080257, 2080640, 2084353, 2084512, 2084545, 2088864, 2089474, 2089792, 2090017, 2090848, 2091041, 2091872,
+ 2092225, 2095072, 2095169, 2095360, 2095425, 2095616, 2095681, 2095872, 2095937, 2096032, 2097153, 2097536,
+ 2097569, 2098400, 2098433, 2099040, 2099073, 2099136, 2099169, 2099648, 2099713, 2100160, 2101249, 2105184,
+ 2105571, 2107008, 2107395, 2109216, 2109763, 2109824, 2117633, 2118560, 2118657, 2120224, 2120739, 2121600,
+ 2121729, 2122755, 2122880, 2123169, 2123811, 2123841, 2124099, 2124128, 2124289, 2125504, 2125825, 2126784,
+ 2126849, 2128000, 2128129, 2128384, 2128419, 2128576, 2129921, 2134976, 2135042, 2135360, 2135553, 2136704,
+ 2136833, 2137984, 2138113, 2139392, 2139649, 2141312, 2141697, 2142048, 2142081, 2142560, 2142593, 2142816,
+ 2142849, 2142912, 2142945, 2143296, 2143329, 2143808, 2143841, 2144064, 2144097, 2144160, 2146305, 2156256,
+ 2156545, 2157248, 2157569, 2157824, 2158593, 2158784, 2158817, 2160160, 2160193, 2160480, 2162689, 2162880,
+ 2162945, 2162976, 2163009, 2164416, 2164449, 2164512, 2164609, 2164640, 2164705, 2165440, 2165507, 2165761,
+ 2166496, 2166563, 2166785, 2167776, 2168035, 2168320, 2169857, 2170464, 2170497, 2170560, 2170723, 2170881,
+ 2171587, 2171776, 2171905, 2172736, 2174977, 2176768, 2176899, 2176961, 2177027, 2177536, 2177603, 2179073,
+ 2179104, 2179585, 2179712, 2179745, 2179840, 2179873, 2180800, 2181123, 2181408, 2182145, 2183075, 2183136,
+ 2183169, 2184099, 2184192, 2185217, 2185472, 2185505, 2186400, 2186595, 2186752, 2187265, 2188992, 2189313,
+ 2190016, 2190083, 2190337, 2190944, 2191107, 2191361, 2191936, 2192675, 2192896, 2195457, 2197792, 2199553,
+ 2201184, 2201601, 2203232, 2203459, 2203649, 2204800, 2205186, 2205504, 2214915, 2215904, 2215937, 2217280,
+ 2217473, 2217536, 2220033, 2220963, 2221281, 2221312, 2221569, 2222272, 2222627, 2222752, 2223617, 2224192,
+ 2225665, 2226339, 2226560, 2227201, 2227936, 2228321, 2230016, 2230851, 2231490, 2231808, 2231841, 2231904,
+ 2231969, 2232000, 2232417, 2233856, 2234881, 2235680, 2235906, 2236224, 2236513, 2237664, 2238146, 2238464,
+ 2238593, 2238624, 2238689, 2238720, 2238977, 2240096, 2240193, 2240224, 2240609, 2242144, 2242593, 2242720,
+ 2243074, 2243393, 2243424, 2243457, 2243488, 2243619, 2244256, 2244609, 2245184, 2245217, 2246016, 2246625,
+ 2246688, 2248705, 2248928, 2248961, 2248992, 2249025, 2249152, 2249185, 2249664, 2249697, 2250016, 2250241,
+ 2251744, 2252290, 2252608, 2252961, 2253216, 2253281, 2253344, 2253409, 2254112, 2254145, 2254368, 2254401,
+ 2254464, 2254497, 2254656, 2254753, 2254784, 2255361, 2255392, 2255777, 2255936, 2260993, 2262688, 2263265,
+ 2263392, 2263554, 2263872, 2264033, 2264128, 2265089, 2266624, 2267265, 2267328, 2267361, 2267392, 2267650,
+ 2267968, 2273281, 2274784, 2276097, 2276224, 2277377, 2278912, 2279553, 2279584, 2279938, 2280256, 2281473,
+ 2282848, 2283265, 2283296, 2283522, 2283840, 2285569, 2286432, 2287106, 2287427, 2287488, 2287617, 2287840,
+ 2293761, 2295168, 2298881, 2300930, 2301251, 2301536, 2301921, 2302176, 2302241, 2302272, 2302337, 2302592,
+ 2302625, 2302688, 2302721, 2303488, 2303969, 2304000, 2304033, 2304064, 2304514, 2304832, 2307073, 2307328,
+ 2307393, 2308640, 2309153, 2309184, 2309217, 2309248, 2310145, 2310176, 2310497, 2311776, 2312001, 2312032,
+ 2312705, 2312736, 2313089, 2314560, 2315169, 2315200, 2315777, 2318112, 2326529, 2326816, 2326849, 2328032,
+ 2328577, 2328608, 2329090, 2329411, 2330016, 2330177, 2331136, 2334721, 2334944, 2334977, 2335040, 2335073,
+ 2336288, 2336961, 2336992, 2337282, 2337600, 2337793, 2337984, 2338017, 2338080, 2338113, 2339136, 2339585,
+ 2339616, 2339842, 2340160, 2350081, 2350688, 2351169, 2351200, 2351233, 2351648, 2351681, 2352768, 2353666,
+ 2353984, 2356737, 2356768, 2357251, 2357920, 2359297, 2388800, 2392067, 2395616, 2396161, 2402432, 2486785,
+ 2489888, 2490369, 2524672, 2525217, 2525408, 2654209, 2672864, 2949121, 2967328, 2967553, 2968544, 2968578,
+ 2968896, 2969089, 2971616, 2971650, 2971968, 2972161, 2973120, 2973697, 2975232, 2975745, 2975872, 2976258,
+ 2976576, 2976611, 2976832, 2976865, 2977536, 2977697, 2978304, 3000321, 3002371, 3003104, 3006465, 3008864,
+ 3009025, 3009056, 3011169, 3011584, 3013633, 3013696, 3013729, 3013760, 3014657, 3211008, 3211265, 3250880,
+ 3252225, 3252512, 3538433, 3538560, 3538593, 3538816, 3538849, 3538912, 3538945, 3548256, 3548737, 3548768,
+ 3549697, 3549792, 3549857, 3549888, 3550337, 3550464, 3550721, 3563392, 3637249, 3640672, 3640833, 3641248,
+ 3641345, 3641632, 3641857, 3642176, 3823619, 3824256, 3824643, 3825280, 3828739, 3829536, 3833857, 3836576,
+ 3836609, 3838880, 3838913, 3838976, 3839041, 3839072, 3839137, 3839200, 3839265, 3839392, 3839425, 3839808,
+ 3839841, 3839872, 3839905, 3840128, 3840161, 3842240, 3842273, 3842400, 3842465, 3842720, 3842753, 3842976,
+ 3843009, 3843904, 3843937, 3844064, 3844097, 3844256, 3844289, 3844320, 3844417, 3844640, 3844673, 3855552,
+ 3855617, 3856416, 3856449, 3857248, 3857281, 3858272, 3858305, 3859104, 3859137, 3860128, 3860161, 3860960,
+ 3860993, 3861984, 3862017, 3862816, 3862849, 3863840, 3863873, 3864672, 3864705, 3864960, 3865026, 3866624,
+ 3923969, 3924960, 3925153, 3925344, 3933697, 3935680, 3940353, 3941792, 3942113, 3942336, 3942402, 3942720,
+ 3942849, 3942880, 3953153, 3954112, 3954689, 3956096, 3956226, 3956544, 3971585, 3972480, 3972610, 3972928,
+ 3996673, 3996896, 3996929, 3997056, 3997089, 3997152, 3997185, 3997664, 3997697, 4004000, 4004067, 4004352,
+ 4005889, 4008064, 4008289, 4008320, 4008450, 4008768, 4034083, 4035968, 4036003, 4036096, 4036131, 4036256,
+ 4038691, 4040128, 4040163, 4040640, 4046849, 4046976, 4047009, 4047872, 4047905, 4047968, 4048001, 4048032,
+ 4048097, 4048128, 4048161, 4048480, 4048513, 4048640, 4048673, 4048704, 4048737, 4048768, 4048961, 4048992,
+ 4049121, 4049152, 4049185, 4049216, 4049249, 4049280, 4049313, 4049408, 4049441, 4049504, 4049537, 4049568,
+ 4049633, 4049664, 4049697, 4049728, 4049761, 4049792, 4049825, 4049856, 4049889, 4049920, 4049953, 4050016,
+ 4050049, 4050080, 4050145, 4050272, 4050305, 4050528, 4050561, 4050688, 4050721, 4050848, 4050881, 4050912,
+ 4050945, 4051264, 4051297, 4051840, 4052001, 4052096, 4052129, 4052288, 4052321, 4052864, 4071427, 4071840,
+ 4161026, 4161344, 4194305, 5561344, 5562369, 5695296, 5695489, 5702592, 5702657, 5887040, 5887489, 6126624,
+ 6127105, 6147008, 6225921, 6243264, 6291457, 6449504, 6449665, 6583808, 4294967295};
static const uint16 unicode_simple_category_jump_pos[] = {
1, 9, 27, 27, 27, 27, 36, 44, 55, 55, 57, 63, 68, 75, 86, 91, 102, 114, 119,
@@ -198,8 +198,8 @@ static const uint16 unicode_simple_category_jump_pos[] = {
1428, 1428, 1428, 1428, 1428, 1428, 1428, 1428, 1429, 1432, 1432, 1434, 1435, 1442, 1442, 1442, 1448, 1448, 1448,
1448, 1452, 1452, 1452, 1452, 1452, 1452, 1461, 1461, 1465, 1470, 1470, 1470, 1470, 1470, 1470, 1471, 1476, 1480,
1481, 1537, 1546, 1546, 1546, 1546, 1547, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548,
- 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1551, 1563,
- 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566, 1566};
+ 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1548, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1550, 1551, 1565,
+ 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568, 1568};
static const char *unicode_simple_category_table =
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
@@ -362,62 +362,63 @@ static const int32 prepare_search_character_ranges[] = {
8032, -8033, 8040, -8033, 8048, -8049, 8072, -8065, 8080, -8081, 8088, -8081,
8096, -8097, 8104, -8097, 8112, -8113, 8120, -8113, 8122, -8049, 8124, 8115,
8125, 32, 8126, 953, 8127, 32, 8130, -8131, 8136, -8051, 8140, 8131,
- 8141, 32, 8144, -8145, 8152, -8145, 8154, -8055, 8156, 8156, 8157, 32,
- 8160, -8161, 8168, -8161, 8170, -8059, 8172, 8165, 8173, 32, 8176, -8177,
- 8184, -8057, 8186, -8061, 8188, 8179, 8189, 32, 8191, 8191, 8192, 32,
- 8203, 0, 8208, 32, 8234, 0, 8239, 32, 8288, 0, 8293, 8293,
- 8294, 0, 8304, -8305, 8314, 32, 8319, -8320, 8330, 32, 8335, -8336,
- 8352, 32, 8385, -8386, 8400, 0, 8433, -8434, 8448, 32, 8450, 99,
- 8452, 32, 8455, 603, 8456, 32, 8457, 102, 8458, 8458, 8459, 104,
- 8462, -8463, 8464, 105, 8466, 108, 8467, 8467, 8468, 32, 8469, 110,
- 8470, 32, 8473, -113, 8476, 114, 8478, 32, 8484, 122, 8485, 32,
- 8486, 969, 8487, 32, 8488, 122, 8489, 32, 8490, 107, 8491, 229,
- 8492, -99, 8494, 32, 8495, 8495, 8496, -102, 8498, 8526, 8499, 109,
- 8500, -8501, 8506, 32, 8508, -8509, 8510, 947, 8511, 960, 8512, 32,
- 8517, 100, 8518, -8519, 8522, 32, 8526, 8526, 8527, 32, 8528, -8529,
- 8544, -8561, 8560, -8561, 8579, 8580, 8581, -8582, 8586, 32, 8588, -8589,
- 8592, 32, 9255, -9256, 9280, 32, 9291, -9292, 9372, 32, 9398, -9425,
- 9424, -9425, 9472, 32, 10102, -10103, 10132, 32, 11124, -11125, 11126, 32,
- 11158, 11158, 11159, 32, 11264, -11313, 11312, -11313, 11360, 11361, 11362, 619,
- 11363, 7549, 11364, 637, 11365, -11366, 11367, 11368, 11369, 11370, 11371, 11372,
- 11373, 593, 11374, 625, 11375, 592, 11376, 594, 11377, 2097153, 11380, 11380,
- 11381, 11382, 11383, -11384, 11389, 118, 11390, -576, 11392, 2097153, 11492, 11492,
- 11493, 32, 11499, 11500, 11501, 11502, 11503, 0, 11506, 11507, 11508, -11509,
- 11513, 32, 11517, 11517, 11518, 32, 11520, -11521, 11632, 32, 11633, -11634,
- 11647, 0, 11648, -11649, 11744, 0, 11776, 32, 11823, 11823, 11824, 32,
- 11870, -11871, 11904, 32, 11930, 11930, 11931, 32, 11935, 11935, 11936, 32,
- 12019, -12020, 12272, 32, 12284, -12285, 12288, 32, 12293, -12294, 12296, 32,
- 12321, -12322, 12330, 0, 12336, 32, 12337, -12338, 12342, 32, 12344, -12345,
- 12349, 32, 12352, -12353, 12441, 0, 12443, 32, 12445, -12446, 12448, 32,
- 12449, -12450, 12539, 32, 12540, 0, 12541, -12542, 12688, 32, 12690, -12691,
- 12736, 32, 12772, -12773, 12800, 32, 12831, -12832, 12842, 32, 12868, -12869,
- 12880, 32, 12881, -12882, 12910, 32, 12928, -12929, 12992, 32, 13008, -13009,
- 13055, 32, 13312, -13313, 19904, 32, 19968, -19969, 42128, 32, 42183, -42184,
- 42238, 32, 42240, -42241, 42509, 32, 42512, -42513, 42560, 2097153, 42606, 42606,
- 42607, 0, 42611, 32, 42612, 0, 42622, 32, 42623, 2097153, 42652, -42653,
- 42654, 0, 42656, -42657, 42736, 0, 42738, 32, 42744, -42745, 42752, 32,
- 42775, -42776, 42784, 32, 42786, 2097153, 42800, -42801, 42802, 2097153, 42864, -42865,
- 42873, 42874, 42875, 42876, 42877, 7545, 42878, 2097153, 42888, 42888, 42889, 32,
- 42891, 42892, 42893, 613, 42894, -42895, 42896, 2097153, 42900, -42901, 42902, 2097153,
- 42922, 614, 42923, 604, 42924, 609, 42925, 620, 42926, 618, 42927, 42927,
- 42928, 670, 42929, 647, 42930, 669, 42931, 43859, 42932, 2097153, 42948, 42900,
- 42949, 642, 42950, 7566, 42951, 42952, 42953, 42954, 42955, -42956, 42960, 42961,
- 42962, -42963, 42966, 2097153, 42970, -42971, 42994, 99, 42995, 102, 42996, 113,
- 42997, 42998, 42999, 42999, 43000, 295, 43001, -43002, 43010, 0, 43011, -43012,
- 43014, 0, 43015, -43016, 43019, 0, 43020, -43021, 43043, 0, 43048, 32,
- 43052, 0, 43053, -43054, 43062, 32, 43066, -43067, 43124, 32, 43128, -43129,
- 43136, 0, 43138, -43139, 43188, 0, 43206, -43207, 43214, 32, 43216, -43217,
- 43232, 0, 43250, -43251, 43256, 32, 43259, 43259, 43260, 32, 43261, -43262,
- 43263, 0, 43264, -43265, 43302, 0, 43310, 32, 43312, -43313, 43335, 0,
- 43348, -43349, 43359, 32, 43360, -43361, 43392, 0, 43396, -43397, 43443, 0,
- 43457, 32, 43470, -43471, 43486, 32, 43488, -43489, 43493, 0, 43494, -43495,
- 43561, 0, 43575, -43576, 43587, 0, 43588, -43589, 43596, 0, 43598, -43599,
- 43612, 32, 43616, -43617, 43639, 32, 43642, 43642, 43643, 0, 43646, -43647,
- 43696, 0, 43697, 43697, 43698, 0, 43701, -43702, 43703, 0, 43705, -43706,
- 43710, 0, 43712, 43712, 43713, 0, 43714, -43715, 43742, 32, 43744, -43745,
- 43755, 0, 43760, 32, 43762, -43763, 43765, 0, 43767, -43768, 43867, 32,
- 43868, -43869, 43882, 32, 43884, -43885, 43888, -5025, 43968, -43969, 44003, 0,
- 44011, 32, 44012, 0, 44014, -44015, 55296, 0, 57344, -57345, 64286, 0,
+ 8141, 32, 8144, -8145, 8147, 912, 8148, -8149, 8152, -8145, 8154, -8055,
+ 8156, 8156, 8157, 32, 8160, -8161, 8163, 944, 8164, -8165, 8168, -8161,
+ 8170, -8059, 8172, 8165, 8173, 32, 8176, -8177, 8184, -8057, 8186, -8061,
+ 8188, 8179, 8189, 32, 8191, 8191, 8192, 32, 8203, 0, 8208, 32,
+ 8234, 0, 8239, 32, 8288, 0, 8293, 8293, 8294, 0, 8304, -8305,
+ 8314, 32, 8319, -8320, 8330, 32, 8335, -8336, 8352, 32, 8385, -8386,
+ 8400, 0, 8433, -8434, 8448, 32, 8450, 99, 8452, 32, 8455, 603,
+ 8456, 32, 8457, 102, 8458, 8458, 8459, 104, 8462, -8463, 8464, 105,
+ 8466, 108, 8467, 8467, 8468, 32, 8469, 110, 8470, 32, 8473, -113,
+ 8476, 114, 8478, 32, 8484, 122, 8485, 32, 8486, 969, 8487, 32,
+ 8488, 122, 8489, 32, 8490, 107, 8491, 229, 8492, -99, 8494, 32,
+ 8495, 8495, 8496, -102, 8498, 8526, 8499, 109, 8500, -8501, 8506, 32,
+ 8508, -8509, 8510, 947, 8511, 960, 8512, 32, 8517, 100, 8518, -8519,
+ 8522, 32, 8526, 8526, 8527, 32, 8528, -8529, 8544, -8561, 8560, -8561,
+ 8579, 8580, 8581, -8582, 8586, 32, 8588, -8589, 8592, 32, 9255, -9256,
+ 9280, 32, 9291, -9292, 9372, 32, 9398, -9425, 9424, -9425, 9472, 32,
+ 10102, -10103, 10132, 32, 11124, -11125, 11126, 32, 11158, 11158, 11159, 32,
+ 11264, -11313, 11312, -11313, 11360, 11361, 11362, 619, 11363, 7549, 11364, 637,
+ 11365, -11366, 11367, 11368, 11369, 11370, 11371, 11372, 11373, 593, 11374, 625,
+ 11375, 592, 11376, 594, 11377, 2097153, 11380, 11380, 11381, 11382, 11383, -11384,
+ 11389, 118, 11390, -576, 11392, 2097153, 11492, 11492, 11493, 32, 11499, 11500,
+ 11501, 11502, 11503, 0, 11506, 11507, 11508, -11509, 11513, 32, 11517, 11517,
+ 11518, 32, 11520, -11521, 11632, 32, 11633, -11634, 11647, 0, 11648, -11649,
+ 11744, 0, 11776, 32, 11823, 11823, 11824, 32, 11870, -11871, 11904, 32,
+ 11930, 11930, 11931, 32, 11935, 11935, 11936, 32, 12019, -12020, 12272, 32,
+ 12293, -12294, 12296, 32, 12321, -12322, 12330, 0, 12336, 32, 12337, -12338,
+ 12342, 32, 12344, -12345, 12349, 32, 12352, -12353, 12441, 0, 12443, 32,
+ 12445, -12446, 12448, 32, 12449, -12450, 12539, 32, 12540, 0, 12541, -12542,
+ 12688, 32, 12690, -12691, 12736, 32, 12772, -12773, 12783, 32, 12784, -12785,
+ 12800, 32, 12831, -12832, 12842, 32, 12868, -12869, 12880, 32, 12881, -12882,
+ 12910, 32, 12928, -12929, 12992, 32, 13008, -13009, 13055, 32, 13312, -13313,
+ 19904, 32, 19968, -19969, 42128, 32, 42183, -42184, 42238, 32, 42240, -42241,
+ 42509, 32, 42512, -42513, 42560, 2097153, 42606, 42606, 42607, 0, 42611, 32,
+ 42612, 0, 42622, 32, 42623, 2097153, 42652, -42653, 42654, 0, 42656, -42657,
+ 42736, 0, 42738, 32, 42744, -42745, 42752, 32, 42775, -42776, 42784, 32,
+ 42786, 2097153, 42800, -42801, 42802, 2097153, 42864, -42865, 42873, 42874, 42875, 42876,
+ 42877, 7545, 42878, 2097153, 42888, 42888, 42889, 32, 42891, 42892, 42893, 613,
+ 42894, -42895, 42896, 2097153, 42900, -42901, 42902, 2097153, 42922, 614, 42923, 604,
+ 42924, 609, 42925, 620, 42926, 618, 42927, 42927, 42928, 670, 42929, 647,
+ 42930, 669, 42931, 43859, 42932, 2097153, 42948, 42900, 42949, 642, 42950, 7566,
+ 42951, 42952, 42953, 42954, 42955, -42956, 42960, 42961, 42962, -42963, 42966, 2097153,
+ 42970, -42971, 42994, 99, 42995, 102, 42996, 113, 42997, 42998, 42999, 42999,
+ 43000, 295, 43001, -43002, 43010, 0, 43011, -43012, 43014, 0, 43015, -43016,
+ 43019, 0, 43020, -43021, 43043, 0, 43048, 32, 43052, 0, 43053, -43054,
+ 43062, 32, 43066, -43067, 43124, 32, 43128, -43129, 43136, 0, 43138, -43139,
+ 43188, 0, 43206, -43207, 43214, 32, 43216, -43217, 43232, 0, 43250, -43251,
+ 43256, 32, 43259, 43259, 43260, 32, 43261, -43262, 43263, 0, 43264, -43265,
+ 43302, 0, 43310, 32, 43312, -43313, 43335, 0, 43348, -43349, 43359, 32,
+ 43360, -43361, 43392, 0, 43396, -43397, 43443, 0, 43457, 32, 43470, -43471,
+ 43486, 32, 43488, -43489, 43493, 0, 43494, -43495, 43561, 0, 43575, -43576,
+ 43587, 0, 43588, -43589, 43596, 0, 43598, -43599, 43612, 32, 43616, -43617,
+ 43639, 32, 43642, 43642, 43643, 0, 43646, -43647, 43696, 0, 43697, 43697,
+ 43698, 0, 43701, -43702, 43703, 0, 43705, -43706, 43710, 0, 43712, 43712,
+ 43713, 0, 43714, -43715, 43742, 32, 43744, -43745, 43755, 0, 43760, 32,
+ 43762, -43763, 43765, 0, 43767, -43768, 43867, 32, 43868, -43869, 43882, 32,
+ 43884, -43885, 43888, -5025, 43968, -43969, 44003, 0, 44011, 32, 44012, 0,
+ 44014, -44015, 55296, 0, 57344, -57345, 64261, 64262, 64263, -64264, 64286, 0,
64287, -64288, 64297, 32, 64298, -64299, 64434, 32, 64451, -64452, 64830, 32,
64848, -64849, 64975, 32, 65008, -65009, 65020, 32, 65024, 0, 65040, 32,
65050, -65051, 65056, 0, 65072, 32, 65107, 65107, 65108, 32, 65127, 65127,
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/ChainScheduler.cpp b/protocols/Telegram/tdlib/td/tdutils/test/ChainScheduler.cpp
index 029a4ff366..f93a718138 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/ChainScheduler.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/ChainScheduler.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -116,7 +116,7 @@ TEST(ChainScheduler, Stress) {
td::vector<QueryWithParents> active_queries;
td::ChainScheduler<QueryPtr> scheduler;
- td::vector<td::vector<QueryPtr>> chains(ChainsN);
+ td::vector<td::vector<QueryPtr>> chains(ChainsN + 1);
int inflight_queries{};
int current_query_id{};
int sent_cnt{};
@@ -138,7 +138,7 @@ TEST(ChainScheduler, Stress) {
query->id = query_id;
int chain_n = rnd.fast(1, ChainsN);
td::vector<ChainId> chain_ids(ChainsN);
- std::iota(chain_ids.begin(), chain_ids.end(), 0);
+ std::iota(chain_ids.begin(), chain_ids.end(), 1);
td::rand_shuffle(td::as_mutable_span(chain_ids), rnd);
chain_ids.resize(chain_n);
for (auto chain_id : chain_ids) {
@@ -151,7 +151,7 @@ TEST(ChainScheduler, Stress) {
};
auto check_parents_ok = [&](const QueryWithParents &query_with_parents) -> bool {
- return td::all_of(query_with_parents.parents, [](auto &parent) { return parent->is_ok; });
+ return td::all_of(query_with_parents.parents, [](const auto &parent) { return parent->is_ok; });
};
auto to_query_ptr = [&](TaskId task_id) {
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/ConcurrentHashMap.cpp b/protocols/Telegram/tdlib/td/tdutils/test/ConcurrentHashMap.cpp
index 5ab1f85ad2..7fbe25d0d7 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/ConcurrentHashMap.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/ConcurrentHashMap.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -40,10 +40,6 @@ class ArrayHashMap {
public:
explicit ArrayHashMap(std::size_t n) : array_(n) {
}
- struct Node {
- std::atomic<KeyT> key{KeyT{}};
- std::atomic<ValueT> value{ValueT{}};
- };
static td::string get_name() {
return "ArrayHashMap";
}
@@ -201,21 +197,23 @@ class HashMapBenchmark final : public td::Benchmark {
void run(int n) final {
n = n_;
- td::vector<td::thread> threads;
-
- for (std::size_t i = 0; i < threads_n; i++) {
- std::size_t l = n * i / threads_n;
- std::size_t r = n * (i + 1) / threads_n;
- threads.emplace_back([l, r, this] {
- for (size_t i = l; i < r; i++) {
- auto x = td::narrow_cast<int>((i + 1) * MUL % n_) + 3;
- auto y = td::narrow_cast<int>(i + 2);
- hash_map->insert(x, y);
- }
- });
- }
- for (auto &thread : threads) {
- thread.join();
+ for (int count = 0; count < 1000; count++) {
+ td::vector<td::thread> threads;
+
+ for (std::size_t i = 0; i < threads_n; i++) {
+ std::size_t l = n * i / threads_n;
+ std::size_t r = n * (i + 1) / threads_n;
+ threads.emplace_back([l, r, this] {
+ for (size_t i = l; i < r; i++) {
+ auto x = td::narrow_cast<int>((i + 1) * MUL % n_) + 3;
+ auto y = td::narrow_cast<int>(i + 2);
+ hash_map->insert(x, y);
+ }
+ });
+ }
+ for (auto &thread : threads) {
+ thread.join();
+ }
}
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp b/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp
index 9bdabfac57..2040b85225 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -66,6 +66,7 @@ TEST(MpmcEagerWaiter, stress_one_one) {
}
TEST(MpmcSleepyWaiter, stress_one_one) {
+ return; // the test hangs sometimes; run with --filter MpmcSleepyWaiter_stress_one_one --stress to reproduce
test_waiter_stress_one_one<td::MpmcSleepyWaiter>();
}
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/StealingQueue.cpp b/protocols/Telegram/tdlib/td/tdutils/test/StealingQueue.cpp
index c0ccabf793..0a2f0d083a 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/StealingQueue.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/StealingQueue.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -108,7 +108,7 @@ TEST(AtomicRead, simple2) {
TEST(StealingQueue, simple) {
td::uint64 sum = 0;
- std::atomic<td::uint64> got_sum{0};
+ std::atomic<td::uint64> check_sum{0};
td::Stage run;
td::Stage check;
@@ -138,10 +138,10 @@ TEST(StealingQueue, simple) {
sum += x_sum[x];
gq.push(x, id);
}
- got_sum = 0;
+ check_sum = 0;
}
run.wait(round * threads_n);
- while (got_sum.load() != sum) {
+ while (check_sum.load() != sum) {
auto x = [&] {
int res;
if (lq[id].local_pop(res)) {
@@ -159,8 +159,8 @@ TEST(StealingQueue, simple) {
if (x == 0) {
continue;
}
- //LOG(ERROR) << x << " " << got_sum.load() << " " << sum;
- got_sum.fetch_add(x, std::memory_order_relaxed);
+ //LOG(ERROR) << x << " " << check_sum.load() << " " << sum;
+ check_sum.fetch_add(x, std::memory_order_relaxed);
lq[id].local_push(x - 1, [&](auto y) {
//LOG(ERROR) << "OVERFLOW";
gq.push(y, id);
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/hashset_benchmark.cpp b/protocols/Telegram/tdlib/td/tdutils/test/hashset_benchmark.cpp
index dbfcaa992b..35e1ae5a5e 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/hashset_benchmark.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/hashset_benchmark.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -590,7 +590,7 @@ BENCHMARK_TEMPLATE(BM_mask, td::MaskSse2);
#endif
template <class KeyT, class ValueT, class HashT = td::Hash<KeyT>, class EqT = std::equal_to<KeyT>>
-using FlatHashMapImpl = td::FlatHashTable<td::MapNode<KeyT, ValueT>, HashT, EqT>;
+using FlatHashMapImpl = td::FlatHashTable<td::MapNode<KeyT, ValueT, EqT>, HashT, EqT>;
#define FOR_EACH_TABLE(F) \
F(FlatHashMapImpl) \
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/json.cpp b/protocols/Telegram/tdlib/td/tdutils/test/json.cpp
index 8b42751a3d..928dea80eb 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/json.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/json.cpp
@@ -1,12 +1,14 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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/benchmark.h"
#include "td/utils/common.h"
#include "td/utils/JsonBuilder.h"
#include "td/utils/logging.h"
+#include "td/utils/Parser.h"
#include "td/utils/Slice.h"
#include "td/utils/StringBuilder.h"
#include "td/utils/tests.h"
@@ -89,3 +91,210 @@ TEST(JSON, kphp) {
"{\"keyboard\":[[\"\\u2022 abcdefg\"],[\"\\u2022 hijklmnop\"],[\"\\u2022 "
"qrstuvwxyz\"]],\"one_time_keyboard\":true}");
}
+
+TEST(JSON, json_object_get_field) {
+ const td::string encoded_object =
+ "{\"null\":null,\"bool\":true,\"int\":\"1\",\"int2\":2,\"long\":\"123456789012\",\"long2\":2123456789012,"
+ "\"double\":12345678901.1,\"string\":\"string\",\"string2\":12345e+1,\"array\":[],\"object\":{}}";
+ {
+ td::string encoded_object_copy = encoded_object;
+ auto value = td::json_decode(encoded_object_copy).move_as_ok();
+ auto &object = value.get_object();
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("null")), "null");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("bool")), "true");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("bool")), "null");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("int")), "\"1\"");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("int2")), "2");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("int3")), "null");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("long")), "\"123456789012\"");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("long2")), "2123456789012");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("double")), "12345678901.1");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("string")), "\"string\"");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("string2")), "12345e+1");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("array")), "[]");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("object")), "{}");
+ ASSERT_EQ(td::json_encode<td::string>(object.extract_field("")), "null");
+ }
+
+ {
+ td::string encoded_object_copy = encoded_object;
+ auto value = td::json_decode(encoded_object_copy).move_as_ok();
+ auto &object = value.get_object();
+ ASSERT_TRUE(object.extract_optional_field("int", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_optional_field("int", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_optional_field("int2", td::JsonValue::Type::Number).is_ok());
+ ASSERT_TRUE(object.extract_optional_field("int2", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_optional_field("int3", td::JsonValue::Type::Number).is_ok());
+ ASSERT_TRUE(object.extract_optional_field("int3", td::JsonValue::Type::Null).is_ok());
+ ASSERT_EQ(object.extract_optional_field("int", td::JsonValue::Type::String).ok().get_string(), "1");
+ ASSERT_TRUE(object.extract_optional_field("int", td::JsonValue::Type::Number).is_error());
+ ASSERT_EQ(object.extract_optional_field("int", td::JsonValue::Type::Null).ok().type(), td::JsonValue::Type::Null);
+
+ ASSERT_TRUE(object.extract_required_field("long", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_required_field("long", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_required_field("long2", td::JsonValue::Type::Number).is_ok());
+ ASSERT_TRUE(object.extract_required_field("long2", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_required_field("long3", td::JsonValue::Type::Number).is_error());
+ ASSERT_TRUE(object.extract_required_field("long3", td::JsonValue::Type::Null).is_error());
+ ASSERT_EQ(object.extract_required_field("long", td::JsonValue::Type::String).ok().get_string(), "123456789012");
+ ASSERT_TRUE(object.extract_required_field("long", td::JsonValue::Type::Number).is_error());
+ ASSERT_EQ(object.extract_required_field("long", td::JsonValue::Type::Null).ok().type(), td::JsonValue::Type::Null);
+ }
+
+ td::string encoded_object_copy = encoded_object;
+ auto value = td::json_decode(encoded_object_copy).move_as_ok();
+ const auto &object = value.get_object();
+ ASSERT_TRUE(object.has_field("null"));
+ ASSERT_TRUE(object.has_field("object"));
+ ASSERT_TRUE(!object.has_field(""));
+ ASSERT_TRUE(!object.has_field("objec"));
+ ASSERT_TRUE(!object.has_field("object2"));
+
+ ASSERT_TRUE(object.get_optional_bool_field("int").is_error());
+ ASSERT_EQ(object.get_optional_bool_field("bool").ok(), true);
+ ASSERT_EQ(object.get_optional_bool_field("bool", false).ok(), true);
+ ASSERT_EQ(object.get_required_bool_field("bool").ok(), true);
+ ASSERT_EQ(object.get_optional_bool_field("bool3").ok(), false);
+ ASSERT_EQ(object.get_optional_bool_field("bool4", true).ok(), true);
+ ASSERT_TRUE(object.get_required_bool_field("bool5").is_error());
+
+ ASSERT_TRUE(object.get_optional_int_field("null").is_error());
+ ASSERT_EQ(object.get_optional_int_field("int").ok(), 1);
+ ASSERT_EQ(object.get_optional_int_field("int").ok(), 1);
+ ASSERT_EQ(object.get_required_int_field("int").ok(), 1);
+ ASSERT_EQ(object.get_optional_int_field("int2").ok(), 2);
+ ASSERT_EQ(object.get_optional_int_field("int2").ok(), 2);
+ ASSERT_EQ(object.get_required_int_field("int2").ok(), 2);
+ ASSERT_EQ(object.get_optional_int_field("int3").ok(), 0);
+ ASSERT_EQ(object.get_optional_int_field("int4", 5).ok(), 5);
+ ASSERT_TRUE(object.get_required_int_field("int5").is_error());
+ ASSERT_EQ(object.get_optional_int_field("long").is_error(), true);
+ ASSERT_EQ(object.get_optional_int_field("long2").is_error(), true);
+
+ ASSERT_TRUE(object.get_optional_long_field("null").is_error());
+ ASSERT_EQ(object.get_optional_long_field("long").ok(), 123456789012);
+ ASSERT_EQ(object.get_optional_long_field("long").ok(), 123456789012);
+ ASSERT_EQ(object.get_required_long_field("long").ok(), 123456789012);
+ ASSERT_EQ(object.get_optional_long_field("long2").ok(), 2123456789012);
+ ASSERT_EQ(object.get_optional_long_field("long2").ok(), 2123456789012);
+ ASSERT_EQ(object.get_required_long_field("long2").ok(), 2123456789012);
+ ASSERT_EQ(object.get_optional_long_field("long3").ok(), 0);
+ ASSERT_EQ(object.get_optional_long_field("long4", 5).ok(), 5);
+ ASSERT_TRUE(object.get_required_long_field("long5").is_error());
+ ASSERT_EQ(object.get_optional_long_field("int").ok(), 1);
+ ASSERT_EQ(object.get_optional_long_field("int2").ok(), 2);
+
+ auto are_equal_double = [](double lhs, double rhs) {
+ return rhs - 1e-3 < lhs && lhs < rhs + 1e-3;
+ };
+
+ ASSERT_TRUE(object.get_optional_double_field("null").is_error());
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("double").ok(), 12345678901.1));
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("double").ok(), 12345678901.1));
+ ASSERT_TRUE(are_equal_double(object.get_required_double_field("double").ok(), 12345678901.1));
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("long2").ok(), 2123456789012.0));
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("long2").ok(), 2123456789012.0));
+ ASSERT_TRUE(are_equal_double(object.get_required_double_field("long2").ok(), 2123456789012.0));
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("double3").ok(), 0.0));
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("double4", -5.23).ok(), -5.23));
+ ASSERT_TRUE(object.get_required_double_field("double5").is_error());
+ ASSERT_TRUE(object.get_optional_double_field("int").is_error());
+ ASSERT_TRUE(are_equal_double(object.get_optional_double_field("int2").ok(), 2));
+
+ ASSERT_TRUE(object.get_optional_string_field("null").is_error());
+ ASSERT_EQ(object.get_optional_string_field("string").ok(), "string");
+ ASSERT_EQ(object.get_optional_string_field("string").ok(), "string");
+ ASSERT_EQ(object.get_required_string_field("string").ok(), "string");
+ ASSERT_EQ(object.get_optional_string_field("string2").ok(), "12345e+1");
+ ASSERT_EQ(object.get_optional_string_field("string2").ok(), "12345e+1");
+ ASSERT_EQ(object.get_required_string_field("string2").ok(), "12345e+1");
+ ASSERT_EQ(object.get_optional_string_field("string3").ok(), td::string());
+ ASSERT_EQ(object.get_optional_string_field("string4", "abacaba").ok(), "abacaba");
+ ASSERT_TRUE(object.get_required_string_field("string5").is_error());
+ ASSERT_EQ(object.get_optional_string_field("int").ok(), "1");
+ ASSERT_EQ(object.get_optional_string_field("int2").ok(), "2");
+}
+
+class JsonStringDecodeBenchmark final : public td::Benchmark {
+ td::string str_;
+
+ public:
+ explicit JsonStringDecodeBenchmark(td::string str) : str_('"' + str + '"') {
+ }
+
+ td::string get_description() const final {
+ return td::string("JsonStringDecodeBenchmark") + str_.substr(1, 6);
+ }
+
+ void run(int n) final {
+ for (int i = 0; i < n; i++) {
+ auto str = str_;
+ td::Parser parser(str);
+ td::json_string_decode(parser).ensure();
+ }
+ }
+};
+
+TEST(JSON, bench_json_string_decode) {
+ td::bench(JsonStringDecodeBenchmark(td::string(1000, 'a')));
+ td::bench(JsonStringDecodeBenchmark(td::string(1000, '\\')));
+ td::string str;
+ for (int i = 32; i < 128; i++) {
+ if (i == 'u') {
+ continue;
+ }
+ str += "a\\";
+ str += static_cast<char>(i);
+ }
+ td::bench(JsonStringDecodeBenchmark(str));
+}
+
+static void test_string_decode(td::string str, const td::string &result) {
+ auto str_copy = str;
+ td::Parser skip_parser(str_copy);
+ auto status = td::json_string_skip(skip_parser);
+ ASSERT_TRUE(status.is_ok());
+ ASSERT_TRUE(skip_parser.empty());
+
+ td::Parser parser(str);
+ auto r_value = td::json_string_decode(parser);
+ ASSERT_TRUE(r_value.is_ok());
+ ASSERT_TRUE(parser.empty());
+ ASSERT_EQ(result, r_value.ok());
+}
+
+static void test_string_decode_error(td::string str) {
+ auto str_copy = str;
+ td::Parser skip_parser(str_copy);
+ auto status = td::json_string_skip(skip_parser);
+ ASSERT_TRUE(status.is_error());
+
+ td::Parser parser(str);
+ auto r_value = td::json_string_decode(parser);
+ ASSERT_TRUE(r_value.is_error());
+}
+
+TEST(JSON, string_decode) {
+ test_string_decode("\"\"", "");
+ test_string_decode("\"abacaba\"", "abacaba");
+ test_string_decode(
+ "\"\\1\\a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\l\\m\\n\\o\\p\\q\\r\\s\\t\\u00201\\v\\w\\x\\y\\z\\U\\\"\\\\\\/\\+\\-\"",
+ "1a\bcde\fghijklm\nopq\rs\t 1vwxyzU\"\\/+-");
+ test_string_decode("\"\\u0373\\ud7FB\\uD840\\uDC04\\uD840a\\uD840\\u0373\"",
+ "\xCD\xB3\xED\x9F\xBB\xF0\xA0\x80\x84\xed\xa1\x80\x61\xed\xa1\x80\xCD\xB3");
+
+ test_string_decode_error(" \"\"");
+ test_string_decode_error("\"");
+ test_string_decode_error("\"\\");
+ test_string_decode_error("\"\\b'");
+ test_string_decode_error("\"\\u\"");
+ test_string_decode_error("\"\\u123\"");
+ test_string_decode_error("\"\\u123g\"");
+ test_string_decode_error("\"\\u123G\"");
+ test_string_decode_error("\"\\u123 \"");
+ test_string_decode_error("\"\\ug123\"");
+ test_string_decode_error("\"\\uG123\"");
+ test_string_decode_error("\"\\u 123\"");
+ test_string_decode_error("\"\\uD800\\ug123\"");
+ test_string_decode_error("\"\\uD800\\u123\"");
+}
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/misc.cpp b/protocols/Telegram/tdlib/td/tdutils/test/misc.cpp
index e1612a9924..cabd4e6efb 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/misc.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/misc.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -7,6 +7,7 @@
#include "td/utils/algorithm.h"
#include "td/utils/as.h"
#include "td/utils/base64.h"
+#include "td/utils/benchmark.h"
#include "td/utils/BigNum.h"
#include "td/utils/bits.h"
#include "td/utils/CancellationToken.h"
@@ -82,14 +83,11 @@ TEST(Misc, update_atime_saves_mtime) {
r_file.move_as_ok().close();
auto info = td::stat(name).ok();
- td::int32 tests_ok = 0;
td::int32 tests_wa = 0;
for (int i = 0; i < 10000; i++) {
td::update_atime(name).ensure();
auto new_info = td::stat(name).ok();
- if (info.mtime_nsec_ == new_info.mtime_nsec_) {
- tests_ok++;
- } else {
+ if (info.mtime_nsec_ != new_info.mtime_nsec_) {
tests_wa++;
info.mtime_nsec_ = new_info.mtime_nsec_;
}
@@ -265,6 +263,65 @@ TEST(Misc, base64) {
ASSERT_TRUE(td::base64url_encode("ab><cd") == "YWI-PGNk");
}
+static void test_zero_encode(td::Slice str, td::Slice expected_zero = td::Slice(),
+ td::Slice expected_zero_one = td::Slice()) {
+ auto encoded = td::zero_encode(str);
+ if (!expected_zero.empty()) {
+ ASSERT_EQ(encoded, expected_zero);
+ }
+ ASSERT_EQ(td::zero_decode(encoded), str);
+
+ encoded = td::zero_one_encode(str);
+ if (!expected_zero_one.empty()) {
+ ASSERT_EQ(encoded, expected_zero_one);
+ }
+ ASSERT_EQ(td::zero_one_decode(encoded), str);
+}
+
+TEST(Misc, zero_encode) {
+ td::string str;
+ for (unsigned char i = 1; i < 255; i++) {
+ str += static_cast<char>(i);
+ }
+ test_zero_encode(str, str, str);
+
+ test_zero_encode("");
+ test_zero_encode(td::Slice("\0"), td::Slice("\0\1"), td::Slice("\0\1"));
+ test_zero_encode(td::Slice("\0\xff\0\xff\0\xff\0\xff\0\xff\0\xff\0\xff"),
+ td::Slice("\0\1\xff\0\1\xff\0\1\xff\0\1\xff\0\1\xff\0\1\xff\0\1\xff"),
+ td::Slice("\0\1\xff\1\0\1\xff\1\0\1\xff\1\0\1\xff\1\0\1\xff\1\0\1\xff\1\0\1\xff\1"));
+ test_zero_encode(td::Slice("\0\0\xff\xff\0\0\xff\xff\0\0\xff\xff\0\0\xff\xff\0\0\xff\xff\0\0\xff\xff"),
+ td::Slice("\0\2\xff\xff\0\2\xff\xff\0\2\xff\xff\0\2\xff\xff\0\2\xff\xff\0\2\xff\xff"),
+ td::Slice("\0\2\xff\2\0\2\xff\2\0\2\xff\2\0\2\xff\2\0\2\xff\2\0\2\xff\2"));
+ test_zero_encode(td::Slice("\0\0\0\0\0\xff\xff\xff\xff\xff"), td::Slice("\0\5\xff\xff\xff\xff\xff"),
+ td::Slice("\0\5\xff\5"));
+ test_zero_encode(td::Slice(
+ "\0\0\0\0\0\xff\xff\xff\xff\xff\0\0\0\0\0\xff\xff\xff\xff\xff\0\0\0\0\0\xff\xff\xff\xff\xff\0\0\0\0\0\xff\xff\xff"
+ "\xff\xff\0\0\0\0\0\xff\xff\xff\xff\xff\0\0\0\0\0\xff\xff\xff\xff\xff\0\0\0\0\0\xff\xff\xff\xff\xff"));
+ test_zero_encode(td::string(1000, '\0'));
+ test_zero_encode(str + td::string(1000, '\0') + str + td::string(1000, '\xff') + str);
+}
+
+class ZeroEncodeBenchmark final : public td::Benchmark {
+ public:
+ td::string get_description() const final {
+ return "ZeroEncodeBenchmark";
+ }
+
+ void run(int n) final {
+ for (int i = 0; i < n; i++) {
+ zero_encode(
+ td::Slice("\x02\x00\x00\x02\x01\x00\x00\x00\x19\x01\x00\x00\x7c\xc8\x64\xc1\x04\xec\x82\xb8\x20\x9e\xa0\x8d"
+ "\x1e\xbe\xb2\x79\xc4\x5a\x4c\x1e\x49\x1e\x00\x00\xa9\xa7\x31\x1b\x80\x9f\x11\x46\xfc\x97\xde\x6a"
+ "\x18\x6e\xc0\x73\x01\x00\x00\x00\x02\x00\x00\x00\x6d\x00\x00\x00\x30\x04"));
+ }
+ }
+};
+
+TEST(Misc, bench_zero_encode) {
+ td::bench(ZeroEncodeBenchmark());
+}
+
template <class T>
static void test_remove_if(td::vector<int> v, const T &func, const td::vector<int> &expected) {
td::remove_if(v, func);
@@ -349,6 +406,49 @@ TEST(Misc, remove) {
test_remove(v, 1, v);
}
+static void test_add_to_top(td::vector<int> v, size_t max_size, int new_value, const td::vector<int> &expected) {
+ auto u = v;
+ td::add_to_top(v, max_size, new_value);
+ ASSERT_EQ(expected, v);
+
+ td::add_to_top_if(u, max_size, new_value, [new_value](int value) { return value == new_value; });
+ ASSERT_EQ(expected, u);
+}
+
+static void test_add_to_top_if(td::vector<int> v, int max_size, int new_value, const td::vector<int> &expected) {
+ td::add_to_top_if(v, max_size, new_value, [new_value](int value) { return value % 10 == new_value % 10; });
+ ASSERT_EQ(expected, v);
+}
+
+TEST(Misc, add_to_top) {
+ test_add_to_top({}, 0, 1, {1});
+ test_add_to_top({}, 1, 1, {1});
+ test_add_to_top({}, 6, 1, {1});
+
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 3, 2, {2, 1, 3, 4, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 1, {1, 2, 3, 4, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 1, {1, 2, 3, 4, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 2, {2, 1, 3, 4, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 2, {2, 1, 3, 4, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 4, {4, 1, 2, 3, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 4, {4, 1, 2, 3, 5, 6});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 6, {6, 1, 2, 3, 4, 5});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 6, {6, 1, 2, 3, 4, 5});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 6, 7, {7, 1, 2, 3, 4, 5});
+ test_add_to_top({1, 2, 3, 4, 5, 6}, 7, 7, {7, 1, 2, 3, 4, 5, 6});
+
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 11, {1, 2, 3, 4, 5, 6});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 21, {1, 2, 3, 4, 5, 6});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 32, {2, 1, 3, 4, 5, 6});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 42, {2, 1, 3, 4, 5, 6});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 54, {4, 1, 2, 3, 5, 6});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 64, {4, 1, 2, 3, 5, 6});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 76, {6, 1, 2, 3, 4, 5});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 86, {6, 1, 2, 3, 4, 5});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 6, 97, {97, 1, 2, 3, 4, 5});
+ test_add_to_top_if({1, 2, 3, 4, 5, 6}, 7, 87, {87, 1, 2, 3, 4, 5, 6});
+}
+
static void test_unique(td::vector<int> v, const td::vector<int> &expected) {
auto v_str = td::transform(v, &td::to_string<int>);
auto expected_str = td::transform(expected, &td::to_string<int>);
diff --git a/protocols/Telegram/tdlib/td/tdutils/test/pq.cpp b/protocols/Telegram/tdlib/td/tdutils/test/pq.cpp
index 0983ea814c..b499b31e0f 100644
--- a/protocols/Telegram/tdlib/td/tdutils/test/pq.cpp
+++ b/protocols/Telegram/tdlib/td/tdutils/test/pq.cpp
@@ -1,5 +1,5 @@
//
-// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
+// 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)
@@ -112,8 +112,8 @@ static void test_pq_slow(td::uint64 first, td::uint64 second) {
td::BigNum p_res = td::BigNum::from_binary(p_str);
td::BigNum q_res = td::BigNum::from_binary(q_str);
- LOG_CHECK(p_str == p.to_binary()) << td::tag("got", p_res.to_decimal()) << td::tag("expected", first);
- LOG_CHECK(q_str == q.to_binary()) << td::tag("got", q_res.to_decimal()) << td::tag("expected", second);
+ LOG_CHECK(p_str == p.to_binary()) << td::tag("receive", p_res.to_decimal()) << td::tag("expected", first);
+ LOG_CHECK(q_str == q.to_binary()) << td::tag("receive", q_res.to_decimal()) << td::tag("expected", second);
}
#endif