1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This file is available and licensed under the following license: 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the distribution. 16 * - Neither the name of Oracle Corporation nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 34 #include "PlatformString.h" 35 36 #include "Java.h" 37 #include "Helpers.h" 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <stdlib.h> 42 #include <memory.h> 43 #include <sstream> 44 #include <string.h> 45 46 #include "jni.h" 47 48 //-------------------------------------------------------------------------------------------------- 49 50 #ifdef MAC 51 StringToFileSystemString::StringToFileSystemString(const TString &value) { 52 FRelease = false; 53 PlatformString lvalue = PlatformString(value); 54 Platform& platform = Platform::GetInstance(); 55 FData = platform.ConvertStringToFileSystemString(lvalue, FRelease); 56 } 57 58 StringToFileSystemString::~StringToFileSystemString() { 59 if (FRelease == true) { 60 delete[] FData; 61 } 62 } 63 64 StringToFileSystemString::operator TCHAR* () { 65 return FData; 66 } 67 #endif //MAC 68 69 //-------------------------------------------------------------------------------------------------- 70 71 #ifdef MAC 72 FileSystemStringToString::FileSystemStringToString(const TCHAR* value) { 73 bool release = false; 74 PlatformString lvalue = PlatformString(value); 75 Platform& platform = Platform::GetInstance(); 76 TCHAR* buffer = platform.ConvertFileSystemStringToString(lvalue, release); 77 FData = buffer; 78 79 if (buffer != NULL && release == true) { 80 delete[] buffer; 81 } 82 } 83 84 FileSystemStringToString::operator TString () { 85 return FData; 86 } 87 #endif //MAC 88 89 90 //-------------------------------------------------------------------------------------------------- 91 92 93 void PlatformString::initialize() { 94 FWideTStringToFree = NULL; 95 FLength = 0; 96 FData = NULL; 97 } 98 99 void PlatformString::CopyString(char *Destination, size_t NumberOfElements, const char *Source) { 100 #ifdef WINDOWS 101 strcpy_s(Destination, NumberOfElements, Source); 102 #endif //WINDOWS 103 #ifdef POSIX 104 strncpy(Destination, Source, NumberOfElements); 105 #endif //POSIX 106 107 if (NumberOfElements > 0) { 108 Destination[NumberOfElements - 1] = '\0'; 109 } 110 } 111 112 void PlatformString::CopyString(wchar_t *Destination, size_t NumberOfElements, const wchar_t *Source) { 113 #ifdef WINDOWS 114 wcscpy_s(Destination, NumberOfElements, Source); 115 #endif //WINDOWS 116 #ifdef POSIX 117 wcsncpy(Destination, Source, NumberOfElements); 118 #endif //POSIX 119 120 if (NumberOfElements > 0) { 121 Destination[NumberOfElements - 1] = '\0'; 122 } 123 } 124 125 PlatformString::PlatformString(void) { 126 initialize(); 127 } 128 129 PlatformString::~PlatformString(void) { 130 if (FData != NULL) { 131 delete[] FData; 132 } 133 134 if (FWideTStringToFree != NULL) { 135 delete[] FWideTStringToFree; 136 } 137 } 138 139 // Owner must free the return value. 140 MultibyteString PlatformString::WideStringToMultibyteString(const wchar_t* value) { 141 MultibyteString result; 142 size_t count = 0; 143 144 #ifdef WINDOWS 145 wcstombs_s(&count, NULL, 0, value, 0); 146 147 if (count > 0) { 148 result.data = new char[count + 1]; 149 wcstombs_s(&result.length, result.data, count, value, count); 150 151 #endif //WINDOWS 152 #ifdef POSIX 153 count = wcstombs(NULL, value, 0); 154 155 if (count > 0) { 156 result.data = new char[count + 1]; 157 result.data[count] = '\0'; 158 result.length = count; 159 wcstombs(result.data, value, count); 160 #endif //POSIX 161 } 162 163 return result; 164 } 165 166 // Owner must free the return value. 167 WideString PlatformString::MultibyteStringToWideString(const char* value) { 168 WideString result; 169 size_t count = 0; 170 171 #ifdef WINDOWS 172 mbstowcs_s(&count, NULL, 0, value, _TRUNCATE); 173 174 if (count > 0) { 175 result.data = new wchar_t[count + 1]; 176 mbstowcs_s(&result.length, result.data, count, value, count); 177 #endif // WINDOWS 178 #ifdef POSIX 179 count = mbstowcs(NULL, value, 0); 180 181 if (count > 0) { 182 result.data = new wchar_t[count + 1]; 183 result.data[count] = '\0'; 184 result.length = count; 185 mbstowcs(result.data, value, count); 186 #endif //POSIX 187 } 188 189 return result; 190 } 191 192 PlatformString::PlatformString(const PlatformString &value) { 193 initialize(); 194 FLength = value.FLength; 195 FData = new char[FLength + 1]; 196 PlatformString::CopyString(FData, FLength + 1, value.FData); 197 } 198 199 PlatformString::PlatformString(const char* value) { 200 initialize(); 201 FLength = strlen(value); 202 FData = new char[FLength + 1]; 203 PlatformString::CopyString(FData, FLength + 1, value); 204 } 205 206 PlatformString::PlatformString(size_t Value) { 207 initialize(); 208 209 std::stringstream ss; 210 std::string s; 211 ss << Value; 212 s = ss.str(); 213 214 FLength = strlen(s.c_str()); 215 FData = new char[FLength + 1]; 216 PlatformString::CopyString(FData, FLength + 1, s.c_str()); 217 } 218 219 PlatformString::PlatformString(const wchar_t* value) { 220 initialize(); 221 MultibyteString temp = WideStringToMultibyteString(value); 222 FLength = temp.length; 223 FData = temp.data; 224 } 225 226 PlatformString::PlatformString(const std::string &value) { 227 initialize(); 228 const char* lvalue = value.data(); 229 FLength = value.size(); 230 FData = new char[FLength + 1]; 231 PlatformString::CopyString(FData, FLength + 1, lvalue); 232 } 233 234 PlatformString::PlatformString(const std::wstring &value) { 235 initialize(); 236 const wchar_t* lvalue = value.data(); 237 MultibyteString temp = WideStringToMultibyteString(lvalue); 238 FLength = temp.length; 239 FData = temp.data; 240 } 241 242 PlatformString::PlatformString(JNIEnv *env, jstring value) { 243 initialize(); 244 245 if (env != NULL) { 246 const char* lvalue = env->GetStringUTFChars(value, JNI_FALSE); 247 248 if (lvalue == NULL || env->ExceptionCheck() == JNI_TRUE) { 249 throw JavaException(); 250 } 251 252 if (lvalue != NULL) { 253 FLength = env->GetStringUTFLength(value); 254 255 if (env->ExceptionCheck() == JNI_TRUE) { 256 throw JavaException(); 257 } 258 259 FData = new char[FLength + 1]; 260 PlatformString::CopyString(FData, FLength + 1, lvalue); 261 262 env->ReleaseStringUTFChars(value, lvalue); 263 264 if (env->ExceptionCheck() == JNI_TRUE) { 265 throw JavaException(); 266 } 267 } 268 } 269 } 270 271 std::string PlatformString::Format(std::string value, ...) { 272 std::string result = value; 273 274 va_list arglist; 275 va_start(arglist, value); 276 277 while (1) { 278 size_t pos = result.find("%s", 0); 279 280 if (pos == TString::npos) { 281 break; 282 } 283 else { 284 char* arg = va_arg(arglist, char*); 285 286 if (arg == NULL) { 287 break; 288 } 289 else { 290 result.replace(pos, strlen("%s"), arg); 291 } 292 } 293 } 294 295 va_end(arglist); 296 297 return result; 298 } 299 300 size_t PlatformString::length() { 301 return FLength; 302 } 303 304 char* PlatformString::c_str() { 305 return FData; 306 } 307 308 char* PlatformString::toMultibyte() { 309 return FData; 310 } 311 312 wchar_t* PlatformString::toWideString() { 313 WideString result = MultibyteStringToWideString(FData); 314 315 if (result.data != NULL) { 316 if (FWideTStringToFree != NULL) { 317 delete [] FWideTStringToFree; 318 } 319 320 FWideTStringToFree = result.data; 321 } 322 323 return result.data; 324 } 325 326 std::wstring PlatformString::toUnicodeString() { 327 std::wstring result; 328 wchar_t* data = toWideString(); 329 330 if (FLength != 0 && data != NULL) { 331 // NOTE: Cleanup of result is handled by PlatformString destructor. 332 result = data; 333 } 334 335 return result; 336 } 337 338 std::string PlatformString::toStdString() { 339 std::string result; 340 char* data = toMultibyte(); 341 342 if (FLength > 0 && data != NULL) { 343 result = data; 344 } 345 346 return result; 347 } 348 349 jstring PlatformString::toJString(JNIEnv *env) { 350 jstring result = NULL; 351 352 if (env != NULL) { 353 result = env->NewStringUTF(c_str()); 354 355 if (result == NULL || env->ExceptionCheck() == JNI_TRUE) { 356 throw JavaException(); 357 } 358 } 359 360 return result; 361 } 362 363 TCHAR* PlatformString::toPlatformString() { 364 #ifdef _UNICODE 365 return toWideString(); 366 #else 367 return c_str(); 368 #endif //_UNICODE 369 } 370 371 TString PlatformString::toString() { 372 #ifdef _UNICODE 373 return toUnicodeString(); 374 #else 375 return toStdString(); 376 #endif //_UNICODE 377 } 378 379 PlatformString::operator char* () { 380 return c_str(); 381 } 382 383 PlatformString::operator wchar_t* () { 384 return toWideString(); 385 } 386 387 PlatformString::operator std::wstring () { 388 return toUnicodeString(); 389 } 390 391 char* PlatformString::duplicate(const char* Value) { 392 size_t length = strlen(Value); 393 char* result = new char[length + 1]; 394 PlatformString::CopyString(result, length + 1, Value); 395 return result; 396 } 397 398 wchar_t* PlatformString::duplicate(const wchar_t* Value) { 399 size_t length = wcslen(Value); 400 wchar_t* result = new wchar_t[length + 1]; 401 PlatformString::CopyString(result, length + 1, Value); 402 return result; 403 }