FreeRDP
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 
23 JavaVM* g_JavaVm;
24 
25 JavaVM* getJavaVM()
26 {
27  return g_JavaVm;
28 }
29 
30 JNIEnv* 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 
41 jobject 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 
79 char* 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 
110 jstring 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 }