1 /* 2 FormatFuncs.h 3 4 Copyright 2010, Alan Calvert 5 Copyright 2014-2021, Will Godfrey and others. 6 7 This file is part of yoshimi, which is free software: you can 8 redistribute it and/or modify it under the terms of the GNU General 9 Public License as published by the Free Software Foundation, either 10 version 2 of the License, or (at your option) any later version. 11 12 yoshimi is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with yoshimi. If not, see <http://www.gnu.org/licenses/>. 19 20 */ 21 22 #ifndef FORMATFUNCS_H 23 #define FORMATFUNCS_H 24 25 #include <cmath> 26 #include <string> 27 #include <sstream> 28 #include <cstring> 29 #include <list> 30 31 namespace func { 32 33 inline std::string asString(int n) 34 { 35 std::ostringstream oss; 36 oss << n; 37 return std::string(oss.str()); 38 } 39 40 41 inline std::string asString(long long n) 42 { 43 std::ostringstream oss; 44 oss << n; 45 return std::string(oss.str()); 46 } 47 48 49 inline std::string asString(unsigned long n) 50 { 51 std::ostringstream oss; 52 oss << n; 53 return std::string(oss.str()); 54 } 55 56 57 inline std::string asString(long n) 58 { 59 std::ostringstream oss; 60 oss << n; 61 return std::string(oss.str()); 62 } 63 64 65 inline std::string asString(unsigned int n) 66 { 67 std::ostringstream oss; 68 oss << n; 69 return std::string(oss.str()); 70 } 71 72 73 inline std::string asString(unsigned int n, unsigned int width) 74 { 75 std::ostringstream oss; 76 oss << n; 77 std::string val = std::string(oss.str()); 78 if (width && val.size() < width) 79 { 80 val = std::string("000000000") + val; 81 return val.substr(val.size() - width); 82 } 83 return val; 84 } 85 86 87 inline std::string asString(unsigned char c) 88 { 89 std::ostringstream oss; 90 oss.width(1); 91 oss << c; 92 return oss.str(); 93 } 94 95 96 inline std::string asString(float n) 97 { 98 std::ostringstream oss; 99 oss.precision(3); 100 oss.width(3); 101 oss << n; 102 return oss.str(); 103 } 104 105 106 inline std::string asLongString(float n) 107 { 108 std::ostringstream oss; 109 oss.precision(9); 110 oss.width(9); 111 oss << n; 112 return oss.str(); 113 } 114 115 116 inline std::string asCompactString(float n) 117 { 118 std::ostringstream oss; 119 oss.setf(std::ios_base::fixed, std::ios_base::floatfield); 120 oss.precision(1); 121 oss.width(1); 122 oss << n; 123 return oss.str(); 124 } 125 126 127 inline std::string asHexString(int x) 128 { 129 std::ostringstream oss; 130 oss << std::hex << x; 131 std::string res = std::string(oss.str()); 132 if (res.length() & 1) 133 return "0"+res; 134 return res; 135 } 136 137 138 inline std::string asHexString(unsigned int x) 139 { 140 std::ostringstream oss; 141 oss << std::hex << x; 142 std::string res = std::string(oss.str()); 143 if (res.length() & 1) 144 return "0"+res; 145 return res; 146 } 147 148 149 inline std::string asMidiNoteString(unsigned char n) 150 { 151 static std::string note[] = { 152 "C","C#","D","D#","E","F","F#","G","G#","A","B","B#" 153 }; 154 int octave = -1 + n/12; 155 int key = n % 12; 156 return "("+note[key]+asString(octave)+")"; 157 } 158 159 160 161 inline float string2float(std::string str) 162 { 163 std::istringstream machine(str); 164 float fval; 165 machine >> fval; 166 return fval; 167 } 168 169 170 inline double string2double(std::string str) 171 { 172 std::istringstream machine(str); 173 double dval; 174 machine >> dval; 175 return dval; 176 } 177 178 179 inline bool isDigits(std::string str) 180 { 181 if (str.empty()) 182 return false; 183 char c = str.at(0); 184 if (c < '0' or c > '9') 185 return false; 186 return true; 187 } 188 189 inline int string2int(std::string str) 190 { 191 std::istringstream machine(str); 192 int intval; 193 machine >> intval; 194 return intval; 195 } 196 197 inline int string2long(std::string str) 198 { 199 std::istringstream machine(str); 200 long longval; 201 machine >> longval; 202 return longval; 203 } 204 205 206 /* ensures MIDI compatible numbers without errors */ 207 inline int string2int127(std::string str) 208 { 209 std::istringstream machine(str); 210 int intval; 211 machine >> intval; 212 if (intval < 0) 213 intval = 0; 214 else if (intval > 127) 215 intval = 127; 216 return intval; 217 } 218 219 220 inline unsigned int string2uint(std::string str) 221 { 222 std::istringstream machine(str); 223 unsigned int intval; 224 machine >> intval; 225 return intval; 226 } 227 228 /* 229 * turns the 1st count mumber to upper case 230 * all the rest to lower case 231 */ 232 inline std::string stringCaps(std::string str, int count) 233 { 234 int idx = 0; 235 char c; 236 while (str[idx]) 237 { 238 c = str[idx]; 239 if (idx < count) 240 str.replace(idx, 1, 1, toupper(c)); 241 else 242 str.replace(idx, 1, 1, tolower(c)); 243 idx ++; 244 } 245 return str; 246 } 247 248 249 /* this is not actually a file operation so we keep it here */ 250 inline int findSplitPoint(std::string name) 251 { 252 unsigned int chk = 0; 253 char ch = name.at(chk); 254 unsigned int len = name.length() - 1; 255 while (ch >= '0' and ch <= '9' and chk < len) 256 { 257 chk += 1; 258 ch = name.at(chk); 259 } 260 if (chk >= len) 261 return 0; 262 if (ch != '-') 263 return 0; 264 return chk; 265 } 266 267 /* 268 * This is principally used to format strings for the GUI 269 * where they are fitted into windows with limited width. 270 * However, it may be useful elsewhere. 271 */ 272 inline std::string formatTextLines(std::string text, size_t maxLen) 273 { 274 size_t totalLen = text.length(); 275 if (totalLen < maxLen) 276 return text; 277 size_t pos = 0; 278 size_t ref = 0; 279 while (pos < totalLen) // split overlong words first 280 { 281 if (text.at(pos) < '!') 282 { 283 ++ pos; 284 ref = pos; 285 } 286 if ((pos - ref) > maxLen) 287 { 288 text.insert(pos, 1, '\n'); 289 ++ totalLen; 290 ++ pos; 291 ref = pos; 292 } 293 ++pos; 294 } 295 296 pos = 0; 297 ref = 0; 298 size_t lastSpace = 0; 299 while (pos < text.length()) 300 { 301 if (text.at(pos) == '\n') // skip over existing line ends 302 { 303 ++ pos; 304 ref = pos; 305 lastSpace = 0; 306 } 307 else if (text.at(pos) == ' ') 308 lastSpace = pos; 309 if ((pos - ref) >= maxLen) 310 { 311 if (lastSpace == 0) 312 pos = text.length(); 313 else 314 { 315 text.at(lastSpace)= '\n'; 316 ref = lastSpace; 317 lastSpace = 0; 318 } 319 } 320 ++ pos; 321 } 322 while (text.at(text.length() - 1) < '!') // tidy up 323 text.pop_back(); 324 return text; 325 } 326 327 328 inline std::string nextLine(std::string& list) // this is destructive 329 { // currently only used in main 330 size_t pos = list.find('\n'); 331 std::string line = ""; 332 if (pos == std::string::npos) 333 { 334 line = list; 335 list = ""; 336 } 337 else 338 { 339 line = list.substr(0, pos); 340 ++pos; 341 if (pos > list.size()) 342 list = ""; 343 else 344 list = list.substr(pos); 345 } 346 return line; 347 } 348 349 }//(End)namespace func 350 #endif /*FORMATFUNCS_H*/ 351