-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathstrtok.cpp
142 lines (121 loc) · 2.81 KB
/
strtok.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/// string tokenizer implementation
/**
* \file strtok.cpp
*
* string tokenizer
*
* Copyright (C) 2006, 2007, 2008 Lukas Jelinek, <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of one of the following licenses:
*
* \li 1. X11-style license (see LICENSE-X11)
* \li 2. GNU Lesser General Public License, version 2.1 (see LICENSE-LGPL)
* \li 3. GNU General Public License, version 2 (see LICENSE-GPL)
*
* If you want to help with choosing the best license for you,
* please visit http://www.gnu.org/licenses/license-list.html.
*
*/
#include <sstream>
#include "strtok.h"
StringTokenizer::StringTokenizer(const std::string& rStr, char cDelim, char cPrefix)
{
m_str = rStr;
m_cDelim = cDelim;
m_cPrefix = cPrefix;
m_pos = 0;
m_len = rStr.length();
}
std::string StringTokenizer::GetNextToken(bool fSkipEmpty)
{
std::string s;
do {
_GetNextToken(s, true);
} while (fSkipEmpty && s.empty() && m_pos < m_len);
return s;
}
std::string StringTokenizer::GetNextTokenRaw(bool fSkipEmpty)
{
std::string s;
do {
_GetNextToken(s, false);
} while (fSkipEmpty && s.empty() && m_pos < m_len);
return s;
}
std::string StringTokenizer::GetRemainder()
{
return m_cPrefix == '\0'
? m_str.substr(m_pos)
: StripPrefix(m_str.c_str() + m_pos, m_len - m_pos);
}
std::string StringTokenizer::StripPrefix(const char* s, SIZE cnt)
{
std::ostringstream stream;
SIZE pos = 0;
while (pos < cnt) {
if (s[pos] == m_cPrefix) {
if ((pos < cnt - 1) && s[pos+1] == m_cPrefix) {
stream << m_cPrefix;
pos++;
}
}
else {
stream << s[pos];
}
pos++;
}
return stream.str();
}
void StringTokenizer::_GetNextToken(std::string& rToken, bool fStripPrefix)
{
if (m_cPrefix == '\0') {
_GetNextTokenNoPrefix(rToken);
}
else {
_GetNextTokenWithPrefix(rToken);
if (fStripPrefix)
rToken = StripPrefix(rToken.c_str(), rToken.length());
}
}
void StringTokenizer::_GetNextTokenNoPrefix(std::string& rToken)
{
const char* s = m_str.c_str();
for (SIZE i=m_pos; i<m_len; i++) {
if (s[i] == m_cDelim) {
rToken = m_str.substr(m_pos, i - m_pos);
m_pos = i + 1;
return;
}
}
rToken = m_str.substr(m_pos);
m_pos = m_len;
}
void StringTokenizer::_GetNextTokenWithPrefix(std::string& rToken)
{
int pref = 0;
const char* s = m_str.c_str();
for (SIZE i=m_pos; i<m_len; i++) {
if (s[i] == m_cDelim) {
if (pref == 0) {
rToken = m_str.substr(m_pos, i - m_pos);
m_pos = i + 1;
return;
}
else {
pref = 0;
}
}
else if (s[i] == m_cPrefix) {
if (pref == 1)
pref = 0;
else
pref = 1;
}
else {
pref = 0;
}
}
rToken = m_str.substr(m_pos);
m_pos = m_len;
}