From 2d3186e00178f2267c57cdca87a710307a8b4e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20M=C3=B6ller?= Date: Mon, 24 Jan 2022 14:15:03 +0100 Subject: [PATCH] Introduce a variant of rtc::split that returns a vector of string_view Intended to be compatible with absl::StrSplit, but without the binary cost of that dependency. Bug: webrtc:13579 Change-Id: I167726903d74b8d5f299886cfb3e5d60610ddb93 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/247185 Reviewed-by: Ali Tofigh Reviewed-by: Harald Alvestrand Commit-Queue: Niels Moller Cr-Commit-Position: refs/heads/main@{#35780} --- pc/BUILD.gn | 1 + pc/sdp_serializer.cc | 14 +++++++------- pc/simulcast_description.cc | 2 +- pc/simulcast_description.h | 4 +++- rtc_base/string_encode.cc | 22 +++++++++++++++------- rtc_base/string_encode.h | 5 ++++- 6 files changed, 31 insertions(+), 17 deletions(-) diff --git a/pc/BUILD.gn b/pc/BUILD.gn index f29b558b41..09d31a5d12 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -210,6 +210,7 @@ rtc_source_set("simulcast_description") { "../rtc_base:socket_address", "../rtc_base/system:rtc_export", ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings" ] } rtc_source_set("rtc_pc") { diff --git a/pc/sdp_serializer.cc b/pc/sdp_serializer.cc index 3f46db5bb0..cdd2f2e9ad 100644 --- a/pc/sdp_serializer.cc +++ b/pc/sdp_serializer.cc @@ -101,33 +101,33 @@ rtc::StringBuilder& operator<<(rtc::StringBuilder& builder, // sc-id = [sc-id-paused] rid-id // rid-id = 1*(alpha-numeric / "-" / "_") ; see: I-D.ietf-mmusic-rid RTCErrorOr ParseSimulcastLayerList(const std::string& str) { - std::vector tokens; - rtc::split(str, kDelimiterSemicolonChar, &tokens); + std::vector tokens = + rtc::split(str, kDelimiterSemicolonChar); if (tokens.empty()) { return ParseError("Layer list cannot be empty."); } SimulcastLayerList result; - for (const std::string& token : tokens) { + for (const absl::string_view& token : tokens) { if (token.empty()) { return ParseError("Simulcast alternative layer list is empty."); } - std::vector rid_tokens; - rtc::split(token, kDelimiterCommaChar, &rid_tokens); + std::vector rid_tokens = + rtc::split(token, kDelimiterCommaChar); if (rid_tokens.empty()) { return ParseError("Simulcast alternative layer list is malformed."); } std::vector layers; - for (const std::string& rid_token : rid_tokens) { + for (const absl::string_view& rid_token : rid_tokens) { if (rid_token.empty() || rid_token == kSimulcastPausedStream) { return ParseError("Rid must not be empty."); } bool paused = rid_token[0] == kSimulcastPausedStreamChar; - std::string rid = paused ? rid_token.substr(1) : rid_token; + absl::string_view rid = paused ? rid_token.substr(1) : rid_token; layers.push_back(SimulcastLayer(rid, paused)); } diff --git a/pc/simulcast_description.cc b/pc/simulcast_description.cc index 0ae3e2074e..ec87415677 100644 --- a/pc/simulcast_description.cc +++ b/pc/simulcast_description.cc @@ -14,7 +14,7 @@ namespace cricket { -SimulcastLayer::SimulcastLayer(const std::string& rid, bool is_paused) +SimulcastLayer::SimulcastLayer(absl::string_view rid, bool is_paused) : rid{rid}, is_paused{is_paused} { RTC_DCHECK(!rid.empty()); } diff --git a/pc/simulcast_description.h b/pc/simulcast_description.h index f7ae28837e..7caf164de5 100644 --- a/pc/simulcast_description.h +++ b/pc/simulcast_description.h @@ -16,6 +16,8 @@ #include #include +#include "absl/strings/string_view.h" + namespace cricket { // Describes a Simulcast Layer. @@ -23,7 +25,7 @@ namespace cricket { // See also: https://tools.ietf.org/html/draft-ietf-mmusic-rid-15 for // an explanation about rids. struct SimulcastLayer final { - SimulcastLayer(const std::string& rid, bool is_paused); + SimulcastLayer(absl::string_view rid, bool is_paused); SimulcastLayer(const SimulcastLayer& other) = default; SimulcastLayer& operator=(const SimulcastLayer& other) = default; diff --git a/rtc_base/string_encode.cc b/rtc_base/string_encode.cc index 364eaa0f0f..85fb992507 100644 --- a/rtc_base/string_encode.cc +++ b/rtc_base/string_encode.cc @@ -214,19 +214,27 @@ std::string join(const std::vector& source, char delimiter) { return joined_string; } +std::vector split(absl::string_view source, char delimiter) { + std::vector fields; + size_t last = 0; + for (size_t i = 0; i < source.length(); ++i) { + if (source[i] == delimiter) { + fields.push_back(source.substr(last, i - last)); + last = i + 1; + } + } + fields.push_back(source.substr(last)); + return fields; +} + size_t split(absl::string_view source, char delimiter, std::vector* fields) { RTC_DCHECK(fields); fields->clear(); - size_t last = 0; - for (size_t i = 0; i < source.length(); ++i) { - if (source[i] == delimiter) { - fields->emplace_back(source.substr(last, i - last)); - last = i + 1; - } + for (const absl::string_view field_view : split(source, delimiter)) { + fields->emplace_back(field_view); } - fields->emplace_back(source.substr(last)); return fields->size(); } diff --git a/rtc_base/string_encode.h b/rtc_base/string_encode.h index 356fdfaaf7..d636f7f227 100644 --- a/rtc_base/string_encode.h +++ b/rtc_base/string_encode.h @@ -62,7 +62,10 @@ size_t hex_decode_with_delimiter(char* buffer, std::string join(const std::vector& source, char delimiter); // Splits the source string into multiple fields separated by delimiter, -// with duplicates of delimiter creating empty fields. +// with duplicates of delimiter creating empty fields. Empty input produces a +// single, empty, field. +std::vector split(absl::string_view source, char delimiter); + size_t split(absl::string_view source, char delimiter, std::vector* fields);