1 /////////////////////////////////////////
2 //
3 //             OpenLieroX
4 //
5 // code under LGPL, based on JasonBs work,
6 // enhanced by Dark Charlie and Albert Zeyer
7 //
8 //
9 /////////////////////////////////////////
10 
11 
12 // String Buffer
13 // Created 11/8/08
14 // Karel Petranek
15 
16 
17 
18 #include "StringBuf.h"
19 #include "StringUtils.h"
20 #include "Debug.h"
21 #include "Utils.h"
22 
23 
24 // Helper functions
strlwr(const std::string & s)25 std::string strlwr(const std::string& s)
26 {
27 	std::string res = s;
28 	stringlwr(res);
29 	return res;
30 }
31 
32 /////////////////////
33 // Adjusts the blank characters so that there are no repeated blank characters and the blank characters are all
34 // turned to spaces
adjustBlank()35 void StringBuf::adjustBlank()
36 {
37 	// Check
38 	if (sStr.size() < 3)
39 		return;
40 
41 	// Initialize iterators
42 	std::string::const_iterator it = sStr.begin();
43 	std::string::const_iterator prev = it;
44 	it++;
45 
46 	// Get the adjusted string
47 	std::string res;
48 	res += *sStr.begin(); // First character, sStr != "" here
49 	for (; it != sStr.end(); it++, prev++)  {
50 		if (isspace((uchar)*it))  {  // Blank
51 			if (isspace((uchar)*prev)) // Previous also blank, ignroe
52 				continue;
53 			else  { // Previous not blank, convert to space and add
54 				res += ' ';
55 				continue;
56 			}
57 		}
58 		res += *it; // Normal character
59 	}
60 
61 	sStr = res;
62 	tPos = sStr.begin();
63 }
64 
65 /////////////////////
66 // Trims all blank characters from both sides of the string
trimBlank()67 void StringBuf::trimBlank()
68 {
69 	// Start
70 	while (sStr.size() && isspace((uchar)(*(sStr.begin()))))
71 		sStr.erase(sStr.begin());
72 
73 	// End
74 	while (sStr.size() && isspace((uchar)(*(sStr.rbegin()))))
75 		sStr.erase(sStr.size() - 1, 1);
76 
77 	tPos = sStr.begin();
78 }
79 
80 ////////////////////
81 // Tokenizes the string buffer by blank characters, multiple blank characters are taken as one
splitByBlank()82 std::vector<std::string> StringBuf::splitByBlank()
83 {
84 	std::vector<std::string> res;
85 	std::string token;
86 	bool was_space = false;
87 	for (std::string::iterator it = sStr.begin(); it != sStr.end(); it++)  {
88 		if (isspace((uchar)(*it)))  {
89 			if (was_space) // Multiple spaces get ignored
90 				continue;
91 			else  {
92 				res.push_back(token); // Add the token
93 				token = "";
94 			}
95 
96 			was_space = true;
97 			continue;
98 		}
99 
100 		was_space = false;
101 		token += *it;
102 	}
103 
104 	// Last token
105 	res.push_back(token);
106 
107 	return res;
108 }
109 
110 ////////////////////
111 // Tokenizes the string buffer by blank the specified character
splitBy(char c)112 std::vector<std::string> StringBuf::splitBy(char c)
113 {
114 	std::vector<std::string> res;
115 	std::string token;
116 	for (std::string::iterator it = sStr.begin(); it != sStr.end(); it++)  {
117 		if (*it == c)  {
118 			res.push_back(token); // Add the token
119 			token = "";
120 			continue;
121 		}
122 
123 		token += *it;
124 	}
125 
126 	// Last token
127 	res.push_back(token);
128 
129 	return res;
130 }
131 
132 ////////////////////////
133 // Reads until the specified character and skips it
readUntil(char c)134 std::string StringBuf::readUntil(char c)
135 {
136 	std::string res;
137 	while (!atEnd() && *tPos != c)  {
138 		res += *tPos;
139 		incPos();
140 	}
141 
142 	// Skip the breaking character
143 	if (!atEnd())
144 		incPos();
145 
146 	return res;
147 }
148 
149 ////////////////////////
150 // Reads until one of the characters specified in char_array, NOT until the string in char_array
readUntil(const std::string & char_array)151 std::string StringBuf::readUntil(const std::string& char_array)
152 {
153 	std::string res;
154 	while (!atEnd() && char_array.find(*tPos) == std::string::npos)  {
155 		res += *tPos;
156 		incPos();
157 	}
158 
159 	// Skip the breaking character
160 	if (!atEnd())
161 		incPos();
162 
163 	return res;
164 }
165 
166 /////////////////////////
167 // Reads the specified number of bytes from the buf
read(size_t num)168 std::string StringBuf::read(size_t num)
169 {
170 	std::string::iterator oth = tPos;
171 	SafeAdvance(tPos, num, sStr.end());
172 	return std::string(tPos, oth);
173 }
174 
175 ///////////////////////
176 // Skips any blank characters
skipBlank()177 size_t StringBuf::skipBlank()
178 {
179 	size_t res = 0;
180 	while (!atEnd() && isspace((uchar)(*tPos))) {
181 		++res;
182 		incPos();
183 	}
184 	return res;
185 }
186 
187 /////////////////////
188 // Converts the buffer to lower case
toLower()189 void StringBuf::toLower()
190 {
191 	stringlwr(sStr);
192 }
193 
194 /////////////////////
195 // Prints the contents to stdout
debugPrint()196 void StringBuf::debugPrint()
197 {
198 	notes << sStr << endl << endl;
199 }
200