/*! \file pistring_std.h
 * \ingroup Text
 * \~\brief
 * \~english Standard library conversions for PIString
 * \~russian Преобразования `PIString` для стандартной библиотеки
 *
 * \~\details
 * \~english Declares conversions and stream operators between \a PIString and standard library string types.
 * \~russian Объявляет преобразования и потоковые операторы между \a PIString и строковыми типами стандартной библиотеки.
 */
/*
    PIP - Platform Independent Primitives
    STD for PIString
    Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PISTRING_STD_H
#define PISTRING_STD_H


#include <ostream>
#include <string>
#ifdef QNX
//! \~english Compatibility alias for wide strings on QNX.
//! \~russian Совместимый псевдоним для широких строк на QNX.
typedef std::basic_string<wchar_t> wstring;
#endif
#include "piliterals.h"
#include "pistringlist.h"


//! \relatesalso PIString
//! \~english Converts \a PIString to \c std::string by exporting 16-bit character codes byte by byte.
//! \~russian Преобразует \a PIString в \c std::string, выгружая 16-битные коды символов побайтно.
inline std::string PIString2StdString(const PIString & v) {
	std::string s;
	ushort wc;
	uchar tc;
	if (v.size() > 0) {
		for (int i = 0; i < v.length(); ++i) {
			wc = v[i].unicode16Code();
			while (tc = wc & 0xFF, tc) {
				s.push_back(tc);
				wc >>= 8;
			}
		}
	}
	return s;
}


//! \relatesalso PIString
//! \~english Builds \a PIString from \c std::string.
//! \~russian Создает \a PIString из \c std::string.
inline PIString StdString2PIString(const std::string & v) {
	return PIString(v.c_str(), v.length());
}


// #ifdef HAS_LOCALE
//! \relatesalso PIString
//! \~english Converts \a PIString to \c std::wstring.
//! \~russian Преобразует \a PIString в \c std::wstring.
inline std::wstring PIString2StdWString(const PIString & v) {
	std::wstring s;
	for (int i = 0; i < v.length(); ++i) {
		s.push_back(v[i].toWChar());
	}
	return s;
}


//! \relatesalso PIString
//! \~english Builds \a PIString from \c std::wstring.
//! \~russian Создает \a PIString из \c std::wstring.
inline PIString StdWString2PIString(const std::wstring & v) {
	PIString s;
	uint l = v.size();
	for (uint i = 0; i < l; ++i) {
		s.push_back(PIChar(v[i]));
	}
	return s;
}
// #endif


//! \relatesalso PIChar
//! \~english Writes a \a PIChar to \c std::ostream.
//! \~russian Записывает \a PIChar в \c std::ostream.
inline std::ostream & operator<<(std::ostream & s, const PIChar & v) {
	s << v.toCharPtr();
	return s;
}


//! \relatesalso PIString
//! \~english Returns concatenation of \a PIString and \c std::string.
//! \~russian Возвращает конкатенацию \a PIString и \c std::string.
inline PIString operator+(const PIString & f, const std::string & str) {
	PIString s(f);
	s += StdString2PIString(str);
	return s;
}


//! \relatesalso PIString
//! \~english Returns concatenation of \c std::string and \a PIString.
//! \~russian Возвращает конкатенацию \c std::string и \a PIString.
inline PIString operator+(const std::string & str, const PIString & f) {
	return StdString2PIString(str) + f;
}


//! \relatesalso PIString
//! \~english Writes \a PIString to \c std::ostream.
//! \~russian Записывает \a PIString в \c std::ostream.
inline std::ostream & operator<<(std::ostream & s, const PIString & v) {
	for (int i = 0; i < v.length(); ++i) {
		s << v[i];
	}
	return s;
}


//! \relatesalso PIString
//! \~english Reads a whitespace-delimited token from \c std::istream into \a PIString.
//! \~russian Читает из \c std::istream токен до пробельного символа в \a PIString.
inline std::istream & operator>>(std::istream & s, PIString & v) {
	std::string ss;
	s >> ss;
	v = StdString2PIString(ss);
	return s;
}


//! \relatesalso PIStringList
//! \~english Writes \a PIStringList to \c std::ostream in brace-delimited form.
//! \~russian Записывает \a PIStringList в \c std::ostream в формате со скобками.
inline std::ostream & operator<<(std::ostream & s, const PIStringList & v) {
	s << PIChar('{');
	for (uint i = 0; i < v.size(); ++i) {
		s << PIChar('"') << v[i] << PIChar('"');
		if (i < v.size() - 1) s << ", "_a;
	}
	s << PIChar('}');
	return s;
}


#endif // PISTRING_STD_H
