//----------------------------------------------------------------------------- // 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 WINDOWS #include #pragma warning (disable : 4996) #elif MAC #include #elif LINUX #include #include #include #include #include #include #include #endif //------------------------------------------------------------------------ namespace Steinberg { //------------------------------------------------------------------------ #if LINUX //------------------------------------------------------------------------ namespace { using Converter = std::wstring_convert, char16_t>; //------------------------------------------------------------------------ Converter& converter () { static Converter instance; return instance; } //------------------------------------------------------------------------ } // anonymous //------------------------------------------------------------------------ #endif // LINUX //------------------------------------------------------------------------ /** Copy strings of different character width. */ //------------------------------------------------------------------------ template 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. */ //------------------------------------------------------------------------ template 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 (thisBuffer, thisSize); } //------------------------------------------------------------------------ UString& UString::assign (const char16* src, int32 srcSize) { StringCopy (thisBuffer, thisSize, src, srcSize); return *this; } //------------------------------------------------------------------------ UString& UString::append (const char16* src, int32 srcSize) { int32 length = getLength (); StringCopy (thisBuffer + length, thisSize - length, src, srcSize); return *this; } //------------------------------------------------------------------------ const UString& UString::copyTo (char16* dst, int32 dstSize) const { StringCopy (dst, dstSize, thisBuffer, thisSize); return *this; } //------------------------------------------------------------------------ UString& UString::fromAscii (const char* src, int32 srcSize) { StringCopy (thisBuffer, thisSize, src, srcSize); return *this; } //------------------------------------------------------------------------ const UString& UString::toAscii (char* dst, int32 dstSize) const { StringCopy (dst, dstSize, thisBuffer, thisSize); return *this; } //------------------------------------------------------------------------ bool UString::scanFloat (double& value) const { #if 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 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 WINDOWS return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1; #elif MAC 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 LINUX auto utf8Buffer = reinterpret_cast (thisBuffer); auto len = snprintf (utf8Buffer, thisSize, "%.*lf", precision, value); if (len > 0) { auto utf16Buffer = reinterpret_cast (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 WINDOWS return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1; #elif MAC CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false); if (cfStr) { value = CFStringGetIntValue (cfStr); CFRelease (cfStr); return true; } return false; #elif 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 WINDOWS return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1; #elif MAC 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 LINUX auto utf8Buffer = reinterpret_cast (thisBuffer); auto len = snprintf (utf8Buffer, thisSize, "%lld", value); if (len > 0) { auto utf16Buffer = reinterpret_cast (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