171 lines
5.0 KiB
C
171 lines
5.0 KiB
C
|
/*
|
||
|
* Copyright 2018 The WebRTC Project Authors. All rights reserved.
|
||
|
*
|
||
|
* Use of this source code is governed by a BSD-style license
|
||
|
* that can be found in the LICENSE file in the root of the source
|
||
|
* tree. An additional intellectual property rights grant can be found
|
||
|
* in the file PATENTS. All contributing project authors may
|
||
|
* be found in the AUTHORS file in the root of the source tree.
|
||
|
*/
|
||
|
|
||
|
#ifndef RTC_BASE_STRINGS_STRING_BUILDER_H_
|
||
|
#define RTC_BASE_STRINGS_STRING_BUILDER_H_
|
||
|
|
||
|
#include <cstdio>
|
||
|
#include <string>
|
||
|
#include <utility>
|
||
|
|
||
|
#include "absl/strings/string_view.h"
|
||
|
#include "api/array_view.h"
|
||
|
#include "rtc_base/string_encode.h"
|
||
|
|
||
|
namespace rtc {
|
||
|
|
||
|
// This is a minimalistic string builder class meant to cover the most cases of
|
||
|
// when you might otherwise be tempted to use a stringstream (discouraged for
|
||
|
// anything except logging). It uses a fixed-size buffer provided by the caller
|
||
|
// and concatenates strings and numbers into it, allowing the results to be
|
||
|
// read via `str()`.
|
||
|
class SimpleStringBuilder {
|
||
|
public:
|
||
|
explicit SimpleStringBuilder(rtc::ArrayView<char> buffer);
|
||
|
SimpleStringBuilder(const SimpleStringBuilder&) = delete;
|
||
|
SimpleStringBuilder& operator=(const SimpleStringBuilder&) = delete;
|
||
|
|
||
|
SimpleStringBuilder& operator<<(char ch);
|
||
|
SimpleStringBuilder& operator<<(absl::string_view str);
|
||
|
SimpleStringBuilder& operator<<(int i);
|
||
|
SimpleStringBuilder& operator<<(unsigned i);
|
||
|
SimpleStringBuilder& operator<<(long i); // NOLINT
|
||
|
SimpleStringBuilder& operator<<(long long i); // NOLINT
|
||
|
SimpleStringBuilder& operator<<(unsigned long i); // NOLINT
|
||
|
SimpleStringBuilder& operator<<(unsigned long long i); // NOLINT
|
||
|
SimpleStringBuilder& operator<<(float f);
|
||
|
SimpleStringBuilder& operator<<(double f);
|
||
|
SimpleStringBuilder& operator<<(long double f);
|
||
|
|
||
|
// Returns a pointer to the built string. The name `str()` is borrowed for
|
||
|
// compatibility reasons as we replace usage of stringstream throughout the
|
||
|
// code base.
|
||
|
const char* str() const { return buffer_.data(); }
|
||
|
|
||
|
// Returns the length of the string. The name `size()` is picked for STL
|
||
|
// compatibility reasons.
|
||
|
size_t size() const { return size_; }
|
||
|
|
||
|
// Allows appending a printf style formatted string.
|
||
|
#if defined(__GNUC__)
|
||
|
__attribute__((__format__(__printf__, 2, 3)))
|
||
|
#endif
|
||
|
SimpleStringBuilder&
|
||
|
AppendFormat(const char* fmt, ...);
|
||
|
|
||
|
private:
|
||
|
bool IsConsistent() const {
|
||
|
return size_ <= buffer_.size() - 1 && buffer_[size_] == '\0';
|
||
|
}
|
||
|
|
||
|
// An always-zero-terminated fixed-size buffer that we write to. The fixed
|
||
|
// size allows the buffer to be stack allocated, which helps performance.
|
||
|
// Having a fixed size is furthermore useful to avoid unnecessary resizing
|
||
|
// while building it.
|
||
|
const rtc::ArrayView<char> buffer_;
|
||
|
|
||
|
// Represents the number of characters written to the buffer.
|
||
|
// This does not include the terminating '\0'.
|
||
|
size_t size_ = 0;
|
||
|
};
|
||
|
|
||
|
// A string builder that supports dynamic resizing while building a string.
|
||
|
// The class is based around an instance of std::string and allows moving
|
||
|
// ownership out of the class once the string has been built.
|
||
|
// Note that this class uses the heap for allocations, so SimpleStringBuilder
|
||
|
// might be more efficient for some use cases.
|
||
|
class StringBuilder {
|
||
|
public:
|
||
|
StringBuilder() {}
|
||
|
explicit StringBuilder(absl::string_view s) : str_(s) {}
|
||
|
|
||
|
// TODO(tommi): Support construction from StringBuilder?
|
||
|
StringBuilder(const StringBuilder&) = delete;
|
||
|
StringBuilder& operator=(const StringBuilder&) = delete;
|
||
|
|
||
|
StringBuilder& operator<<(const absl::string_view str) {
|
||
|
str_.append(str.data(), str.length());
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(char c) = delete;
|
||
|
|
||
|
StringBuilder& operator<<(int i) {
|
||
|
str_ += rtc::ToString(i);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(unsigned i) {
|
||
|
str_ += rtc::ToString(i);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(long i) { // NOLINT
|
||
|
str_ += rtc::ToString(i);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(long long i) { // NOLINT
|
||
|
str_ += rtc::ToString(i);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(unsigned long i) { // NOLINT
|
||
|
str_ += rtc::ToString(i);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(unsigned long long i) { // NOLINT
|
||
|
str_ += rtc::ToString(i);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(float f) {
|
||
|
str_ += rtc::ToString(f);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(double f) {
|
||
|
str_ += rtc::ToString(f);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
StringBuilder& operator<<(long double f) {
|
||
|
str_ += rtc::ToString(f);
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
const std::string& str() const { return str_; }
|
||
|
|
||
|
void Clear() { str_.clear(); }
|
||
|
|
||
|
size_t size() const { return str_.size(); }
|
||
|
|
||
|
std::string Release() {
|
||
|
std::string ret = std::move(str_);
|
||
|
str_.clear();
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
// Allows appending a printf style formatted string.
|
||
|
StringBuilder& AppendFormat(const char* fmt, ...)
|
||
|
#if defined(__GNUC__)
|
||
|
__attribute__((__format__(__printf__, 2, 3)))
|
||
|
#endif
|
||
|
;
|
||
|
|
||
|
private:
|
||
|
std::string str_;
|
||
|
};
|
||
|
|
||
|
} // namespace rtc
|
||
|
|
||
|
#endif // RTC_BASE_STRINGS_STRING_BUILDER_H_
|