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 "Helpers.h"
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <stdlib.h>
  33 #include <memory.h>
  34 #include <sstream>
  35 #include <string.h>
  36 
  37 #include "jni.h"
  38 
  39 void PlatformString::initialize() {
  40     FWideTStringToFree = NULL;
  41     FLength = 0;
  42     FData = NULL;
  43 }
  44 
  45 PlatformString::PlatformString(void) {
  46     initialize();
  47 }
  48 
  49 PlatformString::~PlatformString(void) {
  50     if (FData != NULL) {
  51         delete[] FData;
  52     }
  53 
  54     if (FWideTStringToFree != NULL) {
  55         delete[] FWideTStringToFree;
  56     }
  57 }
  58 
  59 PlatformString::PlatformString(const PlatformString &value) {
  60     initialize();
  61     FLength = value.FLength;
  62     FData = new char[FLength + 1];
  63     Platform::CopyString(FData, FLength + 1, value.FData);
  64 }
  65 
  66 PlatformString::PlatformString(const char* value) {
  67     initialize();
  68     FLength = strlen(value);
  69     FData = new char[FLength + 1];
  70     Platform::CopyString(FData, FLength + 1, value);
  71 }
  72 
  73 PlatformString::PlatformString(size_t Value) {
  74     initialize();
  75 
  76     std::stringstream ss;
  77     std::string s;
  78     ss << Value;
  79     s = ss.str();
  80 
  81     FLength = strlen(s.c_str());
  82     FData = new char[FLength + 1];
  83     Platform::CopyString(FData, FLength + 1, s.c_str());
  84 }
  85 
  86 PlatformString::PlatformString(const wchar_t* value) {
  87     initialize();
  88     MultibyteString temp = Platform::WideStringToMultibyteString(value);
  89     FLength = temp.length;
  90     FData = temp.data;
  91 }
  92 
  93 PlatformString::PlatformString(const std::string &value) {
  94     initialize();
  95     const char* lvalue = value.data();
  96     FLength = value.size();
  97     FData = new char[FLength + 1];
  98     Platform::CopyString(FData, FLength + 1, lvalue);
  99 }
 100 
 101 PlatformString::PlatformString(const std::wstring &value) {
 102     initialize();
 103     const wchar_t* lvalue = value.data();
 104     MultibyteString temp = Platform::WideStringToMultibyteString(lvalue);
 105     FLength = temp.length;
 106     FData = temp.data;
 107 }
 108 
 109 TString PlatformString::Format(const TString value, ...) {
 110     TString result = value;
 111 
 112     va_list arglist;
 113     va_start(arglist, value);
 114 
 115     while (1) {
 116         size_t pos = result.find(_T("%s"), 0);
 117 
 118         if (pos == TString::npos) {
 119             break;
 120         }
 121         else {
 122             TCHAR* arg = va_arg(arglist, TCHAR*);
 123 
 124             if (arg == NULL) {
 125                 break;
 126             }
 127             else {
 128                 result.replace(pos, StringLength(_T("%s")), arg);
 129             }
 130         }
 131     }
 132 
 133     va_end(arglist);
 134 
 135     return result;
 136 }
 137 
 138 size_t PlatformString::length() {
 139     return FLength;
 140 }
 141 
 142 char* PlatformString::c_str() {
 143     return FData;
 144 }
 145 
 146 char* PlatformString::toMultibyte() {
 147     return FData;
 148 }
 149 
 150 wchar_t* PlatformString::toWideString() {
 151     WideString result = Platform::MultibyteStringToWideString(FData);
 152 
 153     if (result.data != NULL) {
 154         if (FWideTStringToFree != NULL) {
 155             delete [] FWideTStringToFree;
 156         }
 157 
 158         FWideTStringToFree = result.data;
 159     }
 160 
 161     return result.data;
 162 }
 163 
 164 std::wstring PlatformString::toUnicodeString() {
 165     std::wstring result;
 166     wchar_t* data = toWideString();
 167 
 168     if (FLength != 0 && data != NULL) {
 169         // NOTE: Cleanup of result is handled by PlatformString destructor.
 170         result = data;
 171     }
 172 
 173     return result;
 174 }
 175 
 176 std::string PlatformString::toStdString() {
 177     std::string result;
 178     char* data = toMultibyte();
 179 
 180     if (FLength > 0 && data != NULL) {
 181         result = data;
 182     }
 183 
 184     return result;
 185 }
 186 
 187 TCHAR* PlatformString::toPlatformString() {
 188 #ifdef _UNICODE
 189     return toWideString();
 190 #else
 191     return c_str();
 192 #endif //_UNICODE
 193 }
 194 
 195 TString PlatformString::toString() {
 196 #ifdef _UNICODE
 197     return toUnicodeString();
 198 #else
 199     return toStdString();
 200 #endif //_UNICODE
 201 }
 202 
 203 PlatformString::operator char* () {
 204     return c_str();
 205 }
 206 
 207 PlatformString::operator wchar_t* () {
 208     return toWideString();
 209 }
 210 
 211 PlatformString::operator std::wstring () {
 212     return toUnicodeString();
 213 }
 214 
 215 char* PlatformString::duplicate(const char* Value) {
 216     size_t length = strlen(Value);
 217     char* result = new char[length + 1];
 218     Platform::CopyString(result, length + 1, Value);
 219     return result;
 220 }
 221 
 222 wchar_t* PlatformString::duplicate(const wchar_t* Value) {
 223     size_t length = wcslen(Value);
 224     wchar_t* result = new wchar_t[length + 1];
 225     Platform::CopyString(result, length + 1, Value);
 226     return result;
 227 }