blob: ffb90b2265f5e50f86d74c94bd29eb9aa370e601 [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_base/stringencode.h"
12#include "rtc_base/arraysize.h"
13#include "rtc_base/gunit.h"
14#include "rtc_base/stringutils.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000015
16namespace rtc {
17
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000018class HexEncodeTest : public testing::Test {
19 public:
20 HexEncodeTest() : enc_res_(0), dec_res_(0) {
21 for (size_t i = 0; i < sizeof(data_); ++i) {
22 data_[i] = (i + 128) & 0xff;
23 }
24 memset(decoded_, 0x7f, sizeof(decoded_));
25 }
26
27 char data_[10];
28 char encoded_[31];
29 char decoded_[11];
30 size_t enc_res_;
31 size_t dec_res_;
32};
33
34// Test that we can convert to/from hex with no delimiter.
35TEST_F(HexEncodeTest, TestWithNoDelimiter) {
36 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_));
37 ASSERT_EQ(sizeof(data_) * 2, enc_res_);
38 ASSERT_STREQ("80818283848586878889", encoded_);
39 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_);
40 ASSERT_EQ(sizeof(data_), dec_res_);
41 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
42}
43
44// Test that we can convert to/from hex with a colon delimiter.
45TEST_F(HexEncodeTest, TestWithDelimiter) {
Yves Gerey665174f2018-06-19 15:03:05 +020046 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), data_,
47 sizeof(data_), ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000048 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_);
49 ASSERT_STREQ("80:81:82:83:84:85:86:87:88:89", encoded_);
Yves Gerey665174f2018-06-19 15:03:05 +020050 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), encoded_,
51 enc_res_, ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000052 ASSERT_EQ(sizeof(data_), dec_res_);
53 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
54}
55
56// Test that encoding with one delimiter and decoding with another fails.
57TEST_F(HexEncodeTest, TestWithWrongDelimiter) {
Yves Gerey665174f2018-06-19 15:03:05 +020058 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), data_,
59 sizeof(data_), ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000060 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_);
Yves Gerey665174f2018-06-19 15:03:05 +020061 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), encoded_,
62 enc_res_, '/');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000063 ASSERT_EQ(0U, dec_res_);
64}
65
66// Test that encoding without a delimiter and decoding with one fails.
67TEST_F(HexEncodeTest, TestExpectedDelimiter) {
68 enc_res_ = hex_encode(encoded_, sizeof(encoded_), data_, sizeof(data_));
69 ASSERT_EQ(sizeof(data_) * 2, enc_res_);
Yves Gerey665174f2018-06-19 15:03:05 +020070 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), encoded_,
71 enc_res_, ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000072 ASSERT_EQ(0U, dec_res_);
73}
74
75// Test that encoding with a delimiter and decoding without one fails.
76TEST_F(HexEncodeTest, TestExpectedNoDelimiter) {
Yves Gerey665174f2018-06-19 15:03:05 +020077 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), data_,
78 sizeof(data_), ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000079 ASSERT_EQ(sizeof(data_) * 3 - 1, enc_res_);
80 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_);
81 ASSERT_EQ(0U, dec_res_);
82}
83
84// Test that we handle a zero-length buffer with no delimiter.
85TEST_F(HexEncodeTest, TestZeroLengthNoDelimiter) {
86 enc_res_ = hex_encode(encoded_, sizeof(encoded_), "", 0);
87 ASSERT_EQ(0U, enc_res_);
88 dec_res_ = hex_decode(decoded_, sizeof(decoded_), encoded_, enc_res_);
89 ASSERT_EQ(0U, dec_res_);
90}
91
92// Test that we handle a zero-length buffer with a delimiter.
93TEST_F(HexEncodeTest, TestZeroLengthWithDelimiter) {
94 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(encoded_), "", 0, ':');
95 ASSERT_EQ(0U, enc_res_);
Yves Gerey665174f2018-06-19 15:03:05 +020096 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), encoded_,
97 enc_res_, ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000098 ASSERT_EQ(0U, dec_res_);
99}
100
101// Test the std::string variants that take no delimiter.
102TEST_F(HexEncodeTest, TestHelpersNoDelimiter) {
103 std::string result = hex_encode(data_, sizeof(data_));
104 ASSERT_EQ("80818283848586878889", result);
105 dec_res_ = hex_decode(decoded_, sizeof(decoded_), result);
106 ASSERT_EQ(sizeof(data_), dec_res_);
107 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
108}
109
110// Test the std::string variants that use a delimiter.
111TEST_F(HexEncodeTest, TestHelpersWithDelimiter) {
112 std::string result = hex_encode_with_delimiter(data_, sizeof(data_), ':');
113 ASSERT_EQ("80:81:82:83:84:85:86:87:88:89", result);
114 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), result, ':');
115 ASSERT_EQ(sizeof(data_), dec_res_);
116 ASSERT_EQ(0, memcmp(data_, decoded_, dec_res_));
117}
118
119// Test that encoding into a too-small output buffer (without delimiter) fails.
120TEST_F(HexEncodeTest, TestEncodeTooShort) {
Yves Gerey665174f2018-06-19 15:03:05 +0200121 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 2, data_,
122 sizeof(data_), 0);
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000123 ASSERT_EQ(0U, enc_res_);
124}
125
126// Test that encoding into a too-small output buffer (with delimiter) fails.
127TEST_F(HexEncodeTest, TestEncodeWithDelimiterTooShort) {
Yves Gerey665174f2018-06-19 15:03:05 +0200128 enc_res_ = hex_encode_with_delimiter(encoded_, sizeof(data_) * 3 - 1, data_,
129 sizeof(data_), ':');
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000130 ASSERT_EQ(0U, enc_res_);
131}
132
133// Test that decoding into a too-small output buffer fails.
134TEST_F(HexEncodeTest, TestDecodeTooShort) {
135 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "0123456789", 10, 0);
136 ASSERT_EQ(0U, dec_res_);
137 ASSERT_EQ(0x7f, decoded_[4]);
138}
139
140// Test that decoding non-hex data fails.
141TEST_F(HexEncodeTest, TestDecodeBogusData) {
142 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "xyz", 3, 0);
143 ASSERT_EQ(0U, dec_res_);
144}
145
146// Test that decoding an odd number of hex characters fails.
147TEST_F(HexEncodeTest, TestDecodeOddHexDigits) {
148 dec_res_ = hex_decode_with_delimiter(decoded_, sizeof(decoded_), "012", 3, 0);
149 ASSERT_EQ(0U, dec_res_);
150}
151
152// Test that decoding a string with too many delimiters fails.
153TEST_F(HexEncodeTest, TestDecodeWithDelimiterTooManyDelimiters) {
154 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01::23::45::67", 14, ':');
155 ASSERT_EQ(0U, dec_res_);
156}
157
158// Test that decoding a string with a leading delimiter fails.
159TEST_F(HexEncodeTest, TestDecodeWithDelimiterLeadingDelimiter) {
160 dec_res_ = hex_decode_with_delimiter(decoded_, 4, ":01:23:45:67", 12, ':');
161 ASSERT_EQ(0U, dec_res_);
162}
163
164// Test that decoding a string with a trailing delimiter fails.
165TEST_F(HexEncodeTest, TestDecodeWithDelimiterTrailingDelimiter) {
166 dec_res_ = hex_decode_with_delimiter(decoded_, 4, "01:23:45:67:", 12, ':');
167 ASSERT_EQ(0U, dec_res_);
168}
169
170// Tests counting substrings.
171TEST(TokenizeTest, CountSubstrings) {
172 std::vector<std::string> fields;
173
174 EXPECT_EQ(5ul, tokenize("one two three four five", ' ', &fields));
175 fields.clear();
176 EXPECT_EQ(1ul, tokenize("one", ' ', &fields));
177
178 // Extra spaces should be ignored.
179 fields.clear();
180 EXPECT_EQ(5ul, tokenize(" one two three four five ", ' ', &fields));
181 fields.clear();
182 EXPECT_EQ(1ul, tokenize(" one ", ' ', &fields));
183 fields.clear();
184 EXPECT_EQ(0ul, tokenize(" ", ' ', &fields));
185}
186
187// Tests comparing substrings.
188TEST(TokenizeTest, CompareSubstrings) {
189 std::vector<std::string> fields;
190
191 tokenize("find middle one", ' ', &fields);
192 ASSERT_EQ(3ul, fields.size());
193 ASSERT_STREQ("middle", fields.at(1).c_str());
194 fields.clear();
195
196 // Extra spaces should be ignored.
197 tokenize(" find middle one ", ' ', &fields);
198 ASSERT_EQ(3ul, fields.size());
199 ASSERT_STREQ("middle", fields.at(1).c_str());
200 fields.clear();
201 tokenize(" ", ' ', &fields);
202 ASSERT_EQ(0ul, fields.size());
203}
204
205TEST(TokenizeTest, TokenizeAppend) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800206 ASSERT_EQ(0ul, tokenize_append("A B C", ' ', nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000207
208 std::vector<std::string> fields;
209
210 tokenize_append("A B C", ' ', &fields);
211 ASSERT_EQ(3ul, fields.size());
212 ASSERT_STREQ("B", fields.at(1).c_str());
213
214 tokenize_append("D E", ' ', &fields);
215 ASSERT_EQ(5ul, fields.size());
216 ASSERT_STREQ("B", fields.at(1).c_str());
217 ASSERT_STREQ("E", fields.at(4).c_str());
218}
219
220TEST(TokenizeTest, TokenizeWithMarks) {
deadbeef37f5ecf2017-02-27 14:06:41 -0800221 ASSERT_EQ(0ul, tokenize("D \"A B", ' ', '(', ')', nullptr));
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000222
223 std::vector<std::string> fields;
224 tokenize("A B C", ' ', '"', '"', &fields);
225 ASSERT_EQ(3ul, fields.size());
226 ASSERT_STREQ("C", fields.at(2).c_str());
227
228 tokenize("\"A B\" C", ' ', '"', '"', &fields);
229 ASSERT_EQ(2ul, fields.size());
230 ASSERT_STREQ("A B", fields.at(0).c_str());
231
232 tokenize("D \"A B\" C", ' ', '"', '"', &fields);
233 ASSERT_EQ(3ul, fields.size());
234 ASSERT_STREQ("D", fields.at(0).c_str());
235 ASSERT_STREQ("A B", fields.at(1).c_str());
236
237 tokenize("D \"A B\" C \"E F\"", ' ', '"', '"', &fields);
238 ASSERT_EQ(4ul, fields.size());
239 ASSERT_STREQ("D", fields.at(0).c_str());
240 ASSERT_STREQ("A B", fields.at(1).c_str());
241 ASSERT_STREQ("E F", fields.at(3).c_str());
242
243 // No matching marks.
244 tokenize("D \"A B", ' ', '"', '"', &fields);
245 ASSERT_EQ(3ul, fields.size());
246 ASSERT_STREQ("D", fields.at(0).c_str());
247 ASSERT_STREQ("\"A", fields.at(1).c_str());
248
249 tokenize("D (A B) C (E F) G", ' ', '(', ')', &fields);
250 ASSERT_EQ(5ul, fields.size());
251 ASSERT_STREQ("D", fields.at(0).c_str());
252 ASSERT_STREQ("A B", fields.at(1).c_str());
253 ASSERT_STREQ("E F", fields.at(3).c_str());
254}
255
deadbeef0a6c4ca2015-10-06 11:38:28 -0700256TEST(TokenizeTest, TokenizeWithEmptyTokens) {
257 std::vector<std::string> fields;
258 EXPECT_EQ(3ul, tokenize_with_empty_tokens("a.b.c", '.', &fields));
259 EXPECT_EQ("a", fields[0]);
260 EXPECT_EQ("b", fields[1]);
261 EXPECT_EQ("c", fields[2]);
262
263 EXPECT_EQ(3ul, tokenize_with_empty_tokens("..c", '.', &fields));
264 EXPECT_TRUE(fields[0].empty());
265 EXPECT_TRUE(fields[1].empty());
266 EXPECT_EQ("c", fields[2]);
267
268 EXPECT_EQ(1ul, tokenize_with_empty_tokens("", '.', &fields));
269 EXPECT_TRUE(fields[0].empty());
270}
271
Donald Curtis0e07f922015-05-15 09:21:23 -0700272TEST(TokenizeFirstTest, NoLeadingSpaces) {
273 std::string token;
274 std::string rest;
275
276 ASSERT_TRUE(tokenize_first("A &*${}", ' ', &token, &rest));
277 ASSERT_STREQ("A", token.c_str());
278 ASSERT_STREQ("&*${}", rest.c_str());
279
280 ASSERT_TRUE(tokenize_first("A B& *${}", ' ', &token, &rest));
281 ASSERT_STREQ("A", token.c_str());
282 ASSERT_STREQ("B& *${}", rest.c_str());
283
284 ASSERT_TRUE(tokenize_first("A B& *${} ", ' ', &token, &rest));
285 ASSERT_STREQ("A", token.c_str());
286 ASSERT_STREQ("B& *${} ", rest.c_str());
287}
288
289TEST(TokenizeFirstTest, LeadingSpaces) {
290 std::string token;
291 std::string rest;
292
293 ASSERT_TRUE(tokenize_first(" A B C", ' ', &token, &rest));
294 ASSERT_STREQ("", token.c_str());
295 ASSERT_STREQ("A B C", rest.c_str());
296
297 ASSERT_TRUE(tokenize_first(" A B C ", ' ', &token, &rest));
298 ASSERT_STREQ("", token.c_str());
299 ASSERT_STREQ("A B C ", rest.c_str());
300}
301
302TEST(TokenizeFirstTest, SingleToken) {
303 std::string token;
304 std::string rest;
305
306 // In the case where we cannot find delimiter the whole string is a token.
307 ASSERT_FALSE(tokenize_first("ABC", ' ', &token, &rest));
308
309 ASSERT_TRUE(tokenize_first("ABC ", ' ', &token, &rest));
310 ASSERT_STREQ("ABC", token.c_str());
311 ASSERT_STREQ("", rest.c_str());
312
313 ASSERT_TRUE(tokenize_first(" ABC ", ' ', &token, &rest));
314 ASSERT_STREQ("", token.c_str());
315 ASSERT_STREQ("ABC ", rest.c_str());
316}
317
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000318// Tests counting substrings.
319TEST(SplitTest, CountSubstrings) {
320 std::vector<std::string> fields;
321
322 EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields));
323 fields.clear();
324 EXPECT_EQ(1ul, split("one", ',', &fields));
325
326 // Empty fields between commas count.
327 fields.clear();
328 EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields));
329 fields.clear();
330 EXPECT_EQ(3ul, split(",three,", ',', &fields));
331 fields.clear();
332 EXPECT_EQ(1ul, split("", ',', &fields));
333}
334
335// Tests comparing substrings.
336TEST(SplitTest, CompareSubstrings) {
337 std::vector<std::string> fields;
338
339 split("find,middle,one", ',', &fields);
340 ASSERT_EQ(3ul, fields.size());
341 ASSERT_STREQ("middle", fields.at(1).c_str());
342 fields.clear();
343
344 // Empty fields between commas count.
345 split("find,,middle,one", ',', &fields);
346 ASSERT_EQ(4ul, fields.size());
347 ASSERT_STREQ("middle", fields.at(2).c_str());
348 fields.clear();
349 split("", ',', &fields);
350 ASSERT_EQ(1ul, fields.size());
351 ASSERT_STREQ("", fields.at(0).c_str());
352}
353
354TEST(BoolTest, DecodeValid) {
355 bool value;
356 EXPECT_TRUE(FromString("true", &value));
357 EXPECT_TRUE(value);
358 EXPECT_TRUE(FromString("true,", &value));
359 EXPECT_TRUE(value);
360 EXPECT_TRUE(FromString("true , true", &value));
361 EXPECT_TRUE(value);
362 EXPECT_TRUE(FromString("true ,\n false", &value));
363 EXPECT_TRUE(value);
364 EXPECT_TRUE(FromString(" true \n", &value));
365 EXPECT_TRUE(value);
366
367 EXPECT_TRUE(FromString("false", &value));
368 EXPECT_FALSE(value);
369 EXPECT_TRUE(FromString(" false ", &value));
370 EXPECT_FALSE(value);
371 EXPECT_TRUE(FromString(" false, ", &value));
372 EXPECT_FALSE(value);
373
374 EXPECT_TRUE(FromString<bool>("true\n"));
375 EXPECT_FALSE(FromString<bool>("false\n"));
376}
377
378TEST(BoolTest, DecodeInvalid) {
379 bool value;
380 EXPECT_FALSE(FromString("True", &value));
381 EXPECT_FALSE(FromString("TRUE", &value));
382 EXPECT_FALSE(FromString("False", &value));
383 EXPECT_FALSE(FromString("FALSE", &value));
384 EXPECT_FALSE(FromString("0", &value));
385 EXPECT_FALSE(FromString("1", &value));
386 EXPECT_FALSE(FromString("0,", &value));
387 EXPECT_FALSE(FromString("1,", &value));
388 EXPECT_FALSE(FromString("1,0", &value));
389 EXPECT_FALSE(FromString("1.", &value));
390 EXPECT_FALSE(FromString("1.0", &value));
391 EXPECT_FALSE(FromString("", &value));
392 EXPECT_FALSE(FromString<bool>("false\nfalse"));
393}
394
395TEST(BoolTest, RoundTrip) {
396 bool value;
397 EXPECT_TRUE(FromString(ToString(true), &value));
398 EXPECT_TRUE(value);
399 EXPECT_TRUE(FromString(ToString(false), &value));
400 EXPECT_FALSE(value);
401}
deadbeef0a6c4ca2015-10-06 11:38:28 -0700402
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000403} // namespace rtc