blob: 19d293bc2f7a34720decd44591601c4df417b6cc [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
Yves Gerey3e707812018-11-28 15:47:4917#include "test/gtest.h"
18
henrike@webrtc.orgf0488722014-05-13 18:00:2619namespace rtc {
20
Mirko Bonadei6a489f22019-04-09 13:11:1221class HexEncodeTest : public ::testing::Test {
henrike@webrtc.orgf0488722014-05-13 18:00:2622 public:
Niels Möllere7e36012019-05-23 10:10:2623 HexEncodeTest() : dec_res_(0) {
henrike@webrtc.orgf0488722014-05-13 18:00:2624 for (size_t i = 0; i < sizeof(data_); ++i) {
25 data_[i] = (i + 128) & 0xff;
26 }
27 memset(decoded_, 0x7f, sizeof(decoded_));
28 }
29
30 char data_[10];
henrike@webrtc.orgf0488722014-05-13 18:00:2631 char decoded_[11];
henrike@webrtc.orgf0488722014-05-13 18:00:2632 size_t dec_res_;
33};
34
35// Test that we can convert to/from hex with no delimiter.
36TEST_F(HexEncodeTest, TestWithNoDelimiter) {
Niels Möllere7e36012019-05-23 10:10:2637 std::string encoded = hex_encode(data_, sizeof(data_));
38 EXPECT_EQ("80818283848586878889", encoded);
39 dec_res_ =
40 hex_decode(decoded_, sizeof(decoded_), encoded.data(), encoded.size());
henrike@webrtc.orgf0488722014-05-13 18:00:2641 ASSERT_EQ(sizeof(data_), dec_res_);
42 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
43}
44
45// Test that we can convert to/from hex with a colon delimiter.
46TEST_F(HexEncodeTest, TestWithDelimiter) {
Niels Möllere7e36012019-05-23 10:10:2647 std::string encoded = hex_encode_with_delimiter(data_, sizeof(data_), ':');
48 EXPECT_EQ("80:81:82:83:84:85:86:87:88:89", encoded);
49 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_),
50 encoded.data(), encoded.size(), ':');
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) {
Niels Möllere7e36012019-05-23 10:10:2657 std::string encoded = hex_encode_with_delimiter(data_, sizeof(data_), ':');
58 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_),
59 encoded.data(), encoded.size(), '/');
henrike@webrtc.orgf0488722014-05-13 18:00:2660 ASSERT_EQ(0U, dec_res_);
61}
62
63// Test that encoding without a delimiter and decoding with one fails.
64TEST_F(HexEncodeTest, TestExpectedDelimiter) {
Niels Möllere7e36012019-05-23 10:10:2665 std::string encoded = hex_encode(data_, sizeof(data_));
66 EXPECT_EQ(sizeof(data_) * 2, encoded.size());
67 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_),
68 encoded.data(), encoded.size(), ':');
henrike@webrtc.orgf0488722014-05-13 18:00:2669 ASSERT_EQ(0U, dec_res_);
70}
71
72// Test that encoding with a delimiter and decoding without one fails.
73TEST_F(HexEncodeTest, TestExpectedNoDelimiter) {
Niels Möllere7e36012019-05-23 10:10:2674 std::string encoded = hex_encode_with_delimiter(data_, sizeof(data_), ':');
75 EXPECT_EQ(sizeof(data_) * 3 - 1, encoded.size());
76 dec_res_ =
77 hex_decode(decoded_, sizeof(decoded_), encoded.data(), encoded.size());
henrike@webrtc.orgf0488722014-05-13 18:00:2678 ASSERT_EQ(0U, dec_res_);
79}
80
81// Test that we handle a zero-length buffer with no delimiter.
82TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) {
Niels Möllere7e36012019-05-23 10:10:2683 std::string encoded = hex_encode("", 0);
84 EXPECT_TRUE(encoded.empty());
85 dec_res_ =
86 hex_decode(decoded_, sizeof(decoded_), encoded.data(), encoded.size());
henrike@webrtc.orgf0488722014-05-13 18:00:2687 ASSERT_EQ(0U, dec_res_);
88}
89
90// Test that we handle a zero-length buffer with a delimiter.
91TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) {
Niels Möllere7e36012019-05-23 10:10:2692 std::string encoded = hex_encode_with_delimiter("", 0, ':');
93 EXPECT_TRUE(encoded.empty());
94 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_),
95 encoded.data(), encoded.size(), ':');
henrike@webrtc.orgf0488722014-05-13 18:00:2696 ASSERT_EQ(0U, dec_res_);
97}
98
henrike@webrtc.orgf0488722014-05-13 18:00:2699// Test that decoding into a too-small output buffer fails.
100TEST_F(HexEncodeTest, TestDecodeTooShort) {
101 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0);
102 ASSERT_EQ(0U, dec_res_);
103 ASSERT_EQ(0x7f, decoded_[4]);
104}
105
106// Test that decoding non-hex data fails.
107TEST_F(HexEncodeTest, TestDecodeBogusData) {
Niels Möller12048c72018-10-29 11:58:48108 dec_res_ =
109 hex_decode_with_delimiter(decoded_, sizeof(decoded_), "axyz", 4, 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26110 ASSERT_EQ(0U, dec_res_);
111}
112
113// Test that decoding an odd number of hex characters fails.
114TEST_F(HexEncodeTest, TestDecodeOddHexDigits) {
115 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0);
116 ASSERT_EQ(0U, dec_res_);
117}
118
119// Test that decoding a string with too many delimiters fails.
120TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) {
121 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':');
122 ASSERT_EQ(0U, dec_res_);
123}
124
125// Test that decoding a string with a leading delimiter fails.
126TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) {
127 dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':');
128 ASSERT_EQ(0U, dec_res_);
129}
130
131// Test that decoding a string with a trailing delimiter fails.
132TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) {
133 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':');
134 ASSERT_EQ(0U, dec_res_);
135}
136
137// Tests counting substrings.
138TEST(TokenizeTest, CountSubstrings) {
139 std::vector<std::string> fields;
140
141 EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields));
142 fields.clear();
143 EXPECT_EQ(1ul, tokenize("one", ' ', &fields));
144
145 // Extra spaces should be ignored.
146 fields.clear();
147 EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields));
148 fields.clear();
149 EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields));
150 fields.clear();
151 EXPECT_EQ(0ul, tokenize(" ", ' ', &fields));
152}
153
154// Tests comparing substrings.
155TEST(TokenizeTest, CompareSubstrings) {
156 std::vector<std::string> fields;
157
158 tokenize("find middle one", ' ', &fields);
159 ASSERT_EQ(3ul, fields.size());
160 ASSERT_STREQ("middle", fields.at(1).c_str());
161 fields.clear();
162
163 // Extra spaces should be ignored.
164 tokenize(" find middle one ", ' ', &fields);
165 ASSERT_EQ(3ul, fields.size());
166 ASSERT_STREQ("middle", fields.at(1).c_str());
167 fields.clear();
168 tokenize(" ", ' ', &fields);
169 ASSERT_EQ(0ul, fields.size());
170}
171
172TEST(TokenizeTest, TokenizeAppend) {
deadbeef37f5ecf2017-02-27 22:06:41173 ASSERT_EQ(0ul, tokenize_append("A B C", ' ', nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26174
175 std::vector<std::string> fields;
176
177 tokenize_append("A B C", ' ', &fields);
178 ASSERT_EQ(3ul, fields.size());
179 ASSERT_STREQ("B", fields.at(1).c_str());
180
181 tokenize_append("D E", ' ', &fields);
182 ASSERT_EQ(5ul, fields.size());
183 ASSERT_STREQ("B", fields.at(1).c_str());
184 ASSERT_STREQ("E", fields.at(4).c_str());
185}
186
187TEST(TokenizeTest, TokenizeWithMarks) {
deadbeef37f5ecf2017-02-27 22:06:41188 ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26189
190 std::vector<std::string> fields;
191 tokenize("A B C", ' ', '"', '"', &fields);
192 ASSERT_EQ(3ul, fields.size());
193 ASSERT_STREQ("C", fields.at(2).c_str());
194
195 tokenize("\"A B\" C", ' ', '"', '"', &fields);
196 ASSERT_EQ(2ul, fields.size());
197 ASSERT_STREQ("A B", fields.at(0).c_str());
198
199 tokenize("D \"A B\" C", ' ', '"', '"', &fields);
200 ASSERT_EQ(3ul, fields.size());
201 ASSERT_STREQ("D", fields.at(0).c_str());
202 ASSERT_STREQ("A B", fields.at(1).c_str());
203
204 tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields);
205 ASSERT_EQ(4ul, fields.size());
206 ASSERT_STREQ("D", fields.at(0).c_str());
207 ASSERT_STREQ("A B", fields.at(1).c_str());
208 ASSERT_STREQ("E F", fields.at(3).c_str());
209
210 // No matching marks.
211 tokenize("D \"A B", ' ', '"', '"', &fields);
212 ASSERT_EQ(3ul, fields.size());
213 ASSERT_STREQ("D", fields.at(0).c_str());
214 ASSERT_STREQ("\"A", fields.at(1).c_str());
215
216 tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields);
217 ASSERT_EQ(5ul, fields.size());
218 ASSERT_STREQ("D", fields.at(0).c_str());
219 ASSERT_STREQ("A B", fields.at(1).c_str());
220 ASSERT_STREQ("E F", fields.at(3).c_str());
221}
222
deadbeef0a6c4ca2015-10-06 18:38:28223TEST(TokenizeTest, TokenizeWithEmptyTokens) {
224 std::vector<std::string> fields;
225 EXPECT_EQ(3ul, tokenize_with_empty_tokens("a.b.c", '.', &fields));
226 EXPECT_EQ("a", fields[0]);
227 EXPECT_EQ("b", fields[1]);
228 EXPECT_EQ("c", fields[2]);
229
230 EXPECT_EQ(3ul, tokenize_with_empty_tokens("..c", '.', &fields));
231 EXPECT_TRUE(fields[0].empty());
232 EXPECT_TRUE(fields[1].empty());
233 EXPECT_EQ("c", fields[2]);
234
235 EXPECT_EQ(1ul, tokenize_with_empty_tokens("", '.', &fields));
236 EXPECT_TRUE(fields[0].empty());
237}
238
Donald Curtis0e07f922015-05-15 16:21:23239TEST(TokenizeFirstTest, NoLeadingSpaces) {
240 std::string token;
241 std::string rest;
242
243 ASSERT_TRUE(tokenize_first("A &*${}", ' ', &token, &rest));
244 ASSERT_STREQ("A", token.c_str());
245 ASSERT_STREQ("&*${}", rest.c_str());
246
247 ASSERT_TRUE(tokenize_first("A B& *${}", ' ', &token, &rest));
248 ASSERT_STREQ("A", token.c_str());
249 ASSERT_STREQ("B& *${}", rest.c_str());
250
251 ASSERT_TRUE(tokenize_first("A B& *${} ", ' ', &token, &rest));
252 ASSERT_STREQ("A", token.c_str());
253 ASSERT_STREQ("B& *${} ", rest.c_str());
254}
255
256TEST(TokenizeFirstTest, LeadingSpaces) {
257 std::string token;
258 std::string rest;
259
260 ASSERT_TRUE(tokenize_first(" A B C", ' ', &token, &rest));
261 ASSERT_STREQ("", token.c_str());
262 ASSERT_STREQ("A B C", rest.c_str());
263
264 ASSERT_TRUE(tokenize_first(" A B C ", ' ', &token, &rest));
265 ASSERT_STREQ("", token.c_str());
266 ASSERT_STREQ("A B C ", rest.c_str());
267}
268
269TEST(TokenizeFirstTest, SingleToken) {
270 std::string token;
271 std::string rest;
272
273 // In the case where we cannot find delimiter the whole string is a token.
274 ASSERT_FALSE(tokenize_first("ABC", ' ', &token, &rest));
275
276 ASSERT_TRUE(tokenize_first("ABC ", ' ', &token, &rest));
277 ASSERT_STREQ("ABC", token.c_str());
278 ASSERT_STREQ("", rest.c_str());
279
280 ASSERT_TRUE(tokenize_first(" ABC ", ' ', &token, &rest));
281 ASSERT_STREQ("", token.c_str());
282 ASSERT_STREQ("ABC ", rest.c_str());
283}
284
henrike@webrtc.orgf0488722014-05-13 18:00:26285// Tests counting substrings.
286TEST(SplitTest, CountSubstrings) {
287 std::vector<std::string> fields;
288
289 EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields));
290 fields.clear();
291 EXPECT_EQ(1ul, split("one", ',', &fields));
292
293 // Empty fields between commas count.
294 fields.clear();
295 EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields));
296 fields.clear();
297 EXPECT_EQ(3ul, split(",three,", ',', &fields));
298 fields.clear();
299 EXPECT_EQ(1ul, split("", ',', &fields));
300}
301
302// Tests comparing substrings.
303TEST(SplitTest, CompareSubstrings) {
304 std::vector<std::string> fields;
305
306 split("find,middle,one", ',', &fields);
307 ASSERT_EQ(3ul, fields.size());
308 ASSERT_STREQ("middle", fields.at(1).c_str());
309 fields.clear();
310
311 // Empty fields between commas count.
312 split("find,,middle,one", ',', &fields);
313 ASSERT_EQ(4ul, fields.size());
314 ASSERT_STREQ("middle", fields.at(2).c_str());
315 fields.clear();
316 split("", ',', &fields);
317 ASSERT_EQ(1ul, fields.size());
318 ASSERT_STREQ("", fields.at(0).c_str());
319}
320
Jonas Olsson6b1985d2018-07-05 09:59:48321TEST(ToString, SanityCheck) {
322 EXPECT_EQ(ToString(true), "true");
323 EXPECT_EQ(ToString(false), "false");
henrike@webrtc.orgf0488722014-05-13 18:00:26324
Jonas Olsson6b1985d2018-07-05 09:59:48325 const char* c = "message";
326 EXPECT_EQ(ToString(c), c);
327 EXPECT_EQ(ToString(std::string(c)), c);
henrike@webrtc.orgf0488722014-05-13 18:00:26328
Jonas Olsson6b1985d2018-07-05 09:59:48329 EXPECT_EQ(ToString(short{-123}), "-123");
330 EXPECT_EQ(ToString((unsigned short)123), "123");
331 EXPECT_EQ(ToString(int{-123}), "-123");
332 EXPECT_EQ(ToString((unsigned int)123), "123");
333 EXPECT_EQ(ToString((long int)-123), "-123");
334 EXPECT_EQ(ToString((unsigned long int)123), "123");
335 EXPECT_EQ(ToString((long long int)-123), "-123");
336 EXPECT_EQ(ToString((unsigned long long int)123), "123");
337
338 int i = 10;
339 int* p = &i;
340 std::ostringstream s; // no-presubmit-check TODO(webrtc:8982)
341 s << p;
342 EXPECT_EQ(s.str(), ToString(p));
343
344 EXPECT_EQ(ToString(0.5), "0.5");
henrike@webrtc.orgf0488722014-05-13 18:00:26345}
346
Jonas Olsson6b1985d2018-07-05 09:59:48347template <typename T>
348void ParsesTo(std::string s, T t) {
349 T value;
350 EXPECT_TRUE(FromString(s, &value));
351 EXPECT_EQ(value, t);
henrike@webrtc.orgf0488722014-05-13 18:00:26352}
353
Jonas Olsson6b1985d2018-07-05 09:59:48354TEST(FromString, DecodeValid) {
355 ParsesTo("true", true);
356 ParsesTo("false", false);
357
358 ParsesTo("105", 105);
359 ParsesTo("0.25", 0.25);
360}
361
362template <typename T>
363void FailsToParse(std::string s) {
364 T value;
365 EXPECT_FALSE(FromString(s, &value)) << "[" << s << "]";
366}
367
368TEST(FromString, DecodeInvalid) {
369 FailsToParse<bool>("True");
370 FailsToParse<bool>("0");
371 FailsToParse<bool>("yes");
372
373 FailsToParse<int>("0.5");
374 FailsToParse<int>("XIV");
375 FailsToParse<double>("");
376 FailsToParse<double>(" ");
377 FailsToParse<int>("1 2");
378}
379
380template <typename T>
381void RoundTrip(T t) {
382 std::string s = ToString(t);
383 T value;
384 EXPECT_TRUE(FromString(s, &value));
385 EXPECT_EQ(value, t);
386}
387
388TEST(FromString, RoundTrip) {
389 RoundTrip<int>(123);
390 RoundTrip(false);
391 RoundTrip(true);
392 RoundTrip(0.5);
393 RoundTrip(-15l);
henrike@webrtc.orgf0488722014-05-13 18:00:26394}
deadbeef0a6c4ca2015-10-06 18:38:28395
henrike@webrtc.orgf0488722014-05-13 18:00:26396} // namespace rtc