diff --git a/base/string_tokenizer.h b/base/string_tokenizer.h index eb9ac2d2081..a6b58702045 100644 --- a/base/string_tokenizer.h +++ b/base/string_tokenizer.h @@ -141,6 +141,11 @@ class StringTokenizerT { return true; } + // Start iterating through tokens from the beginning of the string. + void Reset() { + token_end_ = start_pos_; + } + // Returns true if token is a delimiter. When the tokenizer is constructed // with the RETURN_DELIMS option, this method can be used to check if the // returned token is actually a delimiter. @@ -156,6 +161,7 @@ class StringTokenizerT { void Init(const_iterator string_begin, const_iterator string_end, const str& delims) { + start_pos_ = string_begin; token_end_ = string_begin; end_ = string_end; delims_ = delims; @@ -195,6 +201,7 @@ class StringTokenizerT { return true; } + const_iterator start_pos_; const_iterator token_begin_; const_iterator token_end_; const_iterator end_; diff --git a/base/string_tokenizer_unittest.cc b/base/string_tokenizer_unittest.cc index a9e98cd3af9..80cb960d544 100644 --- a/base/string_tokenizer_unittest.cc +++ b/base/string_tokenizer_unittest.cc @@ -30,6 +30,28 @@ TEST(StringTokenizerTest, Simple) { EXPECT_FALSE(t.GetNext()); } +TEST(StringTokenizerTest, Reset) { + string input = "this is a test"; + StringTokenizer t(input, " "); + + for (int i = 0; i < 2; ++i) { + EXPECT_TRUE(t.GetNext()); + EXPECT_EQ(string("this"), t.token()); + + EXPECT_TRUE(t.GetNext()); + EXPECT_EQ(string("is"), t.token()); + + EXPECT_TRUE(t.GetNext()); + EXPECT_EQ(string("a"), t.token()); + + EXPECT_TRUE(t.GetNext()); + EXPECT_EQ(string("test"), t.token()); + + EXPECT_FALSE(t.GetNext()); + t.Reset(); + } +} + TEST(StringTokenizerTest, RetDelims) { string input = "this is a test"; StringTokenizer t(input, " "); diff --git a/net/http/http_util.h b/net/http/http_util.h index fcf762d9ac3..a3b0def9022 100644 --- a/net/http/http_util.h +++ b/net/http/http_util.h @@ -167,6 +167,10 @@ class HttpUtil { // current position will be at the end of the headers. bool AdvanceTo(const char* lowercase_name); + void Reset() { + lines_.Reset(); + } + std::string::const_iterator name_begin() const { return name_begin_; } diff --git a/net/http/http_util_unittest.cc b/net/http/http_util_unittest.cc index 80413ac75cd..bdae329242f 100644 --- a/net/http/http_util_unittest.cc +++ b/net/http/http_util_unittest.cc @@ -105,6 +105,19 @@ TEST(HttpUtilTest, HeadersIterator_AdvanceTo) { EXPECT_FALSE(it.GetNext()); // should be at end of headers } +TEST(HttpUtilTest, HeadersIterator_Reset) { + std::string headers = "foo: 1\r\n: 2\r\n3\r\nbar: 4"; + HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); + // Search past "foo". + EXPECT_TRUE(it.AdvanceTo("bar")); + // Now try advancing to "foo". This time it should fail since the iterator + // position is past it. + EXPECT_FALSE(it.AdvanceTo("foo")); + it.Reset(); + // Now that we reset the iterator position, we should find 'foo' + EXPECT_TRUE(it.AdvanceTo("foo")); +} + TEST(HttpUtilTest, ValuesIterator) { std::string values = " must-revalidate, no-cache=\"foo, bar\"\t, private ";