FreeRDP
Loading...
Searching...
No Matches
android_jni_utils.c
1
13#include "android_jni_utils.h"
14
15#include <locale.h>
16#include <freerdp/channels/channels.h>
17#include <freerdp/log.h>
18
19#include "android_jni_callback.h"
20
21#define TAG CLIENT_TAG("android.utils")
22
23JavaVM* g_JavaVm;
24
25JavaVM* getJavaVM()
26{
27 return g_JavaVm;
28}
29
30JNIEnv* getJNIEnv()
31{
32 JNIEnv* env = NULL;
33 if ((*g_JavaVm)->GetEnv(g_JavaVm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)
34 {
35 WLog_FATAL(TAG, "Failed to obtain JNIEnv");
36 return NULL;
37 }
38 return env;
39}
40
41jobject create_string_builder(JNIEnv* env, char* initialStr)
42{
43 jclass cls;
44 jmethodID methodId;
45 jobject obj;
46
47 // get class
48 cls = (*env)->FindClass(env, "java/lang/StringBuilder");
49 if (!cls)
50 return NULL;
51
52 if (initialStr)
53 {
54 // get method id for constructor
55 methodId = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V");
56 if (!methodId)
57 return NULL;
58
59 // create string that holds our initial string
60 jstring jstr = (*env)->NewStringUTF(env, initialStr);
61
62 // construct new StringBuilder
63 obj = (*env)->NewObject(env, cls, methodId, jstr);
64 }
65 else
66 {
67 // get method id for constructor
68 methodId = (*env)->GetMethodID(env, cls, "<init>", "()V");
69 if (!methodId)
70 return NULL;
71
72 // construct new StringBuilder
73 obj = (*env)->NewObject(env, cls, methodId);
74 }
75
76 return obj;
77}
78
79char* get_string_from_string_builder(JNIEnv* env, jobject strBuilder)
80{
81 jclass cls;
82 jmethodID methodId;
83 jstring strObj;
84 const char* native_str;
85 char* result;
86
87 // get class
88 cls = (*env)->FindClass(env, "java/lang/StringBuilder");
89 if (!cls)
90 return NULL;
91
92 // get method id for constructor
93 methodId = (*env)->GetMethodID(env, cls, "toString", "()Ljava/lang/String;");
94 if (!methodId)
95 return NULL;
96
97 // get jstring representation of our buffer
98 strObj = (*env)->CallObjectMethod(env, strBuilder, methodId);
99
100 // read string
101 native_str = (*env)->GetStringUTFChars(env, strObj, NULL);
102 if (!native_str)
103 return NULL;
104 result = _strdup(native_str);
105 (*env)->ReleaseStringUTFChars(env, strObj, native_str);
106
107 return result;
108}
109
110jstring jniNewStringUTF(JNIEnv* env, const char* in, int len)
111{
112 jstring out = NULL;
113 jchar* unicode = NULL;
114 jint result_size = 0;
115 unsigned char* utf8 = (unsigned char*)in;
116
117 if (!in)
118 {
119 return NULL;
120 }
121 if (len < 0)
122 len = strlen(in);
123
124 unicode = (jchar*)malloc(sizeof(jchar) * (len + 1));
125 if (!unicode)
126 {
127 return NULL;
128 }
129
130 for (jint i = 0; i < len; i++)
131 {
132 unsigned char one = utf8[i];
133 switch (one >> 4)
134 {
135 case 0x00:
136 case 0x01:
137 case 0x02:
138 case 0x03:
139 case 0x04:
140 case 0x05:
141 case 0x06:
142 case 0x07:
143 unicode[result_size++] = one;
144 break;
145 case 0x08:
146 case 0x09:
147 case 0x0a:
148 case 0x0b:
149 // case 0x0f:
150 /*
151 * Bit pattern 10xx or 1111, which are illegal start bytes.
152 * Note: 1111 is valid for normal UTF-8, but not the
153 * modified UTF-8 used here.
154 */
155 break;
156 case 0x0f:
157 case 0x0e:
158 // Bit pattern 111x, so there are two additional bytes.
159 if (i < (len - 2))
160 {
161 unsigned char two = utf8[i + 1];
162 unsigned char three = utf8[i + 2];
163 if ((two & 0xc0) == 0x80 && (three & 0xc0) == 0x80)
164 {
165 i += 2;
166 unicode[result_size++] =
167 ((one & 0x0f) << 12) | ((two & 0x3f) << 6) | (three & 0x3f);
168 }
169 }
170 break;
171 case 0x0c:
172 case 0x0d:
173 // Bit pattern 110x, so there is one additional byte.
174 if (i < (len - 1))
175 {
176 unsigned char two = utf8[i + 1];
177 if ((two & 0xc0) == 0x80)
178 {
179 i += 1;
180 unicode[result_size++] = ((one & 0x1f) << 6) | (two & 0x3f);
181 }
182 }
183 break;
184 }
185 }
186
187 out = (*env)->NewString(env, unicode, result_size);
188 free(unicode);
189
190 return out;
191}