1 /*
   2  * Copyright (c) 2014, 2018, 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 #ifndef PLATFORMSTRING_H
  27 #define PLATFORMSTRING_H
  28 
  29 
  30 #include <string>
  31 #include <list>
  32 #include <stdio.h>
  33 #include <stdlib.h>
  34 
  35 #include "jni.h"
  36 #include "Platform.h"
  37 
  38 
  39 struct WideString {
  40     size_t length;
  41     wchar_t* data;
  42 
  43     WideString() { length = 0; data = NULL; }
  44 };
  45 
  46 struct MultibyteString {
  47     size_t length;
  48     char* data;
  49 
  50     MultibyteString() { length = 0; data = NULL; }
  51 };
  52 
  53 
  54 template <typename T>
  55 class DynamicBuffer {
  56 private:
  57     T* FData;
  58     size_t FSize;
  59 
  60 public:
  61     DynamicBuffer(size_t Size) {
  62         FSize = 0;
  63         FData = NULL;
  64         Resize(Size);
  65     }
  66 
  67     ~DynamicBuffer() {
  68         delete[] FData;
  69     }
  70 
  71     T* GetData() { return FData; }
  72     size_t GetSize() { return FSize; }
  73 
  74     bool Resize(size_t Size) {
  75         FSize = Size;
  76 
  77         if (FData != NULL) {
  78             delete[] FData;
  79             FData = NULL;
  80         }
  81 
  82         if (FSize != 0) {
  83             FData = new T[FSize];
  84             if (FData != NULL) {
  85                 Zero();
  86             } else {
  87                 return false;
  88             }
  89         }
  90 
  91         return true;
  92     }
  93 
  94     void Zero() {
  95         memset(FData, 0, FSize * sizeof(T));
  96     }
  97 
  98     T& operator[](size_t index) {
  99         return FData[index];
 100     }
 101 };
 102 
 103 
 104 #ifdef MAC
 105 // StringToFileSystemString is a stack object. It's usage is
 106 // simply inline to convert a
 107 // TString to a file system string. Example:
 108 //
 109 // return dlopen(StringToFileSystemString(FileName), RTLD_LAZY);
 110 //
 111 class StringToFileSystemString {
 112     // Prohibit Heap-Based StringToFileSystemString
 113 private:
 114     static void *operator new(size_t size);
 115     static void operator delete(void *ptr);
 116 
 117 private:
 118     TCHAR* FData;
 119     bool FRelease;
 120 
 121 public:
 122     StringToFileSystemString(const TString &value);
 123     ~StringToFileSystemString();
 124 
 125     operator TCHAR* ();
 126 };
 127 
 128 
 129 // FileSystemStringToString is a stack object. It's usage is
 130 // simply inline to convert a
 131 // file system string to a TString. Example:
 132 //
 133 // DynamicBuffer<TCHAR> buffer(MAX_PATH);
 134 // if (readlink("/proc/self/exe", buffer.GetData(), MAX_PATH) != -1)
 135 //    result = FileSystemStringToString(buffer.GetData());
 136 //
 137 class FileSystemStringToString {
 138     // Prohibit Heap-Based FileSystemStringToString
 139 private:
 140     static void *operator new(size_t size);
 141     static void operator delete(void *ptr);
 142 
 143 private:
 144     TString FData;
 145 
 146 public:
 147     FileSystemStringToString(const TCHAR* value);
 148 
 149     operator TString ();
 150 };
 151 #endif //MAC
 152 
 153 #ifdef LINUX
 154 #define StringToFileSystemString PlatformString
 155 #define FileSystemStringToString PlatformString
 156 #endif //LINUX
 157 
 158 
 159 class PlatformString {
 160 private:
 161     char* FData; // Stored as UTF-8
 162     size_t FLength;
 163     wchar_t* FWideTStringToFree;
 164 
 165     void initialize();
 166 
 167     // Caller must free result using delete[].
 168     static void CopyString(char *Destination,
 169             size_t NumberOfElements, const char *Source);
 170 
 171     // Caller must free result using delete[].
 172     static void CopyString(wchar_t *Destination,
 173             size_t NumberOfElements, const wchar_t *Source);
 174 
 175     static WideString MultibyteStringToWideString(const char* value);
 176     static MultibyteString WideStringToMultibyteString(const wchar_t* value);
 177 
 178 // Prohibit Heap-Based PlatformStrings
 179 private:
 180     static void *operator new(size_t size);
 181     static void operator delete(void *ptr);
 182 
 183 public:
 184     PlatformString(void);
 185     PlatformString(const PlatformString &value);
 186     PlatformString(const char* value);
 187     PlatformString(const wchar_t* value);
 188     PlatformString(const std::string &value);
 189     PlatformString(const std::wstring &value);
 190     PlatformString(JNIEnv *env, jstring value);
 191     PlatformString(size_t Value);
 192 
 193     static TString Format(const TString value, ...);
 194 
 195     ~PlatformString(void);
 196 
 197     size_t length();
 198 
 199     char* c_str();
 200     char* toMultibyte();
 201     wchar_t* toWideString();
 202     std::wstring toUnicodeString();
 203     std::string toStdString();
 204     jstring toJString(JNIEnv *env);
 205     TCHAR* toPlatformString();
 206     TString toString();
 207 
 208     operator char* ();
 209     operator wchar_t* ();
 210     operator std::wstring ();
 211 
 212     // Caller must free result using delete[].
 213     static char* duplicate(const char* Value);
 214 
 215     // Caller must free result using delete[].
 216     static wchar_t* duplicate(const wchar_t* Value);
 217 };
 218 
 219 
 220 #endif // PLATFORMSTRING_H