summaryrefslogtreecommitdiff
path: root/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp')
-rw-r--r--protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp b/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp
new file mode 100644
index 0000000000..ce64bbc9a6
--- /dev/null
+++ b/protocols/Telegram/tdlib/td/tdutils/td/utils/StringBuilder.cpp
@@ -0,0 +1,102 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2018
+//
+// 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/StringBuilder.h"
+
+#include "td/utils/misc.h"
+#include "td/utils/port/thread_local.h"
+
+#include <cstdio>
+#include <locale>
+#include <sstream>
+
+namespace td {
+
+// TODO: optimize
+StringBuilder &StringBuilder::operator<<(int x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%d", x);
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(unsigned int x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%u", x);
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(long int x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%ld", x);
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(long unsigned int x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%lu", x);
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(long long int x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%lld", x);
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(long long unsigned int x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%llu", x);
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(FixedDouble x) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+
+ static TD_THREAD_LOCAL std::stringstream *ss;
+ if (init_thread_local<std::stringstream>(ss)) {
+ ss->imbue(std::locale::classic());
+ ss->setf(std::ios_base::fixed, std::ios_base::floatfield);
+ } else {
+ ss->str(std::string());
+ ss->clear();
+ }
+ ss->precision(x.precision);
+ *ss << x.d;
+
+ int len = narrow_cast<int>(static_cast<std::streamoff>(ss->tellp()));
+ auto left = end_ptr_ + reserved_size - current_ptr_;
+ if (unlikely(len >= left)) {
+ error_flag_ = true;
+ len = left ? narrow_cast<int>(left - 1) : 0;
+ }
+ ss->read(current_ptr_, len);
+ current_ptr_ += len;
+ return *this;
+}
+
+StringBuilder &StringBuilder::operator<<(const void *ptr) {
+ if (unlikely(end_ptr_ < current_ptr_)) {
+ return on_error();
+ }
+ current_ptr_ += std::snprintf(current_ptr_, reserved_size, "%p", ptr);
+ return *this;
+}
+
+} // namespace td