Sorted Socket.
[UnsignedByte.git] / src / Resource / StringUtilities.cpp
blob3b2b2b26a4c5277098d71ce11449f6de8db183a5
1 /***************************************************************************
2 * Copyright (C) 2008 by Sverre Rabbelier *
3 * sverre@rabbelier.nl *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include <sstream>
22 #include <algorithm>
23 #include <cctype>
24 #include <math.h>
26 #include "StringUtilities.h"
27 #include "Parse.h"
29 Strings String::lines(const std::string& input, const char* separator)
31 Assert(separator);
33 Parse p(input, separator, 1);
34 Strings result;
36 while(true)
38 std::string line = p.getword();
39 if(line.size())
40 result.push_back(line);
41 else
42 break;
45 return result;
48 std::string String::unlines(const Strings& input, const char* filler, int extra)
50 Assert(filler);
52 std::string result;
53 int i = 0;
55 for(Strings::const_iterator it = input.begin(); it != input.end(); it++)
57 if(i != 0)
59 if(extra && i%extra == 0)
60 result += "\n";
61 else
62 result += filler;
66 result += (*it);
67 i++;
70 return result;
73 Strings String::unlines(const Strings& input)
75 Strings result;
77 for(Strings::const_iterator it = input.begin(); it != input.end(); it++)
79 Parse p(*it, "\n", 1);
80 while(true)
82 std::string line = p.getword();
83 if(line.size())
84 result.push_back(line);
85 else
86 break;
90 return result;
93 size_t String::maxlength(const Strings& input)
95 size_t champ = 0;
96 for(Strings::const_iterator it = input.begin(); it != input.end(); it++)
98 size_t current = it->size();
99 if(current > champ)
100 champ = current;
102 return champ;
105 std::string String::box(const Strings& unparsedcontent, const std::string& header)
107 bool useheader = (header != Global::Get()->EmptyString);
108 Strings content = unlines(unparsedcontent);
110 size_t length = maxlength(content);
111 if(useheader && header.size() > length)
112 length = header.size();
114 length += 4;
116 std::string result;
117 std::string linefill;
118 std::string spacefill;
119 std::string fill;
121 linefill.assign(length, '_');
122 spacefill.assign(length, ' ');
123 fill.assign( (length-header.size())/2 + 2,' ');
125 std::string title;
126 if(useheader)
127 title = (Global::Get()->sprintf("%s%s%s\n", fill.c_str(), header.c_str(), fill.c_str()));
129 std::string toplet(Global::Get()->sprintf("__%s__\n", linefill.c_str()));
130 std::string top(Global::Get()->sprintf("|\\%s/|\n", linefill.c_str()));
131 std::string body(Global::Get()->sprintf("||%s||\n", spacefill.c_str()));
132 std::string footlet(Global::Get()->sprintf("||%s||\n", linefill.c_str()));
133 std::string footer(Global::Get()->sprintf("|/%s\\|\n", linefill.c_str()));
135 if(useheader)
136 result.append(title);
137 result.append(toplet);
138 result.append(top);
139 result.append(body);
140 for(Strings::const_iterator it = content.begin(); it != content.end(); it++)
142 if(!it->size())
143 continue;
145 result.append(Global::Get()->sprintf("|| %s%.*s||\n",it->c_str(), length - it->size() - 2, spacefill.c_str()));
147 result.append(footlet);
148 result.append(footer);
150 return result;
153 std::string String::toupper(const std::string& input)
155 std::string convertToUpper = input;
156 std::transform(convertToUpper.begin(), convertToUpper.end(), convertToUpper.begin(), (int(*)(int)) std::toupper);
157 return convertToUpper ;
160 std::string String::tolower(const std::string& input)
162 std::string convertToUpper = input;
163 std::transform(convertToUpper.begin(), convertToUpper.end(), convertToUpper.begin(), (int(*)(int)) std::tolower);
164 return convertToUpper ;
167 std::string String::countWord(value_type value)
169 std::string result = fromInt(value);
171 switch(value)
173 case 1:
174 result.append("st");
175 break;
177 case 2:
178 result.append("nd");
179 break;
181 case 3:
182 result.append("rd");
183 break;
185 default:
186 result.append("th");
187 break;
190 return result;
193 std::string String::fromInt(value_type value)
195 std::ostringstream o;
196 if(!(o << value))
197 return "String::fromInt(), ERROR!";
199 return o.str();
202 std::string String::fromLong(signed long value)
204 std::ostringstream o;
205 if(!(o << value))
206 return "String::fromLong(), ERROR!";
208 return o.str();
211 Strings String::createTable(const std::vector<Strings>& content, const Strings& header)
213 Strings result;
215 const size_t maxlinesize = 80;
216 const size_t fieldcount = header.size();
218 std::vector<int> fieldsizes = calculateMinimumFieldSizes(content, fieldcount);
219 rebaseMinimumFieldSizes(fieldsizes, header);
220 capFieldSize(fieldsizes, maxlinesize);
222 std::string theheader = packFields(header, fieldsizes);
224 result.push_back(theheader);
226 for(std::vector<Strings>::const_iterator it = content.begin(); it != content.end(); it++)
228 Strings fields = *it;
229 Assert(fields.size() == fieldcount);
231 std::string line = packFields(fields, fieldsizes);
232 result.push_back(line);
235 return result;
238 std::vector<int> String::calculateMinimumFieldSizes(const std::vector<Strings>& content, int fieldcount)
240 std::vector<int> result(fieldcount);
242 for(std::vector<Strings>::const_iterator it = content.begin(); it != content.end(); it++)
244 Strings line = *it;
245 int i = 0;
246 for(Strings::const_iterator itl = line.begin(); itl != line.end(); itl++)
248 std::string field = *itl;
249 int fieldsize = field.size();
250 fieldsize++; // reserve space for column separator
252 if(fieldsize > result[i])
253 result[i] = fieldsize;
255 i++;
259 return result;
262 void String::rebaseMinimumFieldSizes(std::vector<int>& sizes, const Strings& header)
264 int i = 0;
265 for(Strings::const_iterator it = header.begin(); it != header.end(); it++)
267 std::string field = *it;
268 int fieldsize = field.size();
270 if(fieldsize > sizes[i])
271 sizes[i] = fieldsize;
273 i++;
277 void String::capFieldSize(std::vector<int>& sizes, const int maxlinesize)
279 int totalsize = 0;
280 int maxfairsize = maxlinesize / sizes.size();
281 int unfairfields = 0;
282 int slack = 0;
284 for(size_t i = 0; i < sizes.size(); i++)
286 int size = sizes[i];
287 totalsize += size;
288 if(size > maxfairsize)
289 unfairfields++;
291 if(size < maxfairsize)
292 slack += maxfairsize - size;
295 if(totalsize > maxlinesize)
296 capUnfairFields(sizes, unfairfields, maxfairsize, slack);
299 void String::capUnfairFields(std::vector<int>& sizes, int unfairFields, int maxFairSize, int slack)
301 Assert(unfairFields > 0);
303 for(size_t i = 0; i < sizes.size(); i++)
305 if(sizes[i] > maxFairSize)
307 Assert(unfairFields > 0);
308 Assert(slack >= 0);
310 int size = sizes[i];
311 int toomuch = size - maxFairSize;
312 int myslack = slack / unfairFields;
313 if(myslack > toomuch)
314 myslack = toomuch;
316 sizes[i] = maxFairSize + myslack;
317 slack -= myslack;
318 unfairFields--;
323 std::string String::packFields(const Strings& fields, const std::vector<int>& fieldsizes)
325 std::string result;
327 int i = 0;
328 for(Strings::const_iterator it = fields.begin(); it != fields.end(); it++)
330 result.append("|");
332 std::string field = *it;
333 int fieldsize = field.size();
334 if(fieldsize < fieldsizes[i])
336 size_t padding = fieldsizes[i] - fieldsize;
337 std::string suffix(padding, ' ');
338 result.append(field);
339 result.append(suffix);
341 else if(fieldsize == fieldsizes[i])
342 result.append(field);
343 else
344 result.append(field.substr(0, fieldsizes[i]));
346 i++;
349 result.append("|");
351 return result;
355 7 | 1 | 4 | 6 | 7 | 9 | 12 | 24 = 70
356 0 | -5 | -3 | -1 | 0 | 3 | 5 | 17 = -14
357 7 | 1 | 4 | 6 | 7 | 7 | 7 | 7 = +10
361 9 | 12 | 24 = 70
362 3 | 5 | 17 = -14
363 9 | 11 | 11 = +0/0