1//
2// StringTokenizer.cpp
3//
4// Library: Foundation
5// Package: Core
6// Module: StringTokenizer
7//
8// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/StringTokenizer.h"
16#include "Poco/Ascii.h"
17#include <algorithm>
18
19
20namespace Poco {
21
22
23StringTokenizer::StringTokenizer(const std::string& str, const std::string& separators, int options)
24{
25 std::string::const_iterator it = str.begin();
26 std::string::const_iterator itEnd = str.end();
27 std::string token;
28 bool doTrim = ((options & TOK_TRIM) != 0);
29 bool ignoreEmpty = ((options & TOK_IGNORE_EMPTY) != 0);
30 bool lastToken = false;
31
32 for (; it != itEnd; ++it)
33 {
34 if (separators.find(*it) != std::string::npos)
35 {
36 if (doTrim) trim(token);
37 if (!token.empty() || !ignoreEmpty) _tokens.push_back(token);
38 if (!ignoreEmpty) lastToken = true;
39 token.clear();
40 }
41 else
42 {
43 token += *it;
44 lastToken = false;
45 }
46 }
47
48 if (!token.empty())
49 {
50 if (doTrim) trim(token);
51 if (!token.empty() || !ignoreEmpty) _tokens.push_back(token);
52 }
53 else if (lastToken)
54 {
55 _tokens.push_back(std::string());
56 }
57}
58
59
60StringTokenizer::~StringTokenizer()
61{
62}
63
64
65void StringTokenizer::trim(std::string& token)
66{
67 std::string::size_type front = 0;
68 std::string::size_type back = 0;
69 std::string::size_type length = token.length();
70 std::string::const_iterator tIt = token.begin();
71 std::string::const_iterator tEnd = token.end();
72 for (; tIt != tEnd; ++tIt, ++front)
73 {
74 if (!Ascii::isSpace(*tIt)) break;
75 }
76 if (tIt != tEnd)
77 {
78 std::string::const_reverse_iterator tRit = token.rbegin();
79 std::string::const_reverse_iterator tRend = token.rend();
80 for (; tRit != tRend; ++tRit, ++back)
81 {
82 if (!Ascii::isSpace(*tRit)) break;
83 }
84 }
85 token = token.substr(front, length - back - front);
86}
87
88
89std::size_t StringTokenizer::count(const std::string& token) const
90{
91 std::size_t result = 0;
92 TokenVec::const_iterator it = std::find(_tokens.begin(), _tokens.end(), token);
93 while (it != _tokens.end())
94 {
95 result++;
96 it = std::find(++it, _tokens.end(), token);
97 }
98 return result;
99}
100
101
102std::string::size_type StringTokenizer::find(const std::string& token, std::string::size_type pos) const
103{
104 TokenVec::const_iterator it = std::find(_tokens.begin() + pos, _tokens.end(), token);
105 if (it != _tokens.end())
106 {
107 return it - _tokens.begin();
108 }
109 throw NotFoundException(token);
110}
111
112
113bool StringTokenizer::has(const std::string& token) const
114{
115 TokenVec::const_iterator it = std::find(_tokens.begin(), _tokens.end(), token);
116 return it != _tokens.end();
117}
118
119
120std::size_t StringTokenizer::replace(const std::string& oldToken, const std::string& newToken, std::string::size_type pos)
121{
122 std::size_t result = 0;
123 TokenVec::iterator it = std::find(_tokens.begin() + pos, _tokens.end(), oldToken);
124 while (it != _tokens.end())
125 {
126 result++;
127 *it = newToken;
128 it = std::find(++it, _tokens.end(), oldToken);
129 }
130 return result;
131}
132
133
134} // namespace Poco
135
136