string doc

This commit is contained in:
2022-04-04 16:17:23 +03:00
parent f83d08cf56
commit fb282d405d
5 changed files with 1435 additions and 821 deletions

View File

@@ -35,81 +35,32 @@
# endif
#endif
/*! \class PIString
* \brief String class
* \details PIP use this class for use string information.
*
* \section PIString_sec0 Synopsis
* This class based on \a PIVector to store information.
* String is a sequence of \a PIChar and can contain multibyte
* symbols. Therefore real memory size of string is symbols count * 4.
* String can be constucted from many types of data and can be converted
* to many types. There are man operators and handly functions to use
* string as you wish.
*
* \section PIString_sec1 To/from data convertions
* Most common constructor is \a PIString(const char * str), where "str"
* is null-terminated string, e.g. \c "string". This is 7 chars with last char = 0.
* Also you can constructs \a PIString from single \a PIChar, \a PIByteArray,
* other \a PIString or sequency of the same characters with custom length.\n \n
* This class has implicit conversions to <tt>const char * </tt> and
* \c std::string. Also there are functions to make same convertions:
* * \a data() - to <tt>const char * </tt>,
* * \a stdString() - to \c std::string,
* * \a toByteArray() - to \a PIByteArray.
*
* \section PIString_sec2 Numeric operations
* You can get symbolic representation of any numeric value with function
* \a setNumber(any integer value, int base = 10, bool * ok = 0). Default
* arguments are set for decimal base system, but you can choose any system
* from 2 to 40. There are the same static functions \a fromNumber(), that
* returns \a PIString. \n
* Also there is function \a setReadableSize() which is set human-readable
* size in bytes, Kb, Mb, Gb or Pb. Static analog is \a readableSize().
*
*/
//! \addtogroup Core
//! \{
//! \class PIString pistring.h
//! \brief
//! \~english String class
//! \~russian Класс строки
//!
//! \~\details
//! \~english \section PIString_sec0 Synopsis
//! \~russian \section PIString_sec0 Краткий обзор
//!
//! \~english
//! String is a sequence of \a PIChar. Real memory size of string is symbols count * 2.
//! String can be constucted from many types of data and can be converted
//! to many types. There are many operators and handly functions to use
//! string as you wish.
//!
//! \~russian
//! Строка состоит из последовательности \a PIChar. Реальный объем памяти,
//! занимаемый строкой, равен количеству символов * 2. Строка может быть
//! создана из множества типов и преобразована в несколько типов.
//! Имеет множество методов для манипуляций.
//!
//! \}
/*! \fn int versionCompare(const PIString & v0, const PIString & v1, int components = 6)
* \relatesalso PIString
* \brief Compare two version strings in free notation and returns 0, -1 or 1
* \details This function parse version to number codes and labels. Then it
* compare no more than "components" codes. If there is no difference, compare
* labels. Each label has corresponding integer value, so
* "prealpha" < "alpha" < "prebeta" < "beta" < "rcN" < "" < "rN".
* Example:
* \code
* piCout << versionCompare("1.0.0_rc2-999", "1.0.1_rc2-999"); // -1
* piCout << versionCompare("1.0.0", "0.9.2"); // 1
* piCout << versionCompare("1.0.0_r1", "1.0.0"); // 1
* piCout << versionCompare("1.0.0_r1", "1.0.0", 3); // 0
* piCout << versionCompare("1.0.0_r1", "1.0.0", 3); // 0
* piCout << versionCompare(".2-alpha", "0.2_alpha"); // 0
* piCout << versionCompare("1_prebeta", "1.0_alpha"); // 1
* \endcode
* \return
* * 0 - equal
* * 1 - v0 > v1
* * -1 - v0 < v1
*
*
* \fn PIString versionNormalize(const PIString & v)
* \relatesalso PIString
* \brief Converts version string in free notation to classic view
* \details Parse version as described in \a versionCompare() and
* returns classic view of codes and labels: major.minor.revision[-build][_label].
* Example:
* \code
* piCout << versionNormalize(""); // 0.0.0
* piCout << versionNormalize("1"); // 1.0.0
* piCout << versionNormalize("1.2"); // 1.2.0
* piCout << versionNormalize("1.2.3"); // 1.2.3
* piCout << versionNormalize("1.2+rc1.99"); // 1.2.99_rc1
* piCout << versionNormalize("1.2-alpha"); // 1.2.0_alpha
* piCout << versionNormalize("1..4_rc2-999"); // 1.0.4-999_rc2
* \endcode
*
*/
const char PIString::toBaseN[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
@@ -376,6 +327,19 @@ PIString PIString::fromCodepage(const char * s, const char * c) {
}
//! \~\details
//! \~english
//! Example:
//! \~russian
//! Пример:
//! \~\code
//! piCout << PIString::readableSize(512); // 512 B
//! piCout << PIString::readableSize(5120); // 5.0 kB
//! piCout << PIString::readableSize(512000); // 500.0 kB
//! piCout << PIString::readableSize(5120000); // 4.8 MB
//! piCout << PIString::readableSize(512000000); // 488.2 MB
//! piCout << PIString::readableSize(51200000000); // 47.6 GB
//! \endcode
PIString PIString::readableSize(llong bytes) {
PIString s;
s.setReadableSize(bytes);
@@ -458,28 +422,6 @@ void PIString::trimsubstr(int &st, int &fn) const {
}
const char * PIString::dataConsole() const {
buildData(__sysoemname__ );
return (const char *)(data_.data());
}
const char * PIString::dataUTF8() const {
buildData(__utf8name__);
return (const char *)(data_.data());
}
const char * PIString::dataAscii() const {
data_.clear();
for (int i = 0; i < size_s(); ++i) {
data_.push_back(uchar(at(i).ch));
}
data_.push_back(uchar('\0'));
return (const char *)data_.data();
}
uint PIString::hash() const {
return piHashData((const uchar*)PIDeque<PIChar>::data(), size() * sizeof(PIChar));
}
@@ -579,6 +521,21 @@ bool PIString::operator >(const PIString & str) const {
}
//! \~\details
//! \~english
//! If "len" < 0 then returns substring from symbol "start" to end.
//! \~russian
//! Если "len" < 0 тогда возвращается подстрока от символа "start" и до конца.
//! \~\code
//! PIString s("0123456789");
//! piCout << s.mid(-2, -1); // s = "0123456789"
//! piCout << s.mid(-2, 4); // s = "01"
//! piCout << s.mid(3, -1); // s = "3456789"
//! piCout << s.mid(3, 4); // s = "3456"
//! piCout << s.mid(7, 1); // s = "7"
//! piCout << s.mid(7, 4); // s = "789"
//! \endcode
//! \~\sa \a left(), \a right()
PIString PIString::mid(const int start, const int len) const {
//PIString str;
int s = start, l = len;
@@ -597,6 +554,17 @@ PIString PIString::mid(const int start, const int len) const {
}
//! \~\details
//! \~\code
//! PIString s("0123456789");
//! s.cutMid(1, 3);
//! piCout << s; // s = "0456789"
//! s.cutMid(-1, 3);
//! piCout << s; // s = "56789"
//! s.cutMid(3, -1);
//! piCout << s; // s = "567"
//! \endcode
//! \~\sa \a cutLeft(), \a cutRight()
PIString & PIString::cutMid(const int start, const int len) {
int s = start, l = len;
if (l == 0) return *this;
@@ -614,6 +582,16 @@ PIString & PIString::cutMid(const int start, const int len) {
}
//! \~\details
//! \~english Remove spaces, tabulations, line feeds and null symbols:
//! \~russian Удаляет пробелы, табуляцию, переводы строк и нулевые символы:
//! \~ ' ', '\\n', '\\r', '\\t', '\\0'
//! \~\code
//! PIString s(" \t string \n");
//! s.trim();
//! piCout << s; // s = "string"
//! \endcode
//! \~\sa \a trimmed()
PIString & PIString::trim() {
int st = -1, fn = 0;
trimsubstr(st, fn);
@@ -635,6 +613,15 @@ PIString PIString::trimmed() const {
}
//! \~\details
//! \~\code
//! PIString s("0123456789");
//! s.replace(2, 3, "_cut_");
//! piCout << s; // s = "01_cut_56789"
//! s.replace(0, 1, "one_");
//! piCout << s; // s = "one_1_cut_56789"
//! \endcode
//! \~\sa \a replaced(), \a replaceAll()
PIString & PIString::replace(int from, int count, const PIString & with) {
count = piMini(count, length() - from);
if (count == with.size_s()) {
@@ -647,6 +634,18 @@ PIString & PIString::replace(int from, int count, const PIString & with) {
}
//! \~\details
//! \~english If "ok" is not null, it set to "true" if something was replaced
//! \~russian Если "ok" не null, то устанавливает в "true" если замена произведена
//! \~\code
//! PIString s("pip string");
//! bool ok;
//! s.replace("string", "conf", &ok);
//! piCout << s << ok; // s = "pip conf", true
//! s.replace("PIP", "PlInPr", &ok);
//! piCout << s << ok; // s = "pip conf", false
//! \endcode
//! \~\sa \a replaced(), \a replaceAll()
PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) {
if (what.isEmpty()) {
if (ok != 0) *ok = false;
@@ -659,6 +658,13 @@ PIString & PIString::replace(const PIString & what, const PIString & with, bool
}
//! \~\details
//! \~\code
//! PIString s("substrings");
//! s.replaceAll("s", "_");
//! piCout << s; // s = "_ub_tring_"
//! \endcode
//! \~\sa \a replace(), \a replaced(), \a replacedAll()
PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
if (what.isEmpty() || what == with) return *this;
if (with.isEmpty()) {
@@ -683,6 +689,13 @@ PIString & PIString::replaceAll(const PIString & what, const PIString & with) {
}
//! \~\details
//! \~\code
//! PIString s("substrings");
//! s.replaceAll("s", '_');
//! piCout << s; // s = "_ub_tring_"
//! \endcode
//! \~\sa \a replace(), \a replaced(), \a replacedAll()
PIString & PIString::replaceAll(const PIString & what, const char with) {
if (what.isEmpty()) return *this;
int l = what.length(), dl = what.length() - 1;
@@ -702,6 +715,13 @@ PIString & PIString::replaceAll(const PIString & what, const char with) {
}
//! \~\details
//! \~\code
//! PIString s("substrings");
//! s.replaceAll('s', '_');
//! piCout << s; // s = "_ub_tring_"
//! \endcode
//! \~\sa \a replace(), \a replaced(), \a replacedAll()
PIString & PIString::replaceAll(const char what, const char with) {
int l = length();
for (int i = 0; i < l; ++i) {
@@ -767,6 +787,15 @@ PIStringList PIString::split(const PIString & delim) const {
}
//! \~\details
//! \~\code
//! PIString s("012345012345");
//! piCout << s.find('-'); // -1
//! piCout << s.find('3'); // 3
//! piCout << s.find('3', 4); // 9
//! piCout << s.find('3', 10); // -1
//! \endcode
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int PIString::find(const char c, const int start) const {
for (int i = start; i < length(); ++i) {
if (at(i) == c) return i;
@@ -775,6 +804,15 @@ int PIString::find(const char c, const int start) const {
}
//! \~\details
//! \~\code
//! PIString s("012345012345");
//! piCout << s.find("-"); // -1
//! piCout << s.find("34"); // 3
//! piCout << s.find("3", 4); // 9
//! piCout << s.find("3", 10); // -1
//! \endcode
//! \~\sa \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int PIString::find(const PIString & str, const int start) const {
int l = str.length();
for (int i = start; i < length() - l + 1; ++i) {
@@ -784,6 +822,30 @@ int PIString::find(const PIString & str, const int start) const {
}
//! \~\details
//! \~\code
//! piCout << PIString("1.str").findAny(".,:"); // 1
//! piCout << PIString("1,str").findAny(".,:"); // 1
//! piCout << PIString("1:str").findAny(".,:"); // 1
//! \endcode
//! \~\sa \a find(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int PIString::findAny(const PIString & str, const int start) const {
for (int i = start; i < length(); ++i) {
if (str.contains(at(i))) return i;
}
return -1;
}
//! \~\details
//! \~\code
//! PIString s("012345012345");
//! piCout << s.findLast('-'); // -1
//! piCout << s.findLast('3'); // 9
//! piCout << s.findLast('3', 4); // 9
//! piCout << s.findLast('3', 10); // -1
//! \endcode
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int PIString::findLast(const char c, const int start) const {
for (int i = length() - 1; i >= start; --i) {
if (at(i) == c) return i;
@@ -792,6 +854,15 @@ int PIString::findLast(const char c, const int start) const {
}
//! \~\details
//! \~\code
//! PIString s("012345012345");
//! piCout << s.findLast("-"); // -1
//! piCout << s.findLast("34"); // 9
//! piCout << s.findLast("3", 4); // 9
//! piCout << s.findLast("3", 10); // -1
//! \endcode
//! \~\sa \a find(), \a findAny(), \a findAnyLast(), \a findWord(), \a findCWord(), \a findRange()
int PIString::findLast(const PIString & str, const int start) const {
int l = str.length();
for (int i = length() - l; i >= start; --i) {
@@ -801,6 +872,30 @@ int PIString::findLast(const PIString & str, const int start) const {
}
//! \~\details
//! \~\code
//! piCout << PIString(".str.0").findAnyLast(".,:"); // 4
//! piCout << PIString(".str,0").findAnyLast(".,:"); // 4
//! piCout << PIString(".str:0").findAnyLast(".,:"); // 4
//! \endcode
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findWord(), \a findCWord(), \a findRange()
int PIString::findAnyLast(const PIString & str, const int start) const {
for (int i = length() - 1; i >= start; --i) {
if (str.contains(at(i))) return i;
}
return -1;
}
//! \~\details
//! \~\code
//! PIString s("this is <PIP>");
//! piCout << s.findWord("this"); // 0
//! piCout << s.findWord("is"); // 5
//! piCout << s.findWord("PIP", 4); // -1
//! piCout << s.findWord("<PIP>", 4); // 8
//! \endcode
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findAnyLast(), \a findCWord(), \a findRange()
int PIString::findWord(const PIString & word, const int start) const {
int f = start - 1, tl = length(), wl = word.length();
while ((f = find(word, f + 1)) >= 0) {
@@ -826,6 +921,15 @@ int PIString::findWord(const PIString & word, const int start) const {
}
//! \~\details
//! \~\code
//! PIString s("this::is <PIP>");
//! piCout << s.findCWord("this"); // 0
//! piCout << s.findCWord("is"); // 6
//! piCout << s.findCWord("PIP", 4); // 10
//! piCout << s.findCWord("<PIP>", 4); // 9
//! \endcode
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findRange()
int PIString::findCWord(const PIString & word, const int start) const {
int f = start - 1, tl = length(), wl = word.length();
while ((f = find(word, f + 1)) >= 0) {
@@ -851,6 +955,15 @@ int PIString::findCWord(const PIString & word, const int start) const {
}
//! \~\details
//! \~\code
//! PIString s(" {figures{inside}}");
//! int len = -1;
//! piCout << s.findRange('{', '}', '\\', 0, &len) << len << s.mid(2, len); // 2 15 figures{inside}
//! s = "\"text\\\"shielded\" next";
//! piCout << s.findRange('"', '"', '\\', 0, &len) << len << s.mid(1, len); // 1 14 text\"shielded
//! \endcode
//! \~\sa \a find(), \a findAny(), \a findLast(), \a findAnyLast(), \a findWord(), \a findCWord()
int PIString::findRange(const PIChar start, const PIChar end, const PIChar shield, const int start_index, int * len) const {
if (len) *len = 0;
bool trim_ = (start != ' ' && start != '\t' && start != '\n' && start != '\r'), eq = (start == end);
@@ -891,22 +1004,6 @@ int PIString::findRange(const PIChar start, const PIChar end, const PIChar shiel
}
int PIString::findAny(const PIString & str, const int start) const {
for (int i = start; i < length(); ++i) {
if (str.contains(at(i))) return i;
}
return -1;
}
int PIString::findAnyLast(const PIString & str, const int start) const {
for (int i = length() - 1; i >= start; --i) {
if (str.contains(at(i))) return i;
}
return -1;
}
int PIString::entries(const PIChar c) const {
int sz = size_s(), ret = 0;
for (int i = 0; i < sz; ++i) {
@@ -928,6 +1025,17 @@ bool PIString::endsWith(const PIString & str) const {
}
//! \~\details
//! \~\code
//! piCout << PIString("true").toBool(); // true
//! piCout << PIString("Yes").toBool(); // true
//! piCout << PIString(" TRUE ").toBool(); // true
//! piCout << PIString(" 1 ").toBool(); // true
//! piCout << PIString("0").toBool(); // false
//! piCout << PIString("0.1").toBool(); // true
//! piCout << PIString("-1").toBool(); // false
//! piCout << PIString("").toBool(); // false
//! \endcode
bool PIString::toBool() const {
static const PIString s_true = PIStringAscii("true");
static const PIString s_yes = PIStringAscii("yes" );
@@ -941,6 +1049,15 @@ bool PIString::toBool() const {
}
//! \~\details
//! \~\code
//! PIString s("\t ! word");
//! piCout << s.takeSymbol(); // "!"
//! piCout << s.takeSymbol(); // "w"
//! piCout << s.takeSymbol(); // "o"
//! piCout << s; // "rd"
//! \endcode
//! \~\sa \a takeWord(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange()
PIString PIString::takeSymbol() {
PIString ret;
int sz = size_s(), ss = -1;
@@ -957,6 +1074,15 @@ PIString PIString::takeSymbol() {
}
//! \~\details
//! \~\code
//! PIString s("some words\nnew line ");
//! piCout << s.takeWord(); // "some"
//! piCout << s.takeWord(); // "words"
//! piCout << s.takeWord(); // "new"
//! piCout << s; // " line "
//! \endcode
//! \~\sa \a takeSymbol(), \a takeCWord(), \a takeLine(), \a takeNumber(), \a takeRange()
PIString PIString::takeWord() {
int sz = size_s(), ws = -1, we = -1;
for (int i = 0; i < sz; ++i) {
@@ -977,6 +1103,10 @@ PIString PIString::takeWord() {
}
//! \~\details
//! \~\code
//! \endcode
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeLine(), \a takeNumber(), \a takeRange()
PIString PIString::takeCWord() {
PIString ret;
int sz = size_s(), ws = -1, we = -1;
@@ -1009,6 +1139,15 @@ PIString PIString::takeCWord() {
}
//! \~\details
//! \~\code
//! PIString s("some words\nnew line \n\nend");
//! piCout << s.takeLine(); // "some words"
//! piCout << s.takeLine(); // "new line "
//! piCout << s.takeLine(); // ""
//! piCout << s; // "end"
//! \endcode
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeCWord(), \a takeNumber(), \a takeRange()
PIString PIString::takeLine() {
int sz = size_s(), le = -1;
for (int i = 0; i < sz; ++i) {
@@ -1029,6 +1168,16 @@ PIString PIString::takeLine() {
}
//! \~\details
//! \~\code
//! PIString s(" 0xFF -99 1.2E+5f 1000L");
//! piCout << s.takeNumber(); // "0xFF"
//! piCout << s.takeNumber(); // "-99"
//! piCout << s.takeNumber(); // "1.2E+5f"
//! piCout << s.takeNumber(); // "1000L"
//! piCout << s; // ""
//! \endcode
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeCWord(), \a takeLine(), \a takeRange()
PIString PIString::takeNumber() {
PIString ret;
int sz = size_s(), ls = -1, le = -1, phase = 0;
@@ -1123,6 +1272,18 @@ PIString PIString::takeNumber() {
}
//! \~\details
//! \~english "shield" symbol prevent analysis of the next symbol
//! \~russian Символ "shield" экранирует следующий символ
//! \~\code
//! PIString s(" {figures{inside}}");
//! piCout << s.takeRange('{', '}'); // "figures{inside}"
//! piCout << s; // ""
//! s = "\"text\\\"shielded\" next";
//! piCout << s.takeRange('"', '"'); // "text\"shielded"
//! piCout << s; // " next"
//! \endcode
//! \~\sa \a takeSymbol(), \a takeWord(), \a takeLine(), \a takeNumber()
PIString PIString::takeRange(const PIChar start, const PIChar end, const PIChar shield) {
PIString ret;
bool trim_ = (start != ' ' && start != '\t' && start != '\n' && start != '\r'), eq = (start == end);
@@ -1170,6 +1331,12 @@ PIString PIString::takeRange(const PIChar start, const PIChar end, const PIChar
}
//! \~\details
//! \~\code
//! PIString s("a(b(c)d)e");
//! piCout << s.inBrackets('(', ')'); // "b(c)d"
//! piCout << s; // s = "a(b(c)d)e"
//! \endcode
PIString PIString::inBrackets(const PIChar start, const PIChar end) const {
int slen = length();
int st = -1, bcnt = 0;
@@ -1189,6 +1356,96 @@ PIString PIString::inBrackets(const PIChar start, const PIChar end) const {
}
//! \~\details
//! \~english It`s equivalent length of char sequence returned by function \a data() - 1, without terminating null-char
//! \~russian Эквивалентно длине данных, возвращаемых \a data() - 1, без завершающего нулевого байта
//! \~\code
//! piCout << PIString("0123456789").lengthAscii(); // 10
//! piCout << PIString("№1").lengthAscii(); // 3
//! \endcode
//! \~\sa \a data()
int PIString::lengthAscii() const {
buildData(__syslocname__);
return data_.size_s() - 1;
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Minimum length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Минимальный размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! \~\code
//! piCout << PIString("0123456789").data(); // 0123456789
//! piCout << PIString("№1").data(); // №1
//! \endcode
//! \~\sa \a dataConsole(), \a dataUTF8()
const char * PIString::data() const {
buildData(__syslocname__);
return (const char *)(data_.data());
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Minimum length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Минимальный размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! \~\sa \a data(), \a dataUTF8()
const char * PIString::dataConsole() const {
buildData(__sysoemname__ );
return (const char *)(data_.data());
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Minimum length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Минимальный размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! \~\sa \a data(), \a dataConsole()
const char * PIString::dataUTF8() const {
buildData(__utf8name__);
return (const char *)(data_.data());
}
//! \~\details
//! \~english
//! This function fill internal buffer by sequence
//! of chars. Length of this buffer is count
//! of symbols. Returned pointer is valid until next
//! execution of this function
//! \~russian
//! Этот метод заполняет внутренный байтовый буфер. Размер
//! этого буфера равен количеству символов строки. Возвращаемый указатель
//! действителен до следующего вызова этого метода
//! \~\sa \a dataConsole(), \a dataUTF8()
const char * PIString::dataAscii() const {
data_.clear();
for (int i = 0; i < size_s(); ++i) {
data_.push_back(uchar(at(i).ch));
}
data_.push_back(uchar('\0'));
return (const char *)data_.data();
}
PIString PIString::toUpperCase() const {
PIString str(*this);
int l = str.size();
@@ -1243,6 +1500,26 @@ ldouble PIString::toLDouble() const {
}
//! \~\details
//! \~english
//! Example:
//! \~russian
//! Пример:
//! \~\code
//! PIString s;
//! s.setReadableSize(512);
//! piCout << s; // 512 B
//! s.setReadableSize(5120);
//! piCout << s; // 5.0 kB
//! s.setReadableSize(512000);
//! piCout << s; // 500.0 kB
//! s.setReadableSize(5120000);
//! piCout << s; // 4.8 MB
//! s.setReadableSize(512000000);
//! piCout << s; // 488.2 MB
//! s.setReadableSize(51200000000);
//! piCout << s; // 47.6 GB
//! \endcode
PIString & PIString::setReadableSize(llong bytes) {
clear();
if (bytes < 1024) {
@@ -1351,6 +1628,38 @@ int versionLabelValue(PIString s) {
}
//! \relatesalso PIString
//! \~\details
//! \~english
//! This function parse version to number codes and labels. Then it
//! compare no more than "components" codes. If there is no difference, compare
//! labels. Each label has corresponding integer value, so
//! "prealpha" < "alpha" < "prebeta" < "beta" < "rc[N]" < "" < "r[N]".
//! Example:
//! \~russian
//! Этот метод разбирает версии на числовые части и метку. Затем сравнивает
//! не более чем "components" частей. Если различий нет, то сравниваются
//! метки. Каждой метке соответствует своё значение так, что
//! "prealpha" < "alpha" < "prebeta" < "beta" < "rc[N]" < "" < "r[N]".
//! Пример:
//! \~\code
//! piCout << versionCompare("1.0.0_rc2-999", "1.0.1_rc2-999"); // -1, <
//! piCout << versionCompare("1.0.0", "0.9.2"); // 1, >
//! piCout << versionCompare("1.0.0_r1", "1.0.0"); // 1, >
//! piCout << versionCompare("1.0.0_r1", "1.0.0", 3); // 0, =
//! piCout << versionCompare("1.0.0_r2", "1.0.0", 3); // 0, =
//! piCout << versionCompare(".2-alpha", "0.2_alpha"); // 0, =
//! piCout << versionCompare("1_prebeta", "1.0_alpha"); // 1, >
//! \endcode
//! \~\return
//! \~english
//! * 0 - equal
//! * 1 - v0 > v1
//! * -1 - v0 < v1
//! \~russian
//! * 0 - равны
//! * 1 - v0 > v1
//! * -1 - v0 < v1
int versionCompare(const PIString & v0, const PIString & v1, int components) {
PIStringList strs[2]; PIVector<int> codes[2];
parseVersion(v0.toLowerCase(), codes[0], strs[0]);
@@ -1379,6 +1688,25 @@ int versionCompare(const PIString & v0, const PIString & v1, int components) {
}
//! \relatesalso PIString
//! \~\details
//! \~english
//! Parse version as described in \a versionCompare() and returns
//! classic view of codes and labels: major.minor.revision[-build][_label].
//! Example:
//! \~russian
//! Разбирает версию по описанию \a versionCompare() и возвращает
//! классическое представление версии и метки: major.minor.revision[-build][_label].
//! Пример:
//! \~\code
//! piCout << versionNormalize(""); // 0.0.0
//! piCout << versionNormalize("1"); // 1.0.0
//! piCout << versionNormalize("1.2"); // 1.2.0
//! piCout << versionNormalize("1.2.3"); // 1.2.3
//! piCout << versionNormalize("1.2+rc1.99"); // 1.2.99_rc1
//! piCout << versionNormalize("1.2-alpha"); // 1.2.0_alpha
//! piCout << versionNormalize("1..4_rc2-999"); // 1.0.4-999_rc2
//! \endcode
PIString versionNormalize(const PIString & v) {
PIStringList strs; PIVector<int> codes;
parseVersion(v.toLowerCase(), codes, strs);
@@ -1407,4 +1735,3 @@ PICout operator <<(PICout s, const PIString & v) {
s.quote();
return s;
}