blob: f277d3a856f3b07a8c6f9437ec8fac8763e5ba76 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:261/*
2 * Copyright 2004 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
Steve Anton10542f22019-01-11 17:11:0011#include "rtc_base/string_encode.h"
henrike@webrtc.orgf0488722014-05-13 18:00:2612
Yves Gerey3e707812018-11-28 15:47:4913#include <string.h>
Jonas Olssona4d87372019-07-05 17:08:3314
Jonas Olsson6b1985d2018-07-05 09:59:4815#include <sstream> // no-presubmit-check TODO(webrtc:8982)
16
Ali Tofighfd6a4d62022-03-31 08:36:4817#include "api/array_view.h"
Yves Gerey3e707812018-11-28 15:47:4918#include "test/gtest.h"
19
henrike@webrtc.orgf0488722014-05-13 18:00:2620namespace rtc {
21
Mirko Bonadei6a489f22019-04-09 13:11:1222class HexEncodeTest : public ::testing::Test {
henrike@webrtc.orgf0488722014-05-13 18:00:2623 public:
Niels Möllere7e36012019-05-23 10:10:2624 HexEncodeTest() : dec_res_(0) {
henrike@webrtc.orgf0488722014-05-13 18:00:2625 for (size_t i = 0; i < sizeof(data_); ++i) {
26 data_[i] = (i + 128) & 0xff;
27 }
28 memset(decoded_, 0x7f, sizeof(decoded_));
29 }
30
31 char data_[10];
Ali Tofighfd6a4d62022-03-31 08:36:4832 absl::string_view data_view_{data_, sizeof(data_)};
henrike@webrtc.orgf0488722014-05-13 18:00:2633 char decoded_[11];
henrike@webrtc.orgf0488722014-05-13 18:00:2634 size_t dec_res_;
35};
36
37// Test that we can convert to/from hex with no delimiter.
38TEST_F(HexEncodeTest, TestWithNoDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4839 std::string encoded = hex_encode(data_view_);
Niels Möllere7e36012019-05-23 10:10:2640 EXPECT_EQ("80818283848586878889", encoded);
Ali Tofighfd6a4d62022-03-31 08:36:4841 dec_res_ = hex_decode(ArrayView<char>(decoded_), encoded);
henrike@webrtc.orgf0488722014-05-13 18:00:2642 ASSERT_EQ(sizeof(data_), dec_res_);
43 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
44}
45
46// Test that we can convert to/from hex with a colon delimiter.
47TEST_F(HexEncodeTest, TestWithDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4848 std::string encoded = hex_encode_with_delimiter(data_view_, ':');
Niels Möllere7e36012019-05-23 10:10:2649 EXPECT_EQ("80:81:82:83:84:85:86:87:88:89", encoded);
Ali Tofighfd6a4d62022-03-31 08:36:4850 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_), encoded, ':');
henrike@webrtc.orgf0488722014-05-13 18:00:2651 ASSERT_EQ(sizeof(data_), dec_res_);
52 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
53}
54
55// Test that encoding with one delimiter and decoding with another fails.
56TEST_F(HexEncodeTest, TestWithWrongDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4857 std::string encoded = hex_encode_with_delimiter(data_view_, ':');
58 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_), encoded, '/');
henrike@webrtc.orgf0488722014-05-13 18:00:2659 ASSERT_EQ(0U, dec_res_);
60}
61
62// Test that encoding without a delimiter and decoding with one fails.
63TEST_F(HexEncodeTest, TestExpectedDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4864 std::string encoded = hex_encode(data_view_);
Niels Möllere7e36012019-05-23 10:10:2665 EXPECT_EQ(sizeof(data_) * 2, encoded.size());
Ali Tofighfd6a4d62022-03-31 08:36:4866 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_), encoded, ':');
henrike@webrtc.orgf0488722014-05-13 18:00:2667 ASSERT_EQ(0U, dec_res_);
68}
69
70// Test that encoding with a delimiter and decoding without one fails.
71TEST_F(HexEncodeTest, TestExpectedNoDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4872 std::string encoded = hex_encode_with_delimiter(data_view_, ':');
Niels Möllere7e36012019-05-23 10:10:2673 EXPECT_EQ(sizeof(data_) * 3 - 1, encoded.size());
Ali Tofighfd6a4d62022-03-31 08:36:4874 dec_res_ = hex_decode(ArrayView<char>(decoded_), encoded);
henrike@webrtc.orgf0488722014-05-13 18:00:2675 ASSERT_EQ(0U, dec_res_);
76}
77
78// Test that we handle a zero-length buffer with no delimiter.
79TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4880 std::string encoded = hex_encode("");
Niels Möllere7e36012019-05-23 10:10:2681 EXPECT_TRUE(encoded.empty());
Ali Tofighfd6a4d62022-03-31 08:36:4882 dec_res_ = hex_decode(ArrayView<char>(decoded_), encoded);
henrike@webrtc.orgf0488722014-05-13 18:00:2683 ASSERT_EQ(0U, dec_res_);
84}
85
86// Test that we handle a zero-length buffer with a delimiter.
87TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:4888 std::string encoded = hex_encode_with_delimiter("", ':');
Niels Möllere7e36012019-05-23 10:10:2689 EXPECT_TRUE(encoded.empty());
Ali Tofighfd6a4d62022-03-31 08:36:4890 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_), encoded, ':');
henrike@webrtc.orgf0488722014-05-13 18:00:2691 ASSERT_EQ(0U, dec_res_);
92}
93
henrike@webrtc.orgf0488722014-05-13 18:00:2694// Test that decoding into a too-small output buffer fails.
95TEST_F(HexEncodeTest, TestDecodeTooShort) {
Ali Tofighfd6a4d62022-03-31 08:36:4896 dec_res_ =
97 hex_decode_with_delimiter(ArrayView<char>(decoded_, 4), "0123456789", 0);
henrike@webrtc.orgf0488722014-05-13 18:00:2698 ASSERT_EQ(0U, dec_res_);
99 ASSERT_EQ(0x7f, decoded_[4]);
100}
101
102// Test that decoding non-hex data fails.
103TEST_F(HexEncodeTest, TestDecodeBogusData) {
Ali Tofighfd6a4d62022-03-31 08:36:48104 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_), "axyz", 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26105 ASSERT_EQ(0U, dec_res_);
106}
107
108// Test that decoding an odd number of hex characters fails.
109TEST_F(HexEncodeTest, TestDecodeOddHexDigits) {
Ali Tofighfd6a4d62022-03-31 08:36:48110 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_), "012", 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26111 ASSERT_EQ(0U, dec_res_);
112}
113
114// Test that decoding a string with too many delimiters fails.
115TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) {
Ali Tofighfd6a4d62022-03-31 08:36:48116 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_, 4),
117 "01::23::45::67", ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26118 ASSERT_EQ(0U, dec_res_);
119}
120
121// Test that decoding a string with a leading delimiter fails.
122TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:48123 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_, 4),
124 ":01:23:45:67", ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26125 ASSERT_EQ(0U, dec_res_);
126}
127
128// Test that decoding a string with a trailing delimiter fails.
129TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) {
Ali Tofighfd6a4d62022-03-31 08:36:48130 dec_res_ = hex_decode_with_delimiter(ArrayView<char>(decoded_, 4),
131 "01:23:45:67:", ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26132 ASSERT_EQ(0U, dec_res_);
133}
134
135// Tests counting substrings.
136TEST(TokenizeTest, CountSubstrings) {
137 std::vector<std::string> fields;
138
139 EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields));
140 fields.clear();
141 EXPECT_EQ(1ul, tokenize("one", ' ', &fields));
142
143 // Extra spaces should be ignored.
144 fields.clear();
145 EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields));
146 fields.clear();
147 EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields));
148 fields.clear();
149 EXPECT_EQ(0ul, tokenize(" ", ' ', &fields));
150}
151
152// Tests comparing substrings.
153TEST(TokenizeTest, CompareSubstrings) {
154 std::vector<std::string> fields;
155
156 tokenize("find middle one", ' ', &fields);
157 ASSERT_EQ(3ul, fields.size());
158 ASSERT_STREQ("middle", fields.at(1).c_str());
159 fields.clear();
160
161 // Extra spaces should be ignored.
162 tokenize(" find middle one ", ' ', &fields);
163 ASSERT_EQ(3ul, fields.size());
164 ASSERT_STREQ("middle", fields.at(1).c_str());
165 fields.clear();
166 tokenize(" ", ' ', &fields);
167 ASSERT_EQ(0ul, fields.size());
168}
169
Donald Curtis0e07f922015-05-15 16:21:23170TEST(TokenizeFirstTest, NoLeadingSpaces) {
171 std::string token;
172 std::string rest;
173
174 ASSERT_TRUE(tokenize_first("A &*${}", ' ', &token, &rest));
175 ASSERT_STREQ("A", token.c_str());
176 ASSERT_STREQ("&*${}", rest.c_str());
177
178 ASSERT_TRUE(tokenize_first("A B& *${}", ' ', &token, &rest));
179 ASSERT_STREQ("A", token.c_str());
180 ASSERT_STREQ("B& *${}", rest.c_str());
181
182 ASSERT_TRUE(tokenize_first("A B& *${} ", ' ', &token, &rest));
183 ASSERT_STREQ("A", token.c_str());
184 ASSERT_STREQ("B& *${} ", rest.c_str());
185}
186
187TEST(TokenizeFirstTest, LeadingSpaces) {
188 std::string token;
189 std::string rest;
190
191 ASSERT_TRUE(tokenize_first(" A B C", ' ', &token, &rest));
192 ASSERT_STREQ("", token.c_str());
193 ASSERT_STREQ("A B C", rest.c_str());
194
195 ASSERT_TRUE(tokenize_first(" A B C ", ' ', &token, &rest));
196 ASSERT_STREQ("", token.c_str());
197 ASSERT_STREQ("A B C ", rest.c_str());
198}
199
200TEST(TokenizeFirstTest, SingleToken) {
201 std::string token;
202 std::string rest;
203
204 // In the case where we cannot find delimiter the whole string is a token.
205 ASSERT_FALSE(tokenize_first("ABC", ' ', &token, &rest));
206
207 ASSERT_TRUE(tokenize_first("ABC ", ' ', &token, &rest));
208 ASSERT_STREQ("ABC", token.c_str());
209 ASSERT_STREQ("", rest.c_str());
210
211 ASSERT_TRUE(tokenize_first(" ABC ", ' ', &token, &rest));
212 ASSERT_STREQ("", token.c_str());
213 ASSERT_STREQ("ABC ", rest.c_str());
214}
215
henrike@webrtc.orgf0488722014-05-13 18:00:26216// Tests counting substrings.
217TEST(SplitTest, CountSubstrings) {
Niels Möllerf1d822b2022-06-07 11:58:27218 EXPECT_EQ(5ul, split("one,two,three,four,five", ',').size());
219 EXPECT_EQ(1ul, split("one", ',').size());
henrike@webrtc.orgf0488722014-05-13 18:00:26220
221 // Empty fields between commas count.
Niels Möllerf1d822b2022-06-07 11:58:27222 EXPECT_EQ(5ul, split("one,,three,four,five", ',').size());
223 EXPECT_EQ(3ul, split(",three,", ',').size());
224 EXPECT_EQ(1ul, split("", ',').size());
henrike@webrtc.orgf0488722014-05-13 18:00:26225}
226
227// Tests comparing substrings.
228TEST(SplitTest, CompareSubstrings) {
Niels Möllerf1d822b2022-06-07 11:58:27229 std::vector<absl::string_view> fields = split("find,middle,one", ',');
henrike@webrtc.orgf0488722014-05-13 18:00:26230 ASSERT_EQ(3ul, fields.size());
Niels Möllerf1d822b2022-06-07 11:58:27231 ASSERT_EQ("middle", fields.at(1));
henrike@webrtc.orgf0488722014-05-13 18:00:26232
233 // Empty fields between commas count.
Niels Möllerf1d822b2022-06-07 11:58:27234 fields = split("find,,middle,one", ',');
henrike@webrtc.orgf0488722014-05-13 18:00:26235 ASSERT_EQ(4ul, fields.size());
Niels Möllerf1d822b2022-06-07 11:58:27236 ASSERT_EQ("middle", fields.at(2));
237 fields = split("", ',');
henrike@webrtc.orgf0488722014-05-13 18:00:26238 ASSERT_EQ(1ul, fields.size());
Niels Möllerf1d822b2022-06-07 11:58:27239 ASSERT_EQ("", fields.at(0));
henrike@webrtc.orgf0488722014-05-13 18:00:26240}
241
Niels Möller634f2792021-09-07 14:06:57242TEST(SplitTest, EmptyTokens) {
Niels Möllerf1d822b2022-06-07 11:58:27243 std::vector<absl::string_view> fields = split("a.b.c", '.');
244 ASSERT_EQ(3ul, fields.size());
Niels Möller634f2792021-09-07 14:06:57245 EXPECT_EQ("a", fields[0]);
246 EXPECT_EQ("b", fields[1]);
247 EXPECT_EQ("c", fields[2]);
248
Niels Möllerf1d822b2022-06-07 11:58:27249 fields = split("..c", '.');
250 ASSERT_EQ(3ul, fields.size());
Niels Möller634f2792021-09-07 14:06:57251 EXPECT_TRUE(fields[0].empty());
252 EXPECT_TRUE(fields[1].empty());
253 EXPECT_EQ("c", fields[2]);
254
Niels Möllerf1d822b2022-06-07 11:58:27255 fields = split("", '.');
256 ASSERT_EQ(1ul, fields.size());
Niels Möller634f2792021-09-07 14:06:57257 EXPECT_TRUE(fields[0].empty());
258}
259
Jonas Olsson6b1985d2018-07-05 09:59:48260TEST(ToString, SanityCheck) {
261 EXPECT_EQ(ToString(true), "true");
262 EXPECT_EQ(ToString(false), "false");
henrike@webrtc.orgf0488722014-05-13 18:00:26263
Jonas Olsson6b1985d2018-07-05 09:59:48264 const char* c = "message";
265 EXPECT_EQ(ToString(c), c);
266 EXPECT_EQ(ToString(std::string(c)), c);
henrike@webrtc.orgf0488722014-05-13 18:00:26267
Jonas Olsson6b1985d2018-07-05 09:59:48268 EXPECT_EQ(ToString(short{-123}), "-123");
269 EXPECT_EQ(ToString((unsigned short)123), "123");
270 EXPECT_EQ(ToString(int{-123}), "-123");
271 EXPECT_EQ(ToString((unsigned int)123), "123");
272 EXPECT_EQ(ToString((long int)-123), "-123");
273 EXPECT_EQ(ToString((unsigned long int)123), "123");
274 EXPECT_EQ(ToString((long long int)-123), "-123");
275 EXPECT_EQ(ToString((unsigned long long int)123), "123");
276
277 int i = 10;
278 int* p = &i;
279 std::ostringstream s; // no-presubmit-check TODO(webrtc:8982)
280 s << p;
281 EXPECT_EQ(s.str(), ToString(p));
282
283 EXPECT_EQ(ToString(0.5), "0.5");
henrike@webrtc.orgf0488722014-05-13 18:00:26284}
285
Jonas Olsson6b1985d2018-07-05 09:59:48286template <typename T>
287void ParsesTo(std::string s, T t) {
288 T value;
289 EXPECT_TRUE(FromString(s, &value));
290 EXPECT_EQ(value, t);
henrike@webrtc.orgf0488722014-05-13 18:00:26291}
292
Jonas Olsson6b1985d2018-07-05 09:59:48293TEST(FromString, DecodeValid) {
294 ParsesTo("true", true);
295 ParsesTo("false", false);
296
297 ParsesTo("105", 105);
298 ParsesTo("0.25", 0.25);
299}
300
301template <typename T>
302void FailsToParse(std::string s) {
303 T value;
304 EXPECT_FALSE(FromString(s, &value)) << "[" << s << "]";
305}
306
307TEST(FromString, DecodeInvalid) {
308 FailsToParse<bool>("True");
309 FailsToParse<bool>("0");
310 FailsToParse<bool>("yes");
311
312 FailsToParse<int>("0.5");
313 FailsToParse<int>("XIV");
314 FailsToParse<double>("");
315 FailsToParse<double>(" ");
316 FailsToParse<int>("1 2");
317}
318
319template <typename T>
320void RoundTrip(T t) {
321 std::string s = ToString(t);
322 T value;
323 EXPECT_TRUE(FromString(s, &value));
324 EXPECT_EQ(value, t);
325}
326
327TEST(FromString, RoundTrip) {
328 RoundTrip<int>(123);
329 RoundTrip(false);
330 RoundTrip(true);
331 RoundTrip(0.5);
332 RoundTrip(-15l);
henrike@webrtc.orgf0488722014-05-13 18:00:26333}
deadbeef0a6c4ca2015-10-06 18:38:28334
henrike@webrtc.orgf0488722014-05-13 18:00:26335} // namespace rtc