23 #include "strings.hpp"
27 #include "datastreamoperatorwrapper.h"
28 #include "plugins/engineplugin.h"
29 #include "plugins/pluginloader.h"
34 #include <QDataStream>
37 #include <QRegularExpression>
38 #include <QStringList>
41 const char Strings::RANDOM_CHAR_POOL[RANDOM_CHAR_POOL_SIZE] =
43 'a',
'b',
'c',
'd',
'e',
'f',
'g',
44 'h',
'i',
'j',
'k',
'l',
'm',
'n',
45 'o',
'p',
'q',
'r',
's',
't',
'u',
46 'v',
'w',
'x',
'y',
'z',
'0',
'1',
47 '2',
'3',
'4',
'5',
'6',
'7',
'8',
53 static const char colorChart[22][7] =
81 for (
int i = 0; i < str.length(); i++)
83 if (str[i] == ESCAPE_COLOR_CHAR)
86 if (i >= str.length())
88 QChar colorChar = str[i].toLower();
89 int color = colorChar.toLatin1() - 97;
93 color = current == 0 ? 19 : current - 1;
94 else if (colorChar ==
'*')
96 else if (colorChar ==
'!')
98 else if (colorChar ==
'[')
100 int end = str.indexOf(
']', i);
103 QString colorName = str.mid(i + 1, end - i - 1);
104 if (colorName.indexOf(
'"') == -1)
105 ret += QString(
"<span style=\"color: " + colorName +
"\">");
106 i += colorName.length() + 1;
110 else if (colorChar ==
'-')
124 if (color >= 0 && color < 22)
126 ret += QString(
"<span style=\"color: #") + colorChart[color] +
"\">";
141 for (
const QString &s : fronts)
150 QString combinedPath;
153 if (pathFront.isEmpty())
158 if (pathEnd.isEmpty())
163 pathFront = Strings::trimr(pathFront,
"/\\");
164 pathEnd = Strings::triml(pathEnd,
"/\\");
166 combinedPath = pathFront +
"/" + pathEnd;
174 QString generatedString =
"";
175 for (
unsigned i = 0; i < numChars; ++i)
178 generatedString += RANDOM_CHAR_POOL[index];
181 return generatedString;
184 QString Strings::createRandomAlphaNumericStringWithNewLines(
unsigned numCharsPerLine,
unsigned numLines)
186 QString generatedString =
"";
187 for (
unsigned i = 0; i < numLines; ++i)
192 return generatedString;
196 static char escapeCharacters[] = {
'\\',
'"', 0};
199 for (
unsigned int i = 0; escapeCharacters[i] != 0; i++)
202 for (
int p = 0; p < str.length() && (p = str.indexOf(escapeCharacters[i], p)) != -1; p += 2)
209 const QString &Strings::unescape(QString &str)
211 for (
unsigned int i = 0; escapeCharacters[i] != 0; i++)
213 QString sequence =
"\\" + QString(escapeCharacters[i]);
214 for (
int p = 0; p < str.length() && (p = str.indexOf(sequence, p)) != -1; p++)
215 str.replace(str.indexOf(sequence, p), 2, escapeCharacters[i]);
224 auto fBytes = (float)bytes;
225 fBytes = scaleDataUnit(fBytes, dataUnit);
227 QString formattedString = QString(
"%1 ").arg(fBytes, 0,
'f', 2);
231 formattedString +=
"B";
235 formattedString +=
"kB";
239 formattedString +=
"MB";
243 formattedString +=
"GB";
248 return "#ERR: Formatting data amount error.";
251 return formattedString;
258 speedInBytesPerSecond = scaleDataUnit(speedInBytesPerSecond, dataUnit);
260 QString formattedString = QString(
"%1 ").arg(speedInBytesPerSecond, 0,
'f', 2);
264 formattedString +=
"B/s";
268 formattedString +=
"kB/s";
272 formattedString +=
"MB/s";
276 formattedString +=
"GB/s";
281 return "#ERR: Formatting speed error.";
284 return formattedString;
291 return "#ERR: Formatting time error.";
294 seconds = ceil(seconds);
301 int remainingSeconds = 0;
303 if (seconds >= 3600.0f)
306 hours = seconds / 3600.0f;
307 seconds -= hours * 3600.0f;
310 if (seconds >= 60.0f)
313 minutes = seconds / 60.0f;
314 seconds -= minutes * 60.0f;
317 remainingSeconds = (int)seconds;
319 QString formattedString;
322 formattedString += QString(
"%1h ").arg(hours);
325 if (hours > 0 || minutes > 0)
327 formattedString += QString(
"%1min. ").arg(minutes);
330 formattedString += QString(
"%1s").arg(remainingSeconds);
332 return formattedString;
335 bool Strings::isCharOnCharList(
char c,
const QString &charList)
337 for (
const auto &candidate : charList)
348 QUrl urlObject = url;
350 QString scheme = urlObject.scheme();
352 bool bIsSafe1 = scheme.isEmpty();
353 bool bIsSafe2 = (scheme.compare(
"http", Qt::CaseInsensitive) == 0);
354 bool bIsSafe3 = (scheme.compare(
"ftp", Qt::CaseInsensitive) == 0);
355 bool bIsSafe4 = (scheme.compare(
"https", Qt::CaseInsensitive) == 0);
358 return bIsSafe1 || bIsSafe2 || bIsSafe3 || bIsSafe4;
363 if (text.length() <= left + right) {
367 filtered += text.left(left);
368 filtered += ellipsis;
369 filtered += text.right(text.length() - right);
375 path = QDir::fromNativeSeparators(path);
376 path = QDir::cleanPath(path);
387 float Strings::scaleDataUnit(
float bytes, DataUnit &outUnit)
389 const static float UPPER_BOUNDARY = 900.0f;
392 while (bytes > UPPER_BOUNDARY && outUnit != Gigabyte)
395 outUnit = (DataUnit)((
int)outUnit + 1);
401 QString Strings::timestamp(
const QString &format)
403 return QDateTime::currentDateTime().toString(format);
409 QStringList addressAndPort = addressString.split(
":");
410 QStringList defaultAddressAndPort = defaultAddress.split(
":");
412 if (addressAndPort.size() >= 1 && addressAndPort.size() <= 2)
414 hostname = addressAndPort[0];
415 if (addressAndPort.size() == 2)
417 port = addressAndPort[1].toUShort();
423 if (defaultAddressAndPort.size() >= 1)
425 hostname = defaultAddressAndPort[0];
429 if (port == 0 && defaultAddressAndPort.size() >= 2)
431 port = defaultAddressAndPort[1].toUShort();
435 QString &Strings::trimr(QString &str,
const QString &charList)
438 for (i = str.length() - 1; i >= 0; --i)
440 if (!isCharOnCharList(str[i].toLatin1(), charList))
445 return str.remove(i, str.length() - i);
448 QString &Strings::triml(QString &str,
const QString &charList)
451 for (i = 0; i < str.length(); ++i)
453 if (!isCharOnCharList(str[i].toLatin1(), charList))
457 return str.remove(0, i);
462 static QString pluginSchemes;
463 if (pluginSchemes.isEmpty())
465 pluginSchemes =
"zds";
467 for (
unsigned int i = 0; i < gPlugins->numPlugins(); ++i)
468 pluginSchemes = QString(
"%1|%2").arg(pluginSchemes)
469 .arg(gPlugins->plugin(i)->info()->data()->scheme);
472 QRegularExpression pattern(QString(
"("
474 "(http|https|ftp|%1)://"
476 ")[\\w\\-\\.,@?^=%&:/~\\+#\\(\\)]+"
477 ")").arg(pluginSchemes), QRegularExpression::CaseInsensitiveOption);
478 QString newString = str;
483 auto match = pattern.match(newString, offset);
484 if (!match.hasMatch())
487 int index = match.capturedStart(1);
488 QString cap = match.captured(1);
489 int capLength = cap.length();
491 QString replacement = cap;
492 if (cap.startsWith(
"www.", Qt::CaseInsensitive))
494 replacement =
"http://" + cap;
497 replacement = QString(
"<a href=\"%1\">%2</a>").arg(replacement, cap);
499 newString.replace(index, capLength, replacement);
500 offset = index + replacement.length();