Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-22 14:04:28 +01:00
parent 81b91f4139
commit f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions

View file

@ -0,0 +1,54 @@
/*
* 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.
*/
#include "rtc_base/strings/audio_format_to_string.h"
#include <utility>
#include "rtc_base/strings/string_builder.h"
namespace rtc {
std::string ToString(const webrtc::SdpAudioFormat& saf) {
char sb_buf[1024];
rtc::SimpleStringBuilder sb(sb_buf);
sb << "{name: " << saf.name;
sb << ", clockrate_hz: " << saf.clockrate_hz;
sb << ", num_channels: " << saf.num_channels;
sb << ", parameters: {";
const char* sep = "";
for (const auto& kv : saf.parameters) {
sb << sep << kv.first << ": " << kv.second;
sep = ", ";
}
sb << "}}";
return sb.str();
}
std::string ToString(const webrtc::AudioCodecInfo& aci) {
char sb_buf[1024];
rtc::SimpleStringBuilder sb(sb_buf);
sb << "{sample_rate_hz: " << aci.sample_rate_hz;
sb << ", num_channels: " << aci.num_channels;
sb << ", default_bitrate_bps: " << aci.default_bitrate_bps;
sb << ", min_bitrate_bps: " << aci.min_bitrate_bps;
sb << ", max_bitrate_bps: " << aci.max_bitrate_bps;
sb << ", allow_comfort_noise: " << aci.allow_comfort_noise;
sb << ", supports_network_adaption: " << aci.supports_network_adaption;
sb << "}";
return sb.str();
}
std::string ToString(const webrtc::AudioCodecSpec& acs) {
char sb_buf[1024];
rtc::SimpleStringBuilder sb(sb_buf);
sb << "{format: " << ToString(acs.format);
sb << ", info: " << ToString(acs.info);
sb << "}";
return sb.str();
}
} // namespace rtc

View file

@ -0,0 +1,24 @@
/*
* 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_AUDIO_FORMAT_TO_STRING_H_
#define RTC_BASE_STRINGS_AUDIO_FORMAT_TO_STRING_H_
#include <string>
#include "api/audio_codecs/audio_format.h"
namespace rtc {
std::string ToString(const webrtc::SdpAudioFormat& saf);
std::string ToString(const webrtc::AudioCodecInfo& saf);
std::string ToString(const webrtc::AudioCodecSpec& acs);
} // namespace rtc
#endif // RTC_BASE_STRINGS_AUDIO_FORMAT_TO_STRING_H_

View file

@ -0,0 +1,296 @@
/*
* Copyright 2004 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.
*/
#include "rtc_base/strings/json.h"
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include "absl/strings/string_view.h"
#include "rtc_base/string_encode.h"
namespace rtc {
bool GetStringFromJson(const Json::Value& in, std::string* out) {
if (!in.isString()) {
if (in.isBool()) {
*out = rtc::ToString(in.asBool());
} else if (in.isInt()) {
*out = rtc::ToString(in.asInt());
} else if (in.isUInt()) {
*out = rtc::ToString(in.asUInt());
} else if (in.isDouble()) {
*out = rtc::ToString(in.asDouble());
} else {
return false;
}
} else {
*out = in.asString();
}
return true;
}
bool GetIntFromJson(const Json::Value& in, int* out) {
bool ret;
if (!in.isString()) {
ret = in.isConvertibleTo(Json::intValue);
if (ret) {
*out = in.asInt();
}
} else {
long val; // NOLINT
const char* c_str = in.asCString();
char* end_ptr;
errno = 0;
val = strtol(c_str, &end_ptr, 10); // NOLINT
ret = (end_ptr != c_str && *end_ptr == '\0' && !errno && val >= INT_MIN &&
val <= INT_MAX);
*out = val;
}
return ret;
}
bool GetUIntFromJson(const Json::Value& in, unsigned int* out) {
bool ret;
if (!in.isString()) {
ret = in.isConvertibleTo(Json::uintValue);
if (ret) {
*out = in.asUInt();
}
} else {
unsigned long val; // NOLINT
const char* c_str = in.asCString();
char* end_ptr;
errno = 0;
val = strtoul(c_str, &end_ptr, 10); // NOLINT
ret = (end_ptr != c_str && *end_ptr == '\0' && !errno && val <= UINT_MAX);
*out = val;
}
return ret;
}
bool GetBoolFromJson(const Json::Value& in, bool* out) {
bool ret;
if (!in.isString()) {
ret = in.isConvertibleTo(Json::booleanValue);
if (ret) {
*out = in.asBool();
}
} else {
if (in.asString() == "true") {
*out = true;
ret = true;
} else if (in.asString() == "false") {
*out = false;
ret = true;
} else {
ret = false;
}
}
return ret;
}
bool GetDoubleFromJson(const Json::Value& in, double* out) {
bool ret;
if (!in.isString()) {
ret = in.isConvertibleTo(Json::realValue);
if (ret) {
*out = in.asDouble();
}
} else {
double val;
const char* c_str = in.asCString();
char* end_ptr;
errno = 0;
val = strtod(c_str, &end_ptr);
ret = (end_ptr != c_str && *end_ptr == '\0' && !errno);
*out = val;
}
return ret;
}
namespace {
template <typename T>
bool JsonArrayToVector(const Json::Value& value,
bool (*getter)(const Json::Value& in, T* out),
std::vector<T>* vec) {
vec->clear();
if (!value.isArray()) {
return false;
}
for (Json::Value::ArrayIndex i = 0; i < value.size(); ++i) {
T val;
if (!getter(value[i], &val)) {
return false;
}
vec->push_back(val);
}
return true;
}
// Trivial getter helper
bool GetValueFromJson(const Json::Value& in, Json::Value* out) {
*out = in;
return true;
}
} // unnamed namespace
bool JsonArrayToValueVector(const Json::Value& in,
std::vector<Json::Value>* out) {
return JsonArrayToVector(in, GetValueFromJson, out);
}
bool JsonArrayToIntVector(const Json::Value& in, std::vector<int>* out) {
return JsonArrayToVector(in, GetIntFromJson, out);
}
bool JsonArrayToUIntVector(const Json::Value& in,
std::vector<unsigned int>* out) {
return JsonArrayToVector(in, GetUIntFromJson, out);
}
bool JsonArrayToStringVector(const Json::Value& in,
std::vector<std::string>* out) {
return JsonArrayToVector(in, GetStringFromJson, out);
}
bool JsonArrayToBoolVector(const Json::Value& in, std::vector<bool>* out) {
return JsonArrayToVector(in, GetBoolFromJson, out);
}
bool JsonArrayToDoubleVector(const Json::Value& in, std::vector<double>* out) {
return JsonArrayToVector(in, GetDoubleFromJson, out);
}
namespace {
template <typename T>
Json::Value VectorToJsonArray(const std::vector<T>& vec) {
Json::Value result(Json::arrayValue);
for (size_t i = 0; i < vec.size(); ++i) {
result.append(Json::Value(vec[i]));
}
return result;
}
} // unnamed namespace
Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in) {
return VectorToJsonArray(in);
}
Json::Value IntVectorToJsonArray(const std::vector<int>& in) {
return VectorToJsonArray(in);
}
Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in) {
return VectorToJsonArray(in);
}
Json::Value StringVectorToJsonArray(const std::vector<std::string>& in) {
return VectorToJsonArray(in);
}
Json::Value BoolVectorToJsonArray(const std::vector<bool>& in) {
return VectorToJsonArray(in);
}
Json::Value DoubleVectorToJsonArray(const std::vector<double>& in) {
return VectorToJsonArray(in);
}
bool GetValueFromJsonArray(const Json::Value& in, size_t n, Json::Value* out) {
if (!in.isArray() || !in.isValidIndex(static_cast<int>(n))) {
return false;
}
*out = in[static_cast<Json::Value::ArrayIndex>(n)];
return true;
}
bool GetIntFromJsonArray(const Json::Value& in, size_t n, int* out) {
Json::Value x;
return GetValueFromJsonArray(in, n, &x) && GetIntFromJson(x, out);
}
bool GetUIntFromJsonArray(const Json::Value& in, size_t n, unsigned int* out) {
Json::Value x;
return GetValueFromJsonArray(in, n, &x) && GetUIntFromJson(x, out);
}
bool GetStringFromJsonArray(const Json::Value& in, size_t n, std::string* out) {
Json::Value x;
return GetValueFromJsonArray(in, n, &x) && GetStringFromJson(x, out);
}
bool GetBoolFromJsonArray(const Json::Value& in, size_t n, bool* out) {
Json::Value x;
return GetValueFromJsonArray(in, n, &x) && GetBoolFromJson(x, out);
}
bool GetDoubleFromJsonArray(const Json::Value& in, size_t n, double* out) {
Json::Value x;
return GetValueFromJsonArray(in, n, &x) && GetDoubleFromJson(x, out);
}
bool GetValueFromJsonObject(const Json::Value& in,
absl::string_view k,
Json::Value* out) {
std::string k_str(k);
if (!in.isObject() || !in.isMember(k_str)) {
return false;
}
*out = in[k_str];
return true;
}
bool GetIntFromJsonObject(const Json::Value& in,
absl::string_view k,
int* out) {
Json::Value x;
return GetValueFromJsonObject(in, k, &x) && GetIntFromJson(x, out);
}
bool GetUIntFromJsonObject(const Json::Value& in,
absl::string_view k,
unsigned int* out) {
Json::Value x;
return GetValueFromJsonObject(in, k, &x) && GetUIntFromJson(x, out);
}
bool GetStringFromJsonObject(const Json::Value& in,
absl::string_view k,
std::string* out) {
Json::Value x;
return GetValueFromJsonObject(in, k, &x) && GetStringFromJson(x, out);
}
bool GetBoolFromJsonObject(const Json::Value& in,
absl::string_view k,
bool* out) {
Json::Value x;
return GetValueFromJsonObject(in, k, &x) && GetBoolFromJson(x, out);
}
bool GetDoubleFromJsonObject(const Json::Value& in,
absl::string_view k,
double* out) {
Json::Value x;
return GetValueFromJsonObject(in, k, &x) && GetDoubleFromJson(x, out);
}
std::string JsonValueToString(const Json::Value& json) {
Json::StreamWriterBuilder builder;
std::string output = Json::writeString(builder, json);
return output.substr(0, output.size() - 1); // trim trailing newline
}
} // namespace rtc

View file

@ -0,0 +1,83 @@
/*
* Copyright 2004 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_JSON_H_
#define RTC_BASE_STRINGS_JSON_H_
#include <string>
#include <vector>
#include "absl/strings/string_view.h"
#include "third_party/jsoncpp/json.h"
namespace rtc {
///////////////////////////////////////////////////////////////////////////////
// JSON Helpers
///////////////////////////////////////////////////////////////////////////////
// Robust conversion operators, better than the ones in JsonCpp.
bool GetIntFromJson(const Json::Value& in, int* out);
bool GetUIntFromJson(const Json::Value& in, unsigned int* out);
bool GetStringFromJson(const Json::Value& in, std::string* out);
bool GetBoolFromJson(const Json::Value& in, bool* out);
bool GetDoubleFromJson(const Json::Value& in, double* out);
// Pull values out of a JSON array.
bool GetValueFromJsonArray(const Json::Value& in, size_t n, Json::Value* out);
bool GetIntFromJsonArray(const Json::Value& in, size_t n, int* out);
bool GetUIntFromJsonArray(const Json::Value& in, size_t n, unsigned int* out);
bool GetStringFromJsonArray(const Json::Value& in, size_t n, std::string* out);
bool GetBoolFromJsonArray(const Json::Value& in, size_t n, bool* out);
bool GetDoubleFromJsonArray(const Json::Value& in, size_t n, double* out);
// Convert json arrays to std::vector
bool JsonArrayToValueVector(const Json::Value& in,
std::vector<Json::Value>* out);
bool JsonArrayToIntVector(const Json::Value& in, std::vector<int>* out);
bool JsonArrayToUIntVector(const Json::Value& in,
std::vector<unsigned int>* out);
bool JsonArrayToStringVector(const Json::Value& in,
std::vector<std::string>* out);
bool JsonArrayToBoolVector(const Json::Value& in, std::vector<bool>* out);
bool JsonArrayToDoubleVector(const Json::Value& in, std::vector<double>* out);
// Convert std::vector to json array
Json::Value ValueVectorToJsonArray(const std::vector<Json::Value>& in);
Json::Value IntVectorToJsonArray(const std::vector<int>& in);
Json::Value UIntVectorToJsonArray(const std::vector<unsigned int>& in);
Json::Value StringVectorToJsonArray(const std::vector<std::string>& in);
Json::Value BoolVectorToJsonArray(const std::vector<bool>& in);
Json::Value DoubleVectorToJsonArray(const std::vector<double>& in);
// Pull values out of a JSON object.
bool GetValueFromJsonObject(const Json::Value& in,
absl::string_view k,
Json::Value* out);
bool GetIntFromJsonObject(const Json::Value& in, absl::string_view k, int* out);
bool GetUIntFromJsonObject(const Json::Value& in,
absl::string_view k,
unsigned int* out);
bool GetStringFromJsonObject(const Json::Value& in,
absl::string_view k,
std::string* out);
bool GetBoolFromJsonObject(const Json::Value& in,
absl::string_view k,
bool* out);
bool GetDoubleFromJsonObject(const Json::Value& in,
absl::string_view k,
double* out);
// Writes out a Json value as a string.
std::string JsonValueToString(const Json::Value& json);
} // namespace rtc
#endif // RTC_BASE_STRINGS_JSON_H_

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2021 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_STR_JOIN_H_
#define RTC_BASE_STRINGS_STR_JOIN_H_
#include <string>
#include "absl/strings/string_view.h"
#include "rtc_base/strings/string_builder.h"
namespace webrtc {
template <typename Range>
std::string StrJoin(const Range& seq, absl::string_view delimiter) {
rtc::StringBuilder sb;
int idx = 0;
for (const typename Range::value_type& elem : seq) {
if (idx > 0) {
sb << delimiter;
}
sb << elem;
++idx;
}
return sb.Release();
}
template <typename Range, typename Functor>
std::string StrJoin(const Range& seq,
absl::string_view delimiter,
const Functor& fn) {
rtc::StringBuilder sb;
int idx = 0;
for (const typename Range::value_type& elem : seq) {
if (idx > 0) {
sb << delimiter;
}
fn(sb, elem);
++idx;
}
return sb.Release();
}
} // namespace webrtc
#endif // RTC_BASE_STRINGS_STR_JOIN_H_

View file

@ -0,0 +1,134 @@
/*
* 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.
*/
#include "rtc_base/strings/string_builder.h"
#include <stdarg.h>
#include <cstdio>
#include <cstring>
#include "absl/strings/string_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_minmax.h"
namespace rtc {
SimpleStringBuilder::SimpleStringBuilder(rtc::ArrayView<char> buffer)
: buffer_(buffer) {
buffer_[0] = '\0';
RTC_DCHECK(IsConsistent());
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(char ch) {
return operator<<(absl::string_view(&ch, 1));
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(absl::string_view str) {
RTC_DCHECK_LT(size_ + str.length(), buffer_.size())
<< "Buffer size was insufficient";
const size_t chars_added =
rtc::SafeMin(str.length(), buffer_.size() - size_ - 1);
memcpy(&buffer_[size_], str.data(), chars_added);
size_ += chars_added;
buffer_[size_] = '\0';
RTC_DCHECK(IsConsistent());
return *this;
}
// Numeric conversion routines.
//
// We use std::[v]snprintf instead of std::to_string because:
// * std::to_string relies on the current locale for formatting purposes,
// and therefore concurrent calls to std::to_string from multiple threads
// may result in partial serialization of calls
// * snprintf allows us to print the number directly into our buffer.
// * avoid allocating a std::string (potential heap alloc).
// TODO(tommi): Switch to std::to_chars in C++17.
SimpleStringBuilder& SimpleStringBuilder::operator<<(int i) {
return AppendFormat("%d", i);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(unsigned i) {
return AppendFormat("%u", i);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(long i) { // NOLINT
return AppendFormat("%ld", i);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(long long i) { // NOLINT
return AppendFormat("%lld", i);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(
unsigned long i) { // NOLINT
return AppendFormat("%lu", i);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(
unsigned long long i) { // NOLINT
return AppendFormat("%llu", i);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(float f) {
return AppendFormat("%g", f);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(double f) {
return AppendFormat("%g", f);
}
SimpleStringBuilder& SimpleStringBuilder::operator<<(long double f) {
return AppendFormat("%Lg", f);
}
SimpleStringBuilder& SimpleStringBuilder::AppendFormat(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
const int len =
std::vsnprintf(&buffer_[size_], buffer_.size() - size_, fmt, args);
if (len >= 0) {
const size_t chars_added = rtc::SafeMin(len, buffer_.size() - 1 - size_);
size_ += chars_added;
RTC_DCHECK_EQ(len, chars_added) << "Buffer size was insufficient";
} else {
// This should never happen, but we're paranoid, so re-write the
// terminator in case vsnprintf() overwrote it.
RTC_DCHECK_NOTREACHED();
buffer_[size_] = '\0';
}
va_end(args);
RTC_DCHECK(IsConsistent());
return *this;
}
StringBuilder& StringBuilder::AppendFormat(const char* fmt, ...) {
va_list args, copy;
va_start(args, fmt);
va_copy(copy, args);
const int predicted_length = std::vsnprintf(nullptr, 0, fmt, copy);
va_end(copy);
RTC_DCHECK_GE(predicted_length, 0);
if (predicted_length > 0) {
const size_t size = str_.size();
str_.resize(size + predicted_length);
// Pass "+ 1" to vsnprintf to include space for the '\0'.
const int actual_length =
std::vsnprintf(&str_[size], predicted_length + 1, fmt, args);
RTC_DCHECK_GE(actual_length, 0);
}
va_end(args);
return *this;
}
} // namespace rtc

View file

@ -0,0 +1,170 @@
/*
* 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_

View file

@ -0,0 +1,41 @@
/*
* Copyright 2020 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.
*/
#include "rtc_base/strings/string_format.h"
#include <cstdarg>
#include "rtc_base/checks.h"
namespace rtc {
namespace {
// This is an arbitrary limitation that can be changed if necessary, or removed
// if someone has the time and inclination to replicate the fancy logic from
// Chromium's base::StringPrinf().
constexpr int kMaxSize = 512;
} // namespace
std::string StringFormat(const char* fmt, ...) {
char buffer[kMaxSize];
va_list args;
va_start(args, fmt);
int result = vsnprintf(buffer, kMaxSize, fmt, args);
va_end(args);
RTC_DCHECK_GE(result, 0) << "ERROR: vsnprintf() failed with error " << result;
RTC_DCHECK_LT(result, kMaxSize)
<< "WARNING: string was truncated from " << result << " to "
<< (kMaxSize - 1) << " characters";
return std::string(buffer);
}
} // namespace rtc

View file

@ -0,0 +1,31 @@
/*
* Copyright 2020 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_FORMAT_H_
#define RTC_BASE_STRINGS_STRING_FORMAT_H_
#include <string>
namespace rtc {
#if defined(__GNUC__)
#define RTC_PRINTF_FORMAT(format_param, dots_param) \
__attribute__((format(printf, format_param, dots_param)))
#else
#define RTC_PRINTF_FORMAT(format_param, dots_param)
#endif
// Return a C++ string given printf-like input.
// Based on base::StringPrintf() in Chrome but without its fancy dynamic memory
// allocation for any size of the input buffer.
std::string StringFormat(const char* fmt, ...) RTC_PRINTF_FORMAT(1, 2);
} // namespace rtc
#endif // RTC_BASE_STRINGS_STRING_FORMAT_H_