diff --git a/examples/BUILD.gn b/examples/BUILD.gn index afb410d90d..0a5ee10f84 100644 --- a/examples/BUILD.gn +++ b/examples/BUILD.gn @@ -67,7 +67,11 @@ rtc_library("read_auth_file") { "turnserver/read_auth_file.cc", "turnserver/read_auth_file.h", ] - deps = [ "../rtc_base" ] + deps = [ + "../api:array_view", + "../rtc_base", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/strings:strings" ] } if (rtc_include_tests) { diff --git a/examples/turnserver/read_auth_file.cc b/examples/turnserver/read_auth_file.cc index 3ad5c2bb39..4b0b21b8ae 100644 --- a/examples/turnserver/read_auth_file.cc +++ b/examples/turnserver/read_auth_file.cc @@ -12,6 +12,8 @@ #include +#include "absl/strings/string_view.h" +#include "api/array_view.h" #include "rtc_base/string_encode.h" namespace webrtc_examples { @@ -23,8 +25,8 @@ std::map ReadAuthFile(std::istream* s) { if (sep == std::string::npos) continue; char buf[32]; - size_t len = rtc::hex_decode(buf, sizeof(buf), line.data() + sep + 1, - line.size() - sep - 1); + size_t len = rtc::hex_decode(rtc::ArrayView(buf), + absl::string_view(line).substr(sep + 1)); if (len > 0) { name_to_key.emplace(line.substr(0, sep), std::string(buf, len)); } diff --git a/modules/audio_coding/acm2/audio_coding_module_unittest.cc b/modules/audio_coding/acm2/audio_coding_module_unittest.cc index c429cc4723..1a63fcdcd2 100644 --- a/modules/audio_coding/acm2/audio_coding_module_unittest.cc +++ b/modules/audio_coding/acm2/audio_coding_module_unittest.cc @@ -1114,8 +1114,7 @@ class AcmSenderBitExactnessOldApi : public ::testing::Test, // Extract and verify the payload checksum. rtc::Buffer checksum_result(payload_checksum_->Size()); payload_checksum_->Finish(checksum_result.data(), checksum_result.size()); - checksum_string = - rtc::hex_encode(checksum_result.data(), checksum_result.size()); + checksum_string = rtc::hex_encode(checksum_result); ExpectChecksumEq(payload_checksum_ref, checksum_string); // Verify number of packets produced. diff --git a/modules/audio_coding/neteq/test/result_sink.cc b/modules/audio_coding/neteq/test/result_sink.cc index b70016180e..0822e00ebe 100644 --- a/modules/audio_coding/neteq/test/result_sink.cc +++ b/modules/audio_coding/neteq/test/result_sink.cc @@ -10,8 +10,9 @@ #include "modules/audio_coding/neteq/test/result_sink.h" -#include +#include +#include "absl/strings/string_view.h" #include "rtc_base/ignore_wundef.h" #include "rtc_base/message_digest.h" #include "rtc_base/string_encode.h" @@ -91,10 +92,10 @@ void ResultSink::AddResult(const NetEqNetworkStatistics& stats_raw) { } void ResultSink::VerifyChecksum(const std::string& checksum) { - std::vector buffer; + std::string buffer; buffer.resize(digest_->Size()); - digest_->Finish(&buffer[0], buffer.size()); - const std::string result = rtc::hex_encode(&buffer[0], digest_->Size()); + digest_->Finish(buffer.data(), buffer.size()); + const std::string result = rtc::hex_encode(buffer); if (checksum.size() == result.size()) { EXPECT_EQ(checksum, result); } else { diff --git a/modules/audio_coding/neteq/tools/audio_checksum.h b/modules/audio_coding/neteq/tools/audio_checksum.h index 9d6f3432c0..42e3a3a3a0 100644 --- a/modules/audio_coding/neteq/tools/audio_checksum.h +++ b/modules/audio_coding/neteq/tools/audio_checksum.h @@ -50,8 +50,7 @@ class AudioChecksum : public AudioSink { finished_ = true; checksum_->Finish(checksum_result_.data(), checksum_result_.size()); } - return rtc::hex_encode(checksum_result_.data(), - checksum_result_.size()); + return rtc::hex_encode(checksum_result_); } private: diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn index 9c2d839296..f5e05c149e 100644 --- a/p2p/BUILD.gn +++ b/p2p/BUILD.gn @@ -284,6 +284,7 @@ rtc_library("p2p_server_utils") { ] deps = [ ":rtc_p2p", + "../api:array_view", "../api:packet_socket_factory", "../api:sequence_checker", "../api/transport:stun_types", diff --git a/p2p/base/turn_server.cc b/p2p/base/turn_server.cc index 863319e916..6a5d7a9a3f 100644 --- a/p2p/base/turn_server.cc +++ b/p2p/base/turn_server.cc @@ -16,6 +16,7 @@ #include "absl/algorithm/container.h" #include "absl/memory/memory.h" +#include "api/array_view.h" #include "api/packet_socket_factory.h" #include "api/transport/stun.h" #include "p2p/base/async_stun_tcp_socket.h" @@ -421,7 +422,7 @@ void TurnServer::HandleAllocateRequest(TurnServerConnection* conn, std::string TurnServer::GenerateNonce(int64_t now) const { // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now)) std::string input(reinterpret_cast(&now), sizeof(now)); - std::string nonce = rtc::hex_encode(input.c_str(), input.size()); + std::string nonce = rtc::hex_encode(input); nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input); RTC_DCHECK(nonce.size() == kNonceSize); @@ -437,8 +438,8 @@ bool TurnServer::ValidateNonce(const std::string& nonce) const { // Decode the timestamp. int64_t then; char* p = reinterpret_cast(&then); - size_t len = - rtc::hex_decode(p, sizeof(then), nonce.substr(0, sizeof(then) * 2)); + size_t len = rtc::hex_decode(rtc::ArrayView(p, sizeof(then)), + nonce.substr(0, sizeof(then) * 2)); if (len != sizeof(then)) { return false; } diff --git a/pc/BUILD.gn b/pc/BUILD.gn index a905819ba3..964c51e835 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -567,7 +567,10 @@ rtc_source_set("srtp_session") { "../rtc_base/synchronization:mutex", "../system_wrappers:metrics", ] - absl_deps = [ "//third_party/abseil-cpp/absl/base:core_headers" ] + absl_deps = [ + "//third_party/abseil-cpp/absl/base:core_headers", + "//third_party/abseil-cpp/absl/strings:strings", + ] if (rtc_build_libsrtp) { deps += [ "//third_party/libsrtp" ] } diff --git a/pc/srtp_session.cc b/pc/srtp_session.cc index 41c9b46e45..d01bc38421 100644 --- a/pc/srtp_session.cc +++ b/pc/srtp_session.cc @@ -17,6 +17,7 @@ #include "absl/base/attributes.h" #include "absl/base/const_init.h" +#include "absl/strings/string_view.h" #include "api/array_view.h" #include "api/field_trials_view.h" #include "modules/rtp_rtcp/source/rtp_util.h" @@ -471,13 +472,16 @@ void SrtpSession::DumpPacket(const void* buf, int len, bool outbound) { int64_t minutes = (time_of_day / (60 * 1000)) % 60; int64_t seconds = (time_of_day / 1000) % 60; int64_t millis = time_of_day % 1000; - RTC_LOG(LS_VERBOSE) << "\n" << (outbound ? "O" : "I") << " " - << std::setfill('0') << std::setw(2) << hours << ":" - << std::setfill('0') << std::setw(2) << minutes << ":" - << std::setfill('0') << std::setw(2) << seconds << "." - << std::setfill('0') << std::setw(3) << millis << " " - << "000000 " << rtc::hex_encode_with_delimiter((const char *)buf, len, ' ') - << " # RTP_DUMP"; + RTC_LOG(LS_VERBOSE) << "\n" + << (outbound ? "O" : "I") << " " << std::setfill('0') + << std::setw(2) << hours << ":" << std::setfill('0') + << std::setw(2) << minutes << ":" << std::setfill('0') + << std::setw(2) << seconds << "." << std::setfill('0') + << std::setw(3) << millis << " " + << "000000 " + << rtc::hex_encode_with_delimiter( + absl::string_view((const char*)buf, len), ' ') + << " # RTP_DUMP"; } } // namespace cricket diff --git a/rtc_base/buffer.h b/rtc_base/buffer.h index c9bf2ccebf..be8e22bf9f 100644 --- a/rtc_base/buffer.h +++ b/rtc_base/buffer.h @@ -19,6 +19,7 @@ #include #include +#include "absl/strings/string_view.h" #include "api/array_view.h" #include "rtc_base/checks.h" #include "rtc_base/type_traits.h" @@ -117,6 +118,13 @@ class BufferT { ~BufferT() { MaybeZeroCompleteBuffer(); } + // Implicit conversion to absl::string_view if T is compatible with char. + template + operator typename std::enable_if::value, + absl::string_view>::type() const { + return absl::string_view(data(), size()); + } + // Get a pointer to the data. Just .data() will give you a (const) T*, but if // T is a byte-sized integer, you may also use .data() for any other // byte-sized integer U. diff --git a/rtc_base/buffer_unittest.cc b/rtc_base/buffer_unittest.cc index 8beae43cf9..b56118afde 100644 --- a/rtc_base/buffer_unittest.cc +++ b/rtc_base/buffer_unittest.cc @@ -13,6 +13,7 @@ #include #include +#include "absl/strings/string_view.h" #include "api/array_view.h" #include "test/gmock.h" #include "test/gtest.h" @@ -73,6 +74,13 @@ TEST(BufferTest, TestConstructArray) { EXPECT_EQ(0, memcmp(buf.data(), kTestData, 16)); } +TEST(BufferTest, TestStringViewConversion) { + Buffer buf(kTestData); + absl::string_view view = buf; + EXPECT_EQ(view, + absl::string_view(reinterpret_cast(kTestData), 16u)); +} + TEST(BufferTest, TestSetData) { Buffer buf(kTestData + 4, 7); buf.SetData(kTestData, 9); diff --git a/rtc_base/message_digest.cc b/rtc_base/message_digest.cc index 3b39cf9f18..56abcd2c7b 100644 --- a/rtc_base/message_digest.cc +++ b/rtc_base/message_digest.cc @@ -74,7 +74,7 @@ std::string ComputeDigest(MessageDigest* digest, absl::string_view input) { std::unique_ptr output(new char[digest->Size()]); ComputeDigest(digest, input.data(), input.size(), output.get(), digest->Size()); - return hex_encode(output.get(), digest->Size()); + return hex_encode(absl::string_view(output.get(), digest->Size())); } bool ComputeDigest(absl::string_view alg, @@ -157,7 +157,7 @@ std::string ComputeHmac(MessageDigest* digest, std::unique_ptr output(new char[digest->Size()]); ComputeHmac(digest, key.data(), key.size(), input.data(), input.size(), output.get(), digest->Size()); - return hex_encode(output.get(), digest->Size()); + return hex_encode(absl::string_view(output.get(), digest->Size())); } bool ComputeHmac(absl::string_view alg, diff --git a/rtc_base/message_digest_unittest.cc b/rtc_base/message_digest_unittest.cc index 85e9bbde53..b296783d4e 100644 --- a/rtc_base/message_digest_unittest.cc +++ b/rtc_base/message_digest_unittest.cc @@ -10,6 +10,7 @@ #include "rtc_base/message_digest.h" +#include "absl/strings/string_view.h" #include "rtc_base/string_encode.h" #include "test/gtest.h" @@ -29,7 +30,7 @@ TEST(MessageDigestTest, TestMd5Digest) { EXPECT_EQ(sizeof(output), ComputeDigest(DIGEST_MD5, "abc", 3, output, sizeof(output))); EXPECT_EQ("900150983cd24fb0d6963f7d28e17f72", - hex_encode(output, sizeof(output))); + hex_encode(absl::string_view(output, sizeof(output)))); EXPECT_EQ(0U, ComputeDigest(DIGEST_MD5, "abc", 3, output, sizeof(output) - 1)); } @@ -51,7 +52,7 @@ TEST(MessageDigestTest, TestSha1Digest) { EXPECT_EQ(sizeof(output), ComputeDigest(DIGEST_SHA_1, "abc", 3, output, sizeof(output))); EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", - hex_encode(output, sizeof(output))); + hex_encode(absl::string_view(output, sizeof(output)))); EXPECT_EQ(0U, ComputeDigest(DIGEST_SHA_1, "abc", 3, output, sizeof(output) - 1)); } @@ -99,7 +100,7 @@ TEST(MessageDigestTest, TestMd5Hmac) { ComputeHmac(DIGEST_MD5, key.c_str(), key.size(), input.c_str(), input.size(), output, sizeof(output))); EXPECT_EQ("9294727a3638bb1c13f48ef8158bfc9d", - hex_encode(output, sizeof(output))); + hex_encode(absl::string_view(output, sizeof(output)))); EXPECT_EQ(0U, ComputeHmac(DIGEST_MD5, key.c_str(), key.size(), input.c_str(), input.size(), output, sizeof(output) - 1)); } @@ -140,7 +141,7 @@ TEST(MessageDigestTest, TestSha1Hmac) { ComputeHmac(DIGEST_SHA_1, key.c_str(), key.size(), input.c_str(), input.size(), output, sizeof(output))); EXPECT_EQ("b617318655057264e28bc0b6fb378c8ef146be00", - hex_encode(output, sizeof(output))); + hex_encode(absl::string_view(output, sizeof(output)))); EXPECT_EQ(0U, ComputeHmac(DIGEST_SHA_1, key.c_str(), key.size(), input.c_str(), input.size(), output, sizeof(output) - 1)); diff --git a/rtc_base/ssl_fingerprint.cc b/rtc_base/ssl_fingerprint.cc index a85b7a09ce..a43bb159c3 100644 --- a/rtc_base/ssl_fingerprint.cc +++ b/rtc_base/ssl_fingerprint.cc @@ -18,6 +18,7 @@ #include "absl/algorithm/container.h" #include "absl/strings/string_view.h" +#include "api/array_view.h" #include "rtc_base/logging.h" #include "rtc_base/message_digest.h" #include "rtc_base/rtc_certificate.h" @@ -68,8 +69,8 @@ std::unique_ptr SSLFingerprint::CreateUniqueFromRfc4572( return nullptr; char value[rtc::MessageDigest::kMaxSize]; - size_t value_len = rtc::hex_decode_with_delimiter( - value, sizeof(value), fingerprint.data(), fingerprint.length(), ':'); + size_t value_len = + rtc::hex_decode_with_delimiter(ArrayView(value), fingerprint, ':'); if (!value_len) return nullptr; @@ -110,8 +111,8 @@ bool SSLFingerprint::operator==(const SSLFingerprint& other) const { } std::string SSLFingerprint::GetRfc4572Fingerprint() const { - std::string fingerprint = - rtc::hex_encode_with_delimiter(digest.data(), digest.size(), ':'); + std::string fingerprint = rtc::hex_encode_with_delimiter( + absl::string_view(digest.data(), digest.size()), ':'); absl::c_transform(fingerprint, fingerprint.begin(), ::toupper); return fingerprint; } diff --git a/rtc_base/string_encode.cc b/rtc_base/string_encode.cc index fa99c7a439..136b853170 100644 --- a/rtc_base/string_encode.cc +++ b/rtc_base/string_encode.cc @@ -13,6 +13,7 @@ #include #include "absl/strings/string_view.h" +#include "api/array_view.h" #include "rtc_base/arraysize.h" #include "rtc_base/checks.h" @@ -52,16 +53,16 @@ size_t hex_encode_output_length(size_t srclen, char delimiter) { // hex_encode shows the hex representation of binary data in ascii, with // `delimiter` between bytes, or none if `delimiter` == 0. void hex_encode_with_delimiter(char* buffer, - const char* csource, - size_t srclen, + absl::string_view source, char delimiter) { RTC_DCHECK(buffer); // Init and check bounds. const unsigned char* bsource = - reinterpret_cast(csource); + reinterpret_cast(source.data()); size_t srcpos = 0, bufpos = 0; + size_t srclen = source.length(); while (srcpos < srclen) { unsigned char ch = bsource[srcpos++]; buffer[bufpos] = hex_encode((ch >> 4) & 0xF); @@ -79,42 +80,29 @@ void hex_encode_with_delimiter(char* buffer, } // namespace std::string hex_encode(absl::string_view str) { - return hex_encode(str.data(), str.size()); + return hex_encode_with_delimiter(str, 0); } -std::string hex_encode(const char* source, size_t srclen) { - return hex_encode_with_delimiter(source, srclen, 0); -} - -std::string hex_encode_with_delimiter(const char* source, - size_t srclen, +std::string hex_encode_with_delimiter(absl::string_view source, char delimiter) { - std::string s(hex_encode_output_length(srclen, delimiter), 0); - hex_encode_with_delimiter(&s[0], source, srclen, delimiter); + std::string s(hex_encode_output_length(source.length(), delimiter), 0); + hex_encode_with_delimiter(&s[0], source, delimiter); return s; } -size_t hex_decode(char* cbuffer, - size_t buflen, - const char* source, - size_t srclen) { - return hex_decode_with_delimiter(cbuffer, buflen, source, srclen, 0); -} - -size_t hex_decode_with_delimiter(char* cbuffer, - size_t buflen, - const char* source, - size_t srclen, +size_t hex_decode_with_delimiter(ArrayView cbuffer, + absl::string_view source, char delimiter) { - RTC_DCHECK(cbuffer); // TODO(kwiberg): estimate output size - if (buflen == 0) + if (cbuffer.empty()) return 0; // Init and bounds check. - unsigned char* bbuffer = reinterpret_cast(cbuffer); + unsigned char* bbuffer = reinterpret_cast(cbuffer.data()); size_t srcpos = 0, bufpos = 0; + size_t srclen = source.length(); + size_t needed = (delimiter) ? (srclen + 1) / 3 : srclen / 2; - if (buflen < needed) + if (cbuffer.size() < needed) return 0; while (srcpos < srclen) { @@ -142,15 +130,16 @@ size_t hex_decode_with_delimiter(char* cbuffer, return bufpos; } -size_t hex_decode(char* buffer, size_t buflen, absl::string_view source) { - return hex_decode_with_delimiter(buffer, buflen, source, 0); -} size_t hex_decode_with_delimiter(char* buffer, size_t buflen, absl::string_view source, char delimiter) { - return hex_decode_with_delimiter(buffer, buflen, source.data(), - source.length(), delimiter); + return hex_decode_with_delimiter(ArrayView(buffer, buflen), source, + delimiter); +} + +size_t hex_decode(ArrayView buffer, absl::string_view source) { + return hex_decode_with_delimiter(buffer, source, 0); } size_t tokenize(absl::string_view source, @@ -243,11 +232,11 @@ std::string ToString(const bool b) { return b ? "true" : "false"; } -std::string ToString(const char* const s) { +std::string ToString(absl::string_view s) { return std::string(s); } -std::string ToString(absl::string_view s) { +std::string ToString(const char* s) { return std::string(s); } @@ -321,7 +310,7 @@ std::string ToString(const void* const p) { return std::string(&buf[0], len); } -bool FromString(const std::string& s, bool* b) { +bool FromString(absl::string_view s, bool* b) { if (s == "false") { *b = false; return true; diff --git a/rtc_base/string_encode.h b/rtc_base/string_encode.h index 87c5bc8d44..190150599f 100644 --- a/rtc_base/string_encode.h +++ b/rtc_base/string_encode.h @@ -19,6 +19,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" +#include "api/array_view.h" #include "rtc_base/checks.h" #include "rtc_base/string_to_number.h" @@ -29,29 +30,18 @@ namespace rtc { ////////////////////////////////////////////////////////////////////// std::string hex_encode(absl::string_view str); -std::string hex_encode(const char* source, size_t srclen); -std::string hex_encode_with_delimiter(const char* source, - size_t srclen, - char delimiter); +std::string hex_encode_with_delimiter(absl::string_view source, char delimiter); // hex_decode converts ascii hex to binary. -size_t hex_decode(char* buffer, - size_t buflen, - const char* source, - size_t srclen); +size_t hex_decode(ArrayView buffer, absl::string_view source); // hex_decode, assuming that there is a delimiter between every byte // pair. // `delimiter` == 0 means no delimiter // If the buffer is too short or the data is invalid, we return 0. -size_t hex_decode_with_delimiter(char* buffer, - size_t buflen, - const char* source, - size_t srclen, +size_t hex_decode_with_delimiter(ArrayView buffer, + absl::string_view source, char delimiter); - -// Helper functions for hex_decode. -size_t hex_decode(char* buffer, size_t buflen, absl::string_view source); size_t hex_decode_with_delimiter(char* buffer, size_t buflen, absl::string_view source, @@ -88,8 +78,10 @@ bool tokenize_first(absl::string_view source, // TODO(jonasolsson): Remove these when absl::StrCat becomes available. std::string ToString(bool b); -std::string ToString(const char* s); std::string ToString(absl::string_view s); +// The const char* overload is needed for correct overload resolution because of +// the const void* version of ToString() below. +std::string ToString(const char* s); std::string ToString(short s); std::string ToString(unsigned short s); @@ -109,7 +101,7 @@ template ::value && !std::is_same::value, int>::type = 0> -static bool FromString(const std::string& s, T* t) { +static bool FromString(absl::string_view s, T* t) { RTC_DCHECK(t); absl::optional result = StringToNumber(s); @@ -119,10 +111,10 @@ static bool FromString(const std::string& s, T* t) { return result.has_value(); } -bool FromString(const std::string& s, bool* b); +bool FromString(absl::string_view s, bool* b); template -static inline T FromString(const std::string& str) { +static inline T FromString(absl::string_view str) { T val; FromString(str, &val); return val; diff --git a/rtc_base/string_encode_unittest.cc b/rtc_base/string_encode_unittest.cc index 3dd79c954f..4afed3f00f 100644 --- a/rtc_base/string_encode_unittest.cc +++ b/rtc_base/string_encode_unittest.cc @@ -14,6 +14,7 @@ #include // no-presubmit-check TODO(webrtc:8982) +#include "api/array_view.h" #include "test/gtest.h" namespace rtc { @@ -28,109 +29,106 @@ class HexEncodeTest : public ::testing::Test { } char data_[10]; + absl::string_view data_view_{data_, sizeof(data_)}; char decoded_[11]; size_t dec_res_; }; // Test that we can convert to/from hex with no delimiter. TEST_F(HexEncodeTest, TestWithNoDelimiter) { - std::string encoded = hex_encode(data_, sizeof(data_)); + std::string encoded = hex_encode(data_view_); EXPECT_EQ("80818283848586878889", encoded); - dec_res_ = - hex_decode(decoded_, sizeof(decoded_), encoded.data(), encoded.size()); + dec_res_ = hex_decode(ArrayView(decoded_), encoded); ASSERT_EQ(sizeof(data_), dec_res_); ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); } // Test that we can convert to/from hex with a colon delimiter. TEST_F(HexEncodeTest, TestWithDelimiter) { - std::string encoded = hex_encode_with_delimiter(data_, sizeof(data_), ':'); + std::string encoded = hex_encode_with_delimiter(data_view_, ':'); EXPECT_EQ("80:81:82:83:84:85:86:87:88:89", encoded); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded.data(), encoded.size(), ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_), encoded, ':'); ASSERT_EQ(sizeof(data_), dec_res_); ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_)); } // Test that encoding with one delimiter and decoding with another fails. TEST_F(HexEncodeTest, TestWithWrongDelimiter) { - std::string encoded = hex_encode_with_delimiter(data_, sizeof(data_), ':'); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded.data(), encoded.size(), '/'); + std::string encoded = hex_encode_with_delimiter(data_view_, ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_), encoded, '/'); ASSERT_EQ(0U, dec_res_); } // Test that encoding without a delimiter and decoding with one fails. TEST_F(HexEncodeTest, TestExpectedDelimiter) { - std::string encoded = hex_encode(data_, sizeof(data_)); + std::string encoded = hex_encode(data_view_); EXPECT_EQ(sizeof(data_) * 2, encoded.size()); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded.data(), encoded.size(), ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_), encoded, ':'); ASSERT_EQ(0U, dec_res_); } // Test that encoding with a delimiter and decoding without one fails. TEST_F(HexEncodeTest, TestExpectedNoDelimiter) { - std::string encoded = hex_encode_with_delimiter(data_, sizeof(data_), ':'); + std::string encoded = hex_encode_with_delimiter(data_view_, ':'); EXPECT_EQ(sizeof(data_) * 3 - 1, encoded.size()); - dec_res_ = - hex_decode(decoded_, sizeof(decoded_), encoded.data(), encoded.size()); + dec_res_ = hex_decode(ArrayView(decoded_), encoded); ASSERT_EQ(0U, dec_res_); } // Test that we handle a zero-length buffer with no delimiter. TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) { - std::string encoded = hex_encode("", 0); + std::string encoded = hex_encode(""); EXPECT_TRUE(encoded.empty()); - dec_res_ = - hex_decode(decoded_, sizeof(decoded_), encoded.data(), encoded.size()); + dec_res_ = hex_decode(ArrayView(decoded_), encoded); ASSERT_EQ(0U, dec_res_); } // Test that we handle a zero-length buffer with a delimiter. TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) { - std::string encoded = hex_encode_with_delimiter("", 0, ':'); + std::string encoded = hex_encode_with_delimiter("", ':'); EXPECT_TRUE(encoded.empty()); - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), - encoded.data(), encoded.size(), ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_), encoded, ':'); ASSERT_EQ(0U, dec_res_); } // Test that decoding into a too-small output buffer fails. TEST_F(HexEncodeTest, TestDecodeTooShort) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0); + dec_res_ = + hex_decode_with_delimiter(ArrayView(decoded_, 4), "0123456789", 0); ASSERT_EQ(0U, dec_res_); ASSERT_EQ(0x7f, decoded_[4]); } // Test that decoding non-hex data fails. TEST_F(HexEncodeTest, TestDecodeBogusData) { - dec_res_ = - hex_decode_with_delimiter(decoded_, sizeof(decoded_), "axyz", 4, 0); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_), "axyz", 0); ASSERT_EQ(0U, dec_res_); } // Test that decoding an odd number of hex characters fails. TEST_F(HexEncodeTest, TestDecodeOddHexDigits) { - dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_), "012", 0); ASSERT_EQ(0U, dec_res_); } // Test that decoding a string with too many delimiters fails. TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_, 4), + "01::23::45::67", ':'); ASSERT_EQ(0U, dec_res_); } // Test that decoding a string with a leading delimiter fails. TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_, 4), + ":01:23:45:67", ':'); ASSERT_EQ(0U, dec_res_); } // Test that decoding a string with a trailing delimiter fails. TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) { - dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':'); + dec_res_ = hex_decode_with_delimiter(ArrayView(decoded_, 4), + "01:23:45:67:", ':'); ASSERT_EQ(0U, dec_res_); }