Add initial bits for Qt6 support
[carla.git] / source / includes / vst3sdk / pluginterfaces / base / ustring.cpp
blob24a412f7e2b1492f90e96b5de9bb3bda27874b34
1 //-----------------------------------------------------------------------------
2 // Project : SDK Core
3 //
4 // Category : Helpers
5 // Filename : pluginterfaces/base/ustring.cpp
6 // Created by : Steinberg, 12/2005
7 // Description : UTF-16 String class
8 //
9 //-----------------------------------------------------------------------------
10 // This file is part of a Steinberg SDK. It is subject to the license terms
11 // in the LICENSE file found in the top-level directory of this distribution
12 // and at www.steinberg.net/sdklicenses.
13 // No part of the SDK, including this file, may be copied, modified, propagated,
14 // or distributed except according to the terms contained in the LICENSE file.
15 //-----------------------------------------------------------------------------
17 #include "ustring.h"
19 #if SMTG_OS_WINDOWS
20 #include <cstdio>
22 #ifdef _MSC_VER
23 #pragma warning (disable : 4996) // deprecated functions
24 #endif
26 #elif SMTG_OS_MACOS
27 #include <CoreFoundation/CoreFoundation.h>
29 #elif SMTG_OS_LINUX
30 #include <cstring>
31 #include <string>
32 #include <codecvt>
33 #include <sstream>
34 #include <locale>
36 #include <wctype.h>
37 #include <wchar.h>
39 #endif
41 //------------------------------------------------------------------------
42 namespace Steinberg {
44 //------------------------------------------------------------------------
45 #if SMTG_OS_LINUX
47 //------------------------------------------------------------------------
48 namespace {
50 using Converter = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>;
52 //------------------------------------------------------------------------
53 Converter& converter ()
55 static Converter instance;
56 return instance;
59 //------------------------------------------------------------------------
60 } // anonymous
62 //------------------------------------------------------------------------
63 #endif // SMTG_OS_LINUX
65 //------------------------------------------------------------------------
66 /** Copy strings of different character width. */
67 //------------------------------------------------------------------------
68 template <class TDstChar, class TSrcChar>
69 void StringCopy (TDstChar* dst, int32 dstSize, const TSrcChar* src, int32 srcSize = -1)
71 int32 count = dstSize;
72 if (srcSize >= 0 && srcSize < dstSize)
73 count = srcSize;
74 for (int32 i = 0; i < count; i++)
76 dst[i] = (TDstChar)src[i];
77 if (src[i] == 0)
78 break;
80 dst[dstSize - 1] = 0;
83 //------------------------------------------------------------------------
84 /** Find length of null-terminated string, i.e. StringLength (L"ABC\0") => 3 */
85 //------------------------------------------------------------------------
86 template <class TSrcChar>
87 int32 StringLength (const TSrcChar* src, int32 srcSize = -1)
89 if (srcSize == 0)
90 return 0;
91 int32 length = 0;
92 while (src[length])
94 length++;
95 if (srcSize > 0 && length >= srcSize)
96 break;
98 return length;
101 //------------------------------------------------------------------------
102 // UString
103 //------------------------------------------------------------------------
104 int32 UString::getLength () const
106 return StringLength<char16> (thisBuffer, thisSize);
109 //------------------------------------------------------------------------
110 UString& UString::assign (const char16* src, int32 srcSize)
112 StringCopy<char16, char16> (thisBuffer, thisSize, src, srcSize);
113 return *this;
116 //------------------------------------------------------------------------
117 UString& UString::append (const char16* src, int32 srcSize)
119 int32 length = getLength ();
120 StringCopy<char16, char16> (thisBuffer + length, thisSize - length, src, srcSize);
121 return *this;
124 //------------------------------------------------------------------------
125 const UString& UString::copyTo (char16* dst, int32 dstSize) const
127 StringCopy<char16, char16> (dst, dstSize, thisBuffer, thisSize);
128 return *this;
131 //------------------------------------------------------------------------
132 UString& UString::fromAscii (const char* src, int32 srcSize)
134 StringCopy<char16, char> (thisBuffer, thisSize, src, srcSize);
135 return *this;
138 //------------------------------------------------------------------------
139 const UString& UString::toAscii (char* dst, int32 dstSize) const
141 StringCopy<char, char16> (dst, dstSize, thisBuffer, thisSize);
142 return *this;
145 //------------------------------------------------------------------------
146 bool UString::scanFloat (double& value) const
148 #if SMTG_OS_WINDOWS
149 return swscanf ((const wchar_t*)thisBuffer, L"%lf", &value) != -1;
151 #elif TARGET_API_MAC_CARBON
152 CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
153 if (cfStr)
155 value = CFStringGetDoubleValue (cfStr);
156 CFRelease (cfStr);
157 return true;
159 return false;
161 #elif SMTG_OS_LINUX
162 auto str = converter ().to_bytes (thisBuffer);
163 return sscanf (str.data (), "%lf", &value) == 1;
165 #else
166 #warning Implement me
167 // implement me!
168 return false;
169 #endif
172 //------------------------------------------------------------------------
173 bool UString::printFloat (double value, int32 precision)
175 #if SMTG_OS_WINDOWS
176 return swprintf ((wchar_t*)thisBuffer, L"%.*lf", precision, value) != -1;
177 #elif SMTG_OS_MACOS
178 bool result = false;
179 CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%.*lf"), precision, value);
180 if (cfStr)
182 memset (thisBuffer, 0, thisSize);
183 CFRange range = {0, CFStringGetLength (cfStr)};
184 CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
185 CFRelease (cfStr);
186 return true;
188 return result;
189 #elif SMTG_OS_LINUX
190 auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
191 auto len = snprintf (utf8Buffer, thisSize, "%.*lf", precision, value);
192 if (len > 0)
194 auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
195 utf16Buffer[len] = 0;
196 while (--len >= 0)
198 utf16Buffer[len] = utf8Buffer[len];
200 return true;
202 return false;
203 #else
204 #warning Implement me
205 // implement me!
206 return false;
207 #endif
210 //------------------------------------------------------------------------
211 bool UString::scanInt (int64& value) const
213 #if SMTG_OS_WINDOWS
214 return swscanf ((const wchar_t*)thisBuffer, L"%I64d", &value) != -1;
216 #elif SMTG_OS_MACOS
217 CFStringRef cfStr = CFStringCreateWithBytes (0, (const UInt8 *)thisBuffer, getLength () * 2, kCFStringEncodingUTF16, false);
218 if (cfStr)
220 value = CFStringGetIntValue (cfStr);
221 CFRelease (cfStr);
222 return true;
224 return false;
226 #elif SMTG_OS_LINUX
227 auto str = converter ().to_bytes (thisBuffer);
228 return sscanf (str.data (), "%lld", &value) == 1;
230 #else
231 #warning Implement me
232 // implement me!
233 return false;
234 #endif
237 //------------------------------------------------------------------------
238 bool UString::printInt (int64 value)
240 #if SMTG_OS_WINDOWS
241 return swprintf ((wchar_t*)thisBuffer, L"%I64d", value) != -1;
243 #elif SMTG_OS_MACOS
244 CFStringRef cfStr = CFStringCreateWithFormat (0, 0, CFSTR("%lld"), value);
245 if (cfStr)
247 memset (thisBuffer, 0, thisSize);
248 CFRange range = {0, CFStringGetLength (cfStr)};
249 CFStringGetBytes (cfStr, range, kCFStringEncodingUTF16, 0, false, (UInt8*)thisBuffer, thisSize, 0);
250 CFRelease (cfStr);
251 return true;
253 return false;
254 #elif SMTG_OS_LINUX
255 auto utf8Buffer = reinterpret_cast<char*> (thisBuffer);
256 auto len = snprintf (utf8Buffer, thisSize, "%lld", value);
257 if (len > 0)
259 auto utf16Buffer = reinterpret_cast<char16*> (thisBuffer);
260 utf16Buffer[len] = 0;
261 while (--len >= 0)
263 utf16Buffer[len] = utf8Buffer[len];
265 return true;
267 return false;
269 #else
270 #warning Implement me
271 // implement me!
272 return false;
273 #endif
275 } // namespace Steinberg