| 
							- //-----------------------------------------------------------------------------
 - // Project     : SDK Core
 - //
 - // Category    : Helpers
 - // Filename    : pluginterfaces/base/ustring.cpp
 - // Created by  : Steinberg, 12/2005
 - // Description : UTF-16 String class
 - //
 - //-----------------------------------------------------------------------------
 - // This file is part of a Steinberg SDK. It is subject to the license terms
 - // in the LICENSE file found in the top-level directory of this distribution
 - // and at www.steinberg.net/sdklicenses. 
 - // No part of the SDK, including this file, may be copied, modified, propagated,
 - // or distributed except according to the terms contained in the LICENSE file.
 - //-----------------------------------------------------------------------------
 - 
 - #include "ustring.h"
 - 
 - #if SMTG_OS_WINDOWS
 - #include <cstdio>
 - 
 - #ifdef _MSC_VER
 - #pragma warning (disable : 4996) // deprecated functions
 - #endif
 - 
 - #elif SMTG_OS_MACOS
 - #include <CoreFoundation/CoreFoundation.h>
 - 
 - #elif SMTG_OS_LINUX
 - #include <cstring>
 - #include <string>
 - #include <codecvt>
 - #include <sstream>
 - #include <locale>
 - 
 - #include <wctype.h>
 - #include <wchar.h>
 - 
 - #endif
 - 
 - //------------------------------------------------------------------------
 - namespace Steinberg {
 - 
 - //------------------------------------------------------------------------
 - #if SMTG_OS_LINUX
 - 
 - //------------------------------------------------------------------------
 - namespace {
 - 
 - using Converter = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>;
 - 
 - //------------------------------------------------------------------------
 - Converter& converter ()
 - {
 - 	static Converter instance;
 - 	return instance;
 - }
 - 
 - //------------------------------------------------------------------------
 - } // anonymous
 - 
 - //------------------------------------------------------------------------
 - #endif // SMTG_OS_LINUX
 - 
 - //------------------------------------------------------------------------
 - /** Copy strings of different character width. */
 - //------------------------------------------------------------------------
 - template <class TDstChar, class TSrcChar>
 - void StringCopy (TDstChar* dst, int32 dstSize, const TSrcChar* src, int32 srcSize = -1)
 - {
 - 	int32 count = dstSize;
 - 	if (srcSize >= 0 && srcSize < dstSize)
 - 		count = srcSize;
 - 	for (int32 i = 0; i < count; i++)
 - 	{
 - 		dst[i] = (TDstChar)src[i];
 - 		if (src[i] == 0)
 - 			break;
 - 	}
 - 	dst[dstSize - 1] = 0;
 - }
 - 
 - //------------------------------------------------------------------------
 - /** Find length of null-terminated string, i.e. StringLength (L"ABC\0") => 3 */
 - //------------------------------------------------------------------------
 - template <class TSrcChar>
 - int32 StringLength (const TSrcChar* src, int32 srcSize = -1)
 - {
 - 	if (srcSize == 0)
 - 		return 0;
 - 	int32 length = 0;
 - 	while (src[length])
 - 	{
 - 		length++;
 - 		if (srcSize > 0 && length >= srcSize)
 - 			break;
 - 	}
 - 	return length;
 - }
 - 
 - //------------------------------------------------------------------------
 - // UString
 - //------------------------------------------------------------------------
 - int32 UString::getLength () const
 - {
 - 	return StringLength<char16> (thisBuffer, thisSize);
 - }
 - 
 - //------------------------------------------------------------------------
 - UString& UString::assign (const char16* src, int32 srcSize)
 - {
 - 	StringCopy<char16, char16> (thisBuffer, thisSize, src, srcSize);
 - 	return *this;
 - }
 - 
 - //------------------------------------------------------------------------
 - UString& UString::append (const char16* src, int32 srcSize)
 - {
 - 	int32 length = getLength ();
 - 	StringCopy<char16, char16> (thisBuffer + length, thisSize - length, src, srcSize);
 - 	return *this;
 - }
 - 
 - //------------------------------------------------------------------------
 - const UString& UString::copyTo (char16* dst, int32 dstSize) const
 - {
 - 	StringCopy<char16, char16> (dst, dstSize, thisBuffer, thisSize);
 - 	return *this;
 - }
 - 
 - //------------------------------------------------------------------------
 - UString& UString::fromAscii (const char* src, int32 srcSize)
 - {
 - 	StringCopy<char16, char> (thisBuffer, thisSize, src, srcSize);
 - 	return *this;
 - }
 - 
 - //------------------------------------------------------------------------
 - const UString& UString::toAscii (char* dst, int32 dstSize) const
 - {
 - 	StringCopy<char, char16> (dst, dstSize, thisBuffer, thisSize);
 - 	return *this;
 - }
 - 
 - //------------------------------------------------------------------------
 - bool UString::scanFloat (double& value) const
 - {
 - #if SMTG_OS_WINDOWS
 - 	return swscanf ((const wchar_t*)thisBuffer, L"%lf", &value) != -1;
 - 
 - #elif TARGET_API_MAC_CARBON
 - 	CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
 - 	if (cfStr)
 - 	{
 - 		value = CFStringGetDoubleValue (cfStr);
 - 		CFRelease (cfStr);
 - 		return true;
 - 	}
 - 	return false;
 - 
 - #elif SMTG_OS_LINUX
 - 	auto str = converter ().to_bytes (thisBuffer);
 - 	return sscanf (str.data (), "%lf", &value) == 1;
 - 
 - #else
 - #warning Implement me
 - 	// implement me!
 - 	return false;
 - #endif
 - }
 - 
 - //------------------------------------------------------------------------
 - bool UString::printFloat (double value, int32 precision)
 - {
 - #if SMTG_OS_WINDOWS
 - 	return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1;
 - #elif SMTG_OS_MACOS
 - 	bool result = false;
 - 	CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%.*lf"), precision, value);
 - 	if (cfStr)
 - 	{
 - 		memset (thisBuffer, 0, thisSize);
 - 		CFRange range = {0, CFStringGetLength (cfStr)};
 - 		CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
 - 		CFRelease (cfStr);
 - 		return true;
 - 	}
 - 	return result;
 - #elif SMTG_OS_LINUX
 - 	auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
 - 	auto len = snprintf (utf8Buffer, thisSize, "%.*lf", precision, value);
 - 	if (len > 0)
 - 	{
 - 		auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
 - 		utf16Buffer[len] = 0;
 - 		while (--len >= 0)
 - 		{
 - 			utf16Buffer[len] = utf8Buffer[len];
 - 		}
 - 		return true;
 - 	}
 - 	return false;
 - #else
 - #warning Implement me
 - 	// implement me!
 - 	return false;
 - #endif
 - }
 - 
 - //------------------------------------------------------------------------
 - bool UString::scanInt (int64& value) const
 - {
 - #if SMTG_OS_WINDOWS
 - 	return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1;
 - 
 - #elif SMTG_OS_MACOS
 - 	CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
 - 	if (cfStr)
 - 	{
 - 		value = CFStringGetIntValue (cfStr);
 - 		CFRelease (cfStr);
 - 		return true;
 - 	}
 - 	return false;
 - 
 - #elif SMTG_OS_LINUX
 - 	auto str = converter ().to_bytes (thisBuffer);
 - 	return sscanf (str.data (), "%lld", &value) == 1;
 - 
 - #else
 - #warning Implement me
 - 	// implement me!
 - 	return false;
 - #endif
 - }
 - 
 - //------------------------------------------------------------------------
 - bool UString::printInt (int64 value)
 - {
 - #if SMTG_OS_WINDOWS
 - 	return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1;
 - 
 - #elif SMTG_OS_MACOS
 - 	CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%lld"), value);
 - 	if (cfStr)
 - 	{
 - 		memset (thisBuffer, 0, thisSize);
 - 		CFRange range = {0, CFStringGetLength (cfStr)};
 - 		CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
 - 		CFRelease (cfStr);
 - 		return true;
 - 	}
 - 	return false;
 - #elif SMTG_OS_LINUX
 - 	auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
 - 	auto len = snprintf (utf8Buffer, thisSize, "%lld", value);
 - 	if (len > 0)
 - 	{
 - 		auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
 - 		utf16Buffer[len] = 0;
 - 		while (--len >= 0)
 - 		{
 - 			utf16Buffer[len] = utf8Buffer[len];
 - 		}
 - 		return true;
 - 	}
 - 	return false;
 - 
 - #else
 - #warning Implement me
 - 	// implement me!
 - 	return false;
 - #endif
 - }
 - } // namespace Steinberg
 
 
  |