--- /dev/null 2019-11-18 21:23:07.000000000 -0500 +++ new/src/jdk.incubator.jpackage/windows/native/libjpackage/tstrings.h 2019-11-18 21:23:04.277534500 -0500 @@ -0,0 +1,426 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef TSTRINGS_H +#define TSTRINGS_H + +#ifdef _MSC_VER +# define TSTRINGS_WITH_WCHAR +#endif + +#ifdef TSTRINGS_WITH_WCHAR +#include +#include +// Want compiler issue C4995 warnings for encounters of deprecated functions. +#include +#endif + +// STL's string header depends on deprecated functions. +// We don't care about warnings from STL header, so disable them locally. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4995) +#endif + +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + +#ifndef _T +# define _T(x) x +#endif + + +#ifdef TSTRINGS_WITH_WCHAR +typedef std::wstring tstring; +typedef std::wostringstream tostringstream; +typedef std::wistringstream tistringstream; +typedef std::wstringstream tstringstream; +typedef std::wistream tistream; +typedef std::wostream tostream; +typedef std::wiostream tiostream; +typedef std::wios tios; +#else +typedef std::string tstring; +typedef std::ostringstream tostringstream; +typedef std::istringstream tistringstream; +typedef std::stringstream tstringstream; +typedef std::istream tistream; +typedef std::ostream tostream; +typedef std::iostream tiostream; +typedef std::ios tios; + +typedef const char* LPCTSTR; +typedef char TCHAR; +#endif + +// frequently used "array of tstrings" type +typedef std::vector tstring_array; + +namespace tstrings { + tstring unsafe_format(tstring::const_pointer format, ...); + + enum CompareType {CASE_SENSITIVE, IGNORE_CASE}; + bool equals(const tstring& a, const tstring& b, + const CompareType ct=CASE_SENSITIVE); + bool startsWith(const tstring &str, const tstring &substr, + const CompareType ct=CASE_SENSITIVE); + bool endsWith(const tstring &str, const tstring &substr, + const CompareType ct=CASE_SENSITIVE); + + enum SplitType {ST_ALL, ST_EXCEPT_EMPTY_STRING}; + void split(tstring_array &strVector, const tstring &str, + const tstring &delimiter, const SplitType st = ST_ALL); + inline tstring_array split(const tstring &str, const tstring &delimiter, + const SplitType st = ST_ALL) { + tstring_array result; + split(result, str, delimiter, st); + return result; + } + tstring trim(const tstring& str, const tstring& whitespace = _T(" \t")); + + /** + * Writes sequence of values from [b, e) range into string buffer inserting + * 'delimiter' after each value except of the last one. + * Returns contents of string buffer. + */ + template + tstring join(It b, It e, const tstring& delimiter=tstring()) { + tostringstream buf; + if (b != e) { + for (;;) { + buf << *b; + if (++b == e) { + break; + } + buf << delimiter; + } + } + return buf.str(); + } + + tstring toLower(const tstring& str); + + tstring replace(const tstring &str, const tstring &search, + const tstring &replace); +} + + +namespace tstrings { + inline std::string toUtf8(const std::string& utf8str) { + return utf8str; + } + +#ifdef TSTRINGS_WITH_WCHAR + // conversion to Utf8 + std::string toUtf8(const std::wstring& utf16str); + + // conversion to Utf16 + std::wstring toUtf16(const std::string& utf8str); + + inline std::wstring fromUtf8(const std::string& utf8str) { + return toUtf16(utf8str); + } + +#else + inline std::string fromUtf8(const std::string& utf8str) { + return utf8str; + } +#endif +} // namespace tstrings + + +namespace tstrings { +namespace format_detail { + + template + struct str_arg_value { + const tstring value; + + str_arg_value(const std::string& v): value(fromUtf8(v)) { + } + +#ifdef TSTRINGS_WITH_WCHAR + str_arg_value(const std::wstring& v): value(v) { + } +#endif + + tstring::const_pointer operator () () const { + return value.c_str(); + } + }; + + template <> + struct str_arg_value { + const tstring::const_pointer value; + + str_arg_value(const tstring& v): value(v.c_str()) { + } + + str_arg_value(tstring::const_pointer v): value(v) { + } + + tstring::const_pointer operator () () const { + return value; + } + }; + + inline str_arg_value arg(const std::string& v) { + return v; + } + + inline str_arg_value arg(std::string::const_pointer v) { + return (v ? v : "(null)"); + } + +#ifdef TSTRINGS_WITH_WCHAR + inline str_arg_value arg(const std::wstring& v) { + return v; + } + + inline str_arg_value arg(std::wstring::const_pointer v) { + return (v ? v : L"(null)"); + } +#else + void arg(const std::wstring&); // Compilation error by design. + void arg(std::wstring::const_pointer); // Compilation error by design. +#endif + + template + struct arg_value { + arg_value(const T v): v(v) { + } + T operator () () const { + return v; + } + private: + const T v; + }; + + inline arg_value arg(int v) { + return v; + } + inline arg_value arg(unsigned v) { + return v; + } + inline arg_value arg(long v) { + return v; + } + inline arg_value arg(unsigned long v) { + return v; + } + inline arg_value arg(long long v) { + return v; + } + inline arg_value arg(unsigned long long v) { + return v; + } + inline arg_value arg(float v) { + return v; + } + inline arg_value arg(double v) { + return v; + } + inline arg_value arg(bool v) { + return v; + } + inline arg_value arg(const void* v) { + return v; + } + +} // namespace format_detail +} // namespace tstrings + + +namespace tstrings { + template + inline tstring format(const tstring& fmt, const T& v, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6, const T7& v7) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)(), + format_detail::arg(v2)(), + format_detail::arg(v3)(), + format_detail::arg(v4)(), + format_detail::arg(v5)(), + format_detail::arg(v6)(), + format_detail::arg(v7)()); + } + + template + inline tstring format(const tstring& fmt, const T& v, const T2& v2, const T3& v3, const T4& v4, const T5& v5, const T6& v6) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)(), + format_detail::arg(v2)(), + format_detail::arg(v3)(), + format_detail::arg(v4)(), + format_detail::arg(v5)(), + format_detail::arg(v6)()); + } + + template + inline tstring format(const tstring& fmt, const T& v, const T2& v2, const T3& v3, const T4& v4, const T5& v5) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)(), + format_detail::arg(v2)(), + format_detail::arg(v3)(), + format_detail::arg(v4)(), + format_detail::arg(v5)()); + } + + template + inline tstring format(const tstring& fmt, const T& v, const T2& v2, const T3& v3, const T4& v4) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)(), + format_detail::arg(v2)(), + format_detail::arg(v3)(), + format_detail::arg(v4)()); + } + + template + inline tstring format(const tstring& fmt, const T& v, const T2& v2, const T3& v3) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)(), + format_detail::arg(v2)(), + format_detail::arg(v3)()); + } + + template + inline tstring format(const tstring& fmt, const T& v, const T2& v2) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)(), + format_detail::arg(v2)()); + + } + + template + inline tstring format(const tstring& fmt, const T& v) { + return unsafe_format(fmt.c_str(), format_detail::arg(v)()); + } +} // namespace tstrings + + +namespace tstrings { + /** + * Buffer that accepts both std::wstring and std::string instances doing + * encoding conversions behind the scenes. All std::string-s assumed to be + * UTF8-encoded, all std::wstring-s assumed to be UTF16-encoded. + */ + class any { + public: + any() { + } + + any(std::string::const_pointer msg) { + data << fromUtf8(msg); + } + + any(const std::string& msg) { + data << fromUtf8(msg); + } + +#ifdef TSTRINGS_WITH_WCHAR + any(std::wstring::const_pointer msg) { + data << msg; + } + + any(const std::wstring& msg) { + data << msg; + } + + any& operator << (const std::wstring& v) { + data << v; + return *this; + } + + // need this specialization instead std::wstring::pointer, + // otherwise LPWSTR is handled as abstract pointer (void*) + any& operator << (LPWSTR v) { + data << (v ? v : L"NULL"); + return *this; + } + + // need this specialization instead std::wstring::const_pointer, + // otherwise LPCWSTR is handled as abstract pointer (const void*) + any& operator << (LPCWSTR v) { + data << (v ? v : L"NULL"); + return *this; + } + + std::wstring wstr() const { + return data.str(); + } +#endif + + template + any& operator << (T v) { + data << v; + return *this; + } + + any& operator << (tostream& (*pf)(tostream&)) { + data << pf; + return *this; + } + + any& operator << (tios& (*pf)(tios&)) { + data << pf; + return *this; + } + + any& operator << (std::ios_base& (*pf)(std::ios_base&)) { + data << pf; + return *this; + } + + std::string str() const { + return toUtf8(data.str()); + } + + tstring tstr() const { + return data.str(); + } + + private: + tostringstream data; + }; + + inline tstring to_tstring(const any& val) { + return val.tstr(); + } +} // namespace tstrings + + +inline std::ostream& operator << (std::ostream& os, const tstrings::any& buf) { + os << buf.str(); + return os; +} + +#ifdef TSTRINGS_WITH_WCHAR +inline std::wostream& operator << (std::wostream& os, const tstrings::any& buf) { + os << buf.wstr(); + return os; +} +#endif + +#endif //TSTRINGS_H