1 /* 2 * Copyright 2018 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef RTC_BASE_STRINGS_STRING_BUILDER_H_ 12 #define RTC_BASE_STRINGS_STRING_BUILDER_H_ 13 14 #include <cstdio> 15 #include <string> 16 #include <utility> 17 18 #include "absl/strings/string_view.h" 19 #include "api/array_view.h" 20 #include "rtc_base/string_encode.h" 21 22 namespace rtc { 23 24 // This is a minimalistic string builder class meant to cover the most cases of 25 // when you might otherwise be tempted to use a stringstream (discouraged for 26 // anything except logging). It uses a fixed-size buffer provided by the caller 27 // and concatenates strings and numbers into it, allowing the results to be 28 // read via |str()|. 29 class SimpleStringBuilder { 30 public: 31 explicit SimpleStringBuilder(rtc::ArrayView<char> buffer); 32 SimpleStringBuilder(const SimpleStringBuilder&) = delete; 33 SimpleStringBuilder& operator=(const SimpleStringBuilder&) = delete; 34 35 SimpleStringBuilder& operator<<(const char* str); 36 SimpleStringBuilder& operator<<(char ch); 37 SimpleStringBuilder& operator<<(const std::string& str); 38 SimpleStringBuilder& operator<<(int i); 39 SimpleStringBuilder& operator<<(unsigned i); 40 SimpleStringBuilder& operator<<(long i); // NOLINT 41 SimpleStringBuilder& operator<<(long long i); // NOLINT 42 SimpleStringBuilder& operator<<(unsigned long i); // NOLINT 43 SimpleStringBuilder& operator<<(unsigned long long i); // NOLINT 44 SimpleStringBuilder& operator<<(float f); 45 SimpleStringBuilder& operator<<(double f); 46 SimpleStringBuilder& operator<<(long double f); 47 48 // Returns a pointer to the built string. The name |str()| is borrowed for 49 // compatibility reasons as we replace usage of stringstream throughout the 50 // code base. str()51 const char* str() const { return buffer_.data(); } 52 53 // Returns the length of the string. The name |size()| is picked for STL 54 // compatibility reasons. size()55 size_t size() const { return size_; } 56 57 // Allows appending a printf style formatted string. 58 #if defined(__GNUC__) 59 __attribute__((__format__(__printf__, 2, 3))) 60 #endif 61 SimpleStringBuilder& 62 AppendFormat(const char* fmt, ...); 63 64 // An alternate way from operator<<() to append a string. This variant is 65 // slightly more efficient when the length of the string to append, is known. 66 SimpleStringBuilder& Append(const char* str, size_t length); 67 68 private: IsConsistent()69 bool IsConsistent() const { 70 return size_ <= buffer_.size() - 1 && buffer_[size_] == '\0'; 71 } 72 73 // An always-zero-terminated fixed-size buffer that we write to. The fixed 74 // size allows the buffer to be stack allocated, which helps performance. 75 // Having a fixed size is furthermore useful to avoid unnecessary resizing 76 // while building it. 77 const rtc::ArrayView<char> buffer_; 78 79 // Represents the number of characters written to the buffer. 80 // This does not include the terminating '\0'. 81 size_t size_ = 0; 82 }; 83 84 // A string builder that supports dynamic resizing while building a string. 85 // The class is based around an instance of std::string and allows moving 86 // ownership out of the class once the string has been built. 87 // Note that this class uses the heap for allocations, so SimpleStringBuilder 88 // might be more efficient for some use cases. 89 class StringBuilder { 90 public: StringBuilder()91 StringBuilder() {} StringBuilder(absl::string_view s)92 explicit StringBuilder(absl::string_view s) : str_(s) {} 93 94 // TODO(tommi): Support construction from StringBuilder? 95 StringBuilder(const StringBuilder&) = delete; 96 StringBuilder& operator=(const StringBuilder&) = delete; 97 98 StringBuilder& operator<<(const absl::string_view str) { 99 str_.append(str.data(), str.length()); 100 return *this; 101 } 102 103 StringBuilder& operator<<(char c) = delete; 104 105 StringBuilder& operator<<(int i) { 106 str_ += rtc::ToString(i); 107 return *this; 108 } 109 110 StringBuilder& operator<<(unsigned i) { 111 str_ += rtc::ToString(i); 112 return *this; 113 } 114 115 StringBuilder& operator<<(long i) { // NOLINT 116 str_ += rtc::ToString(i); 117 return *this; 118 } 119 120 StringBuilder& operator<<(long long i) { // NOLINT 121 str_ += rtc::ToString(i); 122 return *this; 123 } 124 125 StringBuilder& operator<<(unsigned long i) { // NOLINT 126 str_ += rtc::ToString(i); 127 return *this; 128 } 129 130 StringBuilder& operator<<(unsigned long long i) { // NOLINT 131 str_ += rtc::ToString(i); 132 return *this; 133 } 134 135 StringBuilder& operator<<(float f) { 136 str_ += rtc::ToString(f); 137 return *this; 138 } 139 140 StringBuilder& operator<<(double f) { 141 str_ += rtc::ToString(f); 142 return *this; 143 } 144 145 StringBuilder& operator<<(long double f) { 146 str_ += rtc::ToString(f); 147 return *this; 148 } 149 str()150 const std::string& str() const { return str_; } 151 Clear()152 void Clear() { str_.clear(); } 153 size()154 size_t size() const { return str_.size(); } 155 Release()156 std::string Release() { 157 std::string ret = std::move(str_); 158 str_.clear(); 159 return ret; 160 } 161 162 // Allows appending a printf style formatted string. 163 StringBuilder& AppendFormat(const char* fmt, ...) 164 #if defined(__GNUC__) 165 __attribute__((__format__(__printf__, 2, 3))) 166 #endif 167 ; 168 169 private: 170 std::string str_; 171 }; 172 173 } // namespace rtc 174 175 #endif // RTC_BASE_STRINGS_STRING_BUILDER_H_ 176