1 /* 2 * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include "PlatformString.h" 27 28 #include "JavaTypes.h" 29 #include "Helpers.h" 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <stdlib.h> 34 #include <memory.h> 35 #include <sstream> 36 #include <string.h> 37 38 #include "jni.h" 39 40 #ifdef MAC 41 StringToFileSystemString::StringToFileSystemString(const TString &value) { 42 FRelease = false; 43 PlatformString lvalue = PlatformString(value); 44 Platform& platform = Platform::GetInstance(); 45 FData = platform.ConvertStringToFileSystemString(lvalue, FRelease); 46 } 47 48 StringToFileSystemString::~StringToFileSystemString() { 49 if (FRelease == true) { 50 delete[] FData; 51 } 52 } 53 54 StringToFileSystemString::operator TCHAR* () { 55 return FData; 56 } 57 #endif //MAC 58 59 #ifdef MAC 60 FileSystemStringToString::FileSystemStringToString(const TCHAR* value) { 61 bool release = false; 62 PlatformString lvalue = PlatformString(value); 63 Platform& platform = Platform::GetInstance(); 64 TCHAR* buffer = platform.ConvertFileSystemStringToString(lvalue, release); 65 FData = buffer; 66 67 if (buffer != NULL && release == true) { 68 delete[] buffer; 69 } 70 } 71 72 FileSystemStringToString::operator TString () { 73 return FData; 74 } 75 #endif //MAC 76 77 78 void PlatformString::initialize() { 79 FWideTStringToFree = NULL; 80 FLength = 0; 81 FData = NULL; 82 } 83 84 void PlatformString::CopyString(char *Destination, 85 size_t NumberOfElements, const char *Source) { 86 #ifdef WINDOWS 87 strcpy_s(Destination, NumberOfElements, Source); 88 #endif //WINDOWS 89 #ifdef POSIX 90 strncpy(Destination, Source, NumberOfElements); 91 #endif //POSIX 92 93 if (NumberOfElements > 0) { 94 Destination[NumberOfElements - 1] = '\0'; 95 } 96 } 97 98 void PlatformString::CopyString(wchar_t *Destination, 99 size_t NumberOfElements, const wchar_t *Source) { 100 #ifdef WINDOWS 101 wcscpy_s(Destination, NumberOfElements, Source); 102 #endif //WINDOWS 103 #ifdef POSIX 104 wcsncpy(Destination, Source, NumberOfElements); 105 #endif //POSIX 106 107 if (NumberOfElements > 0) { 108 Destination[NumberOfElements - 1] = '\0'; 109 } 110 } 111 112 PlatformString::PlatformString(void) { 113 initialize(); 114 } 115 116 PlatformString::~PlatformString(void) { 117 if (FData != NULL) { 118 delete[] FData; 119 } 120 121 if (FWideTStringToFree != NULL) { 122 delete[] FWideTStringToFree; 123 } 124 } 125 126 // Owner must free the return value. 127 MultibyteString PlatformString::WideStringToMultibyteString( 128 const wchar_t* value) { 129 MultibyteString result; 130 size_t count = 0; 131 132 if (value == NULL) { 133 return result; 134 } 135 136 #ifdef WINDOWS 137 count = WideCharToMultiByte(CP_UTF8, 0, value, -1, NULL, 0, NULL, NULL); 138 139 if (count > 0) { 140 result.data = new char[count + 1]; 141 result.length = WideCharToMultiByte(CP_UTF8, 0, value, -1, 142 result.data, (int)count, NULL, NULL); 143 #endif //WINDOWS 144 145 #ifdef POSIX 146 count = wcstombs(NULL, value, 0); 147 148 if (count > 0) { 149 result.data = new char[count + 1]; 150 result.data[count] = '\0'; 151 result.length = count; 152 wcstombs(result.data, value, count); 153 #endif //POSIX 154 } 155 156 return result; 157 } 158 159 // Owner must free the return value. 160 WideString PlatformString::MultibyteStringToWideString(const char* value) { 161 WideString result; 162 size_t count = 0; 163 164 if (value == NULL) { 165 return result; 166 } 167 168 #ifdef WINDOWS 169 mbstowcs_s(&count, NULL, 0, value, _TRUNCATE); 170 171 if (count > 0) { 172 result.data = new wchar_t[count + 1]; 173 mbstowcs_s(&result.length, result.data, count, value, count); 174 #endif // WINDOWS 175 #ifdef POSIX 176 count = mbstowcs(NULL, value, 0); 177 178 if (count > 0) { 179 result.data = new wchar_t[count + 1]; 180 result.data[count] = '\0'; 181 result.length = count; 182 mbstowcs(result.data, value, count); 183 #endif //POSIX 184 } 185 186 return result; 187 } 188 189 PlatformString::PlatformString(const PlatformString &value) { 190 initialize(); 191 FLength = value.FLength; 192 FData = new char[FLength + 1]; 193 PlatformString::CopyString(FData, FLength + 1, value.FData); 194 } 195 196 PlatformString::PlatformString(const char* value) { 197 initialize(); 198 FLength = strlen(value); 199 FData = new char[FLength + 1]; 200 PlatformString::CopyString(FData, FLength + 1, value); 201 } 202 203 PlatformString::PlatformString(size_t Value) { 204 initialize(); 205 206 std::stringstream ss; 207 std::string s; 208 ss << Value; 209 s = ss.str(); 210 211 FLength = strlen(s.c_str()); 212 FData = new char[FLength + 1]; 213 PlatformString::CopyString(FData, FLength + 1, s.c_str()); 214 } 215 216 PlatformString::PlatformString(const wchar_t* value) { 217 initialize(); 218 MultibyteString temp = WideStringToMultibyteString(value); 219 FLength = temp.length; 220 FData = temp.data; 221 } 222 223 PlatformString::PlatformString(const std::string &value) { 224 initialize(); 225 const char* lvalue = value.data(); 226 FLength = value.size(); 227 FData = new char[FLength + 1]; 228 PlatformString::CopyString(FData, FLength + 1, lvalue); 229 } 230 231 PlatformString::PlatformString(const std::wstring &value) { 232 initialize(); 233 const wchar_t* lvalue = value.data(); 234 MultibyteString temp = WideStringToMultibyteString(lvalue); 235 FLength = temp.length; 236 FData = temp.data; 237 } 238 239 PlatformString::PlatformString(JNIEnv *env, jstring value) { 240 initialize(); 241 242 if (env != NULL) { 243 const char* lvalue = env->GetStringUTFChars(value, JNI_FALSE); 244 245 if (lvalue == NULL || env->ExceptionCheck() == JNI_TRUE) { 246 throw JavaException(); 247 } 248 249 if (lvalue != NULL) { 250 FLength = env->GetStringUTFLength(value); 251 252 if (env->ExceptionCheck() == JNI_TRUE) { 253 throw JavaException(); 254 } 255 256 FData = new char[FLength + 1]; 257 PlatformString::CopyString(FData, FLength + 1, lvalue); 258 259 env->ReleaseStringUTFChars(value, lvalue); 260 261 if (env->ExceptionCheck() == JNI_TRUE) { 262 throw JavaException(); 263 } 264 } 265 } 266 } 267 268 TString PlatformString::Format(const TString value, ...) { 269 TString result = value; 270 271 va_list arglist; 272 va_start(arglist, value); 273 274 while (1) { 275 size_t pos = result.find(_T("%s"), 0); 276 277 if (pos == TString::npos) { 278 break; 279 } 280 else { 281 TCHAR* arg = va_arg(arglist, TCHAR*); 282 283 if (arg == NULL) { 284 break; 285 } 286 else { 287 result.replace(pos, StringLength(_T("%s")), arg); 288 } 289 } 290 } 291 292 va_end(arglist); 293 294 return result; 295 } 296 297 size_t PlatformString::length() { 298 return FLength; 299 } 300 301 char* PlatformString::c_str() { 302 return FData; 303 } 304 305 char* PlatformString::toMultibyte() { 306 return FData; 307 } 308 309 wchar_t* PlatformString::toWideString() { 310 WideString result = MultibyteStringToWideString(FData); 311 312 if (result.data != NULL) { 313 if (FWideTStringToFree != NULL) { 314 delete [] FWideTStringToFree; 315 } 316 317 FWideTStringToFree = result.data; 318 } 319 320 return result.data; 321 } 322 323 std::wstring PlatformString::toUnicodeString() { 324 std::wstring result; 325 wchar_t* data = toWideString(); 326 327 if (FLength != 0 && data != NULL) { 328 // NOTE: Cleanup of result is handled by PlatformString destructor. 329 result = data; 330 } 331 332 return result; 333 } 334 335 std::string PlatformString::toStdString() { 336 std::string result; 337 char* data = toMultibyte(); 338 339 if (FLength > 0 && data != NULL) { 340 result = data; 341 } 342 343 return result; 344 } 345 346 jstring PlatformString::toJString(JNIEnv *env) { 347 jstring result = NULL; 348 349 if (env != NULL) { 350 result = env->NewStringUTF(c_str()); 351 352 if (result == NULL || env->ExceptionCheck() == JNI_TRUE) { 353 throw JavaException(); 354 } 355 } 356 357 return result; 358 } 359 360 TCHAR* PlatformString::toPlatformString() { 361 #ifdef _UNICODE 362 return toWideString(); 363 #else 364 return c_str(); 365 #endif //_UNICODE 366 } 367 368 TString PlatformString::toString() { 369 #ifdef _UNICODE 370 return toUnicodeString(); 371 #else 372 return toStdString(); 373 #endif //_UNICODE 374 } 375 376 PlatformString::operator char* () { 377 return c_str(); 378 } 379 380 PlatformString::operator wchar_t* () { 381 return toWideString(); 382 } 383 384 PlatformString::operator std::wstring () { 385 return toUnicodeString(); 386 } 387 388 char* PlatformString::duplicate(const char* Value) { 389 size_t length = strlen(Value); 390 char* result = new char[length + 1]; 391 PlatformString::CopyString(result, length + 1, Value); 392 return result; 393 } 394 395 wchar_t* PlatformString::duplicate(const wchar_t* Value) { 396 size_t length = wcslen(Value); 397 wchar_t* result = new wchar_t[length + 1]; 398 PlatformString::CopyString(result, length + 1, Value); 399 return result; 400 }