blob: 3dd79c954f04ceb33684c3fe6255b1a2c1d1f46e [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
Donald Curtis0e07f922015-05-15 16:21:23172TEST(TokenizeFirstTest, NoLeadingSpaces) {
173 std::string token;
174 std::string rest;
175
176 ASSERT_TRUE(tokenize_first("A &*${}", ' ', &token, &rest));
177 ASSERT_STREQ("A", token.c_str());
178 ASSERT_STREQ("&*${}", rest.c_str());
179
180 ASSERT_TRUE(tokenize_first("A B& *${}", ' ', &token, &rest));
181 ASSERT_STREQ("A", token.c_str());
182 ASSERT_STREQ("B& *${}", rest.c_str());
183
184 ASSERT_TRUE(tokenize_first("A B& *${} ", ' ', &token, &rest));
185 ASSERT_STREQ("A", token.c_str());
186 ASSERT_STREQ("B& *${} ", rest.c_str());
187}
188
189TEST(TokenizeFirstTest, LeadingSpaces) {
190 std::string token;
191 std::string rest;
192
193 ASSERT_TRUE(tokenize_first(" A B C", ' ', &token, &rest));
194 ASSERT_STREQ("", token.c_str());
195 ASSERT_STREQ("A B C", rest.c_str());
196
197 ASSERT_TRUE(tokenize_first(" A B C ", ' ', &token, &rest));
198 ASSERT_STREQ("", token.c_str());
199 ASSERT_STREQ("A B C ", rest.c_str());
200}
201
202TEST(TokenizeFirstTest, SingleToken) {
203 std::string token;
204 std::string rest;
205
206 // In the case where we cannot find delimiter the whole string is a token.
207 ASSERT_FALSE(tokenize_first("ABC", ' ', &token, &rest));
208
209 ASSERT_TRUE(tokenize_first("ABC ", ' ', &token, &rest));
210 ASSERT_STREQ("ABC", token.c_str());
211 ASSERT_STREQ("", rest.c_str());
212
213 ASSERT_TRUE(tokenize_first(" ABC ", ' ', &token, &rest));
214 ASSERT_STREQ("", token.c_str());
215 ASSERT_STREQ("ABC ", rest.c_str());
216}
217
henrike@webrtc.orgf0488722014-05-13 18:00:26218// Tests counting substrings.
219TEST(SplitTest, CountSubstrings) {
220 std::vector<std::string> fields;
221
222 EXPECT_EQ(5ul, split("one,two,three,four,five", ',', &fields));
223 fields.clear();
224 EXPECT_EQ(1ul, split("one", ',', &fields));
225
226 // Empty fields between commas count.
227 fields.clear();
228 EXPECT_EQ(5ul, split("one,,three,four,five", ',', &fields));
229 fields.clear();
230 EXPECT_EQ(3ul, split(",three,", ',', &fields));
231 fields.clear();
232 EXPECT_EQ(1ul, split("", ',', &fields));
233}
234
235// Tests comparing substrings.
236TEST(SplitTest, CompareSubstrings) {
237 std::vector<std::string> fields;
238
239 split("find,middle,one", ',', &fields);
240 ASSERT_EQ(3ul, fields.size());
241 ASSERT_STREQ("middle", fields.at(1).c_str());
242 fields.clear();
243
244 // Empty fields between commas count.
245 split("find,,middle,one", ',', &fields);
246 ASSERT_EQ(4ul, fields.size());
247 ASSERT_STREQ("middle", fields.at(2).c_str());
248 fields.clear();
249 split("", ',', &fields);
250 ASSERT_EQ(1ul, fields.size());
251 ASSERT_STREQ("", fields.at(0).c_str());
252}
253
Niels Möller634f2792021-09-07 14:06:57254TEST(SplitTest, EmptyTokens) {
255 std::vector<std::string> fields;
256 EXPECT_EQ(3ul, split("a.b.c", '.', &fields));
257 EXPECT_EQ("a", fields[0]);
258 EXPECT_EQ("b", fields[1]);
259 EXPECT_EQ("c", fields[2]);
260
261 EXPECT_EQ(3ul, split("..c", '.', &fields));
262 EXPECT_TRUE(fields[0].empty());
263 EXPECT_TRUE(fields[1].empty());
264 EXPECT_EQ("c", fields[2]);
265
266 EXPECT_EQ(1ul, split("", '.', &fields));
267 EXPECT_TRUE(fields[0].empty());
268}
269
Jonas Olsson6b1985d2018-07-05 09:59:48270TEST(ToString, SanityCheck) {
271 EXPECT_EQ(ToString(true), "true");
272 EXPECT_EQ(ToString(false), "false");
henrike@webrtc.orgf0488722014-05-13 18:00:26273
Jonas Olsson6b1985d2018-07-05 09:59:48274 const char* c = "message";
275 EXPECT_EQ(ToString(c), c);
276 EXPECT_EQ(ToString(std::string(c)), c);
henrike@webrtc.orgf0488722014-05-13 18:00:26277
Jonas Olsson6b1985d2018-07-05 09:59:48278 EXPECT_EQ(ToString(short{-123}), "-123");
279 EXPECT_EQ(ToString((unsigned short)123), "123");
280 EXPECT_EQ(ToString(int{-123}), "-123");
281 EXPECT_EQ(ToString((unsigned int)123), "123");
282 EXPECT_EQ(ToString((long int)-123), "-123");
283 EXPECT_EQ(ToString((unsigned long int)123), "123");
284 EXPECT_EQ(ToString((long long int)-123), "-123");
285 EXPECT_EQ(ToString((unsigned long long int)123), "123");
286
287 int i = 10;
288 int* p = &i;
289 std::ostringstream s; // no-presubmit-check TODO(webrtc:8982)
290 s << p;
291 EXPECT_EQ(s.str(), ToString(p));
292
293 EXPECT_EQ(ToString(0.5), "0.5");
henrike@webrtc.orgf0488722014-05-13 18:00:26294}
295
Jonas Olsson6b1985d2018-07-05 09:59:48296template <typename T>
297void ParsesTo(std::string s, T t) {
298 T value;
299 EXPECT_TRUE(FromString(s, &value));
300 EXPECT_EQ(value, t);
henrike@webrtc.orgf0488722014-05-13 18:00:26301}
302
Jonas Olsson6b1985d2018-07-05 09:59:48303TEST(FromString, DecodeValid) {
304 ParsesTo("true", true);
305 ParsesTo("false", false);
306
307 ParsesTo("105", 105);
308 ParsesTo("0.25", 0.25);
309}
310
311template <typename T>
312void FailsToParse(std::string s) {
313 T value;
314 EXPECT_FALSE(FromString(s, &value)) << "[" << s << "]";
315}
316
317TEST(FromString, DecodeInvalid) {
318 FailsToParse<bool>("True");
319 FailsToParse<bool>("0");
320 FailsToParse<bool>("yes");
321
322 FailsToParse<int>("0.5");
323 FailsToParse<int>("XIV");
324 FailsToParse<double>("");
325 FailsToParse<double>(" ");
326 FailsToParse<int>("1 2");
327}
328
329template <typename T>
330void RoundTrip(T t) {
331 std::string s = ToString(t);
332 T value;
333 EXPECT_TRUE(FromString(s, &value));
334 EXPECT_EQ(value, t);
335}
336
337TEST(FromString, RoundTrip) {
338 RoundTrip<int>(123);
339 RoundTrip(false);
340 RoundTrip(true);
341 RoundTrip(0.5);
342 RoundTrip(-15l);
henrike@webrtc.orgf0488722014-05-13 18:00:26343}
deadbeef0a6c4ca2015-10-06 18:38:28344
henrike@webrtc.orgf0488722014-05-13 18:00:26345} // namespace rtc