1 /***************************************************************************
2 * Copyright (C) 2008 by Sverre Rabbelier *
3 * sverre@rabbelier.nl *
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. *
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. *
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 ***************************************************************************/
26 #include "StringUtilities.h"
29 Strings
String::lines(const std::string
& input
, const char* separator
)
33 Parse
p(input
, separator
, 1);
38 std::string line
= p
.getword();
40 result
.push_back(line
);
48 std::string
String::unlines(const Strings
& input
, const char* filler
, int extra
)
55 for(Strings::const_iterator it
= input
.begin(); it
!= input
.end(); it
++)
59 if(extra
&& i
%extra
== 0)
73 Strings
String::unlines(const Strings
& input
)
77 for(Strings::const_iterator it
= input
.begin(); it
!= input
.end(); it
++)
79 Parse
p(*it
, "\n", 1);
82 std::string line
= p
.getword();
84 result
.push_back(line
);
93 size_t String::maxlength(const Strings
& input
)
96 for(Strings::const_iterator it
= input
.begin(); it
!= input
.end(); it
++)
98 size_t current
= it
->size();
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();
117 std::string linefill
;
118 std::string spacefill
;
121 linefill
.assign(length
, '_');
122 spacefill
.assign(length
, ' ');
123 fill
.assign( (length
-header
.size())/2 + 2,' ');
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()));
136 result
.append(title
);
137 result
.append(toplet
);
140 for(Strings::const_iterator it
= content
.begin(); it
!= content
.end(); it
++)
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
);
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
);
193 std::string
String::fromInt(value_type value
)
195 std::ostringstream o
;
197 return "String::fromInt(), ERROR!";
202 std::string
String::fromLong(signed long value
)
204 std::ostringstream o
;
206 return "String::fromLong(), ERROR!";
211 Strings
String::createTable(const std::vector
<Strings
>& content
, const Strings
& header
)
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
);
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
++)
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
;
262 void String::rebaseMinimumFieldSizes(std::vector
<int>& sizes
, const Strings
& header
)
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
;
277 void String::capFieldSize(std::vector
<int>& sizes
, const int maxlinesize
)
280 int maxfairsize
= maxlinesize
/ sizes
.size();
281 int unfairfields
= 0;
284 for(size_t i
= 0; i
< sizes
.size(); i
++)
288 if(size
> maxfairsize
)
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);
311 int toomuch
= size
- maxFairSize
;
312 int myslack
= slack
/ unfairFields
;
313 if(myslack
> toomuch
)
316 sizes
[i
] = maxFairSize
+ myslack
;
323 std::string
String::packFields(const Strings
& fields
, const std::vector
<int>& fieldsizes
)
328 for(Strings::const_iterator it
= fields
.begin(); it
!= fields
.end(); it
++)
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
);
344 result
.append(field
.substr(0, fieldsizes
[i
]));
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