• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <stdlib.h>
19 #include <unicode/ubidi.h>
20 #include <string.h>
21 #include "BidiWrapperInterface.h"
22 
23 typedef struct {
24     UBiDi *pBiDi;
25     void *embeddingLevels;
26 } BiDiData;
27 
28 void check_fail (JNIEnv * env, int err);
29 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1open(JNIEnv * env,jclass clazz)30 JNIEXPORT jlong JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1open
31   (JNIEnv * env, jclass clazz)
32 {
33   BiDiData *data = (BiDiData *)malloc(sizeof(BiDiData));
34   (*data).pBiDi = ubidi_open ();
35   (*data).embeddingLevels = NULL;
36   return (jlong) (data);
37 }
38 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1close(JNIEnv * env,jclass clazz,jlong pBiDi)39 JNIEXPORT void JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1close
40   (JNIEnv * env, jclass clazz, jlong pBiDi)
41 {
42   BiDiData *data = (BiDiData *)pBiDi;
43 
44   ubidi_close ((*data).pBiDi);
45 
46   if ((*data).embeddingLevels != NULL)
47     free((*data).embeddingLevels);
48     free(data);
49 }
50 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1setPara(JNIEnv * env,jclass clazz,jlong pBiDi,jcharArray text,jint length,jbyte paraLevel,jbyteArray embeddingLevels)51 JNIEXPORT void JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1setPara
52   (JNIEnv * env, jclass clazz, jlong pBiDi, jcharArray text, jint length,
53    jbyte paraLevel, jbyteArray embeddingLevels)
54 {
55   UErrorCode err = 0;
56   jchar *_text = NULL;
57   BiDiData *data = (BiDiData *)pBiDi;
58   /* Remembering old embedding levels */
59   void *embLvls = (*data).embeddingLevels;
60 
61   _text = (*env)->GetCharArrayElements (env, text, NULL);
62 
63   if (embeddingLevels != NULL)
64     {
65         jbyte *el = (*env)->GetByteArrayElements (env, embeddingLevels, NULL);
66         (*data).embeddingLevels = malloc(length);
67         memcpy(((*data).embeddingLevels), el, length);
68         (*env)->ReleaseByteArrayElements (env, embeddingLevels, el, 0);
69     } else
70     {
71         (*data).embeddingLevels = NULL;
72     }
73 
74   ubidi_setPara ((*data).pBiDi, _text, length, paraLevel,
75                  ((*data).embeddingLevels), &err);
76   check_fail (env, err);
77 
78   /* Freeing old embedding levels */
79   if (embLvls != NULL) {
80     free(embLvls);
81   }
82 
83   (*env)->ReleaseCharArrayElements (env, text, _text, 0);
84 }
85 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1setLine(JNIEnv * env,jclass clazz,jlong pBiDi,jint start,jint limit)86 JNIEXPORT jlong JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1setLine
87   (JNIEnv * env, jclass clazz, jlong pBiDi, jint start, jint limit)
88 {
89   UErrorCode err = 0;
90   BiDiData *data = (BiDiData *)pBiDi;
91   BiDiData *lineData = (BiDiData *) malloc(sizeof(BiDiData));
92   (*lineData).embeddingLevels = NULL;
93 
94   (*lineData).pBiDi = ubidi_openSized (limit - start, 0, &err);
95   check_fail (env, err);
96 
97   ubidi_setLine ((*data).pBiDi, start, limit, (*lineData).pBiDi,
98                  &err);
99   check_fail (env, err);
100 
101   return (jlong) lineData;
102 }
103 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1getDirection(JNIEnv * env,jclass clazz,jlong pBiDi)104 JNIEXPORT jint JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getDirection
105   (JNIEnv * env, jclass clazz, jlong pBiDi)
106 {
107   BiDiData *data = (BiDiData *)pBiDi;
108   return ubidi_getDirection ((*data).pBiDi);
109 }
110 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLength(JNIEnv * env,jclass clazz,jlong pBiDi)111 JNIEXPORT jint JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLength
112   (JNIEnv * env, jclass clazz, jlong pBiDi)
113 {
114   BiDiData *data = (BiDiData *)pBiDi;
115   return ubidi_getLength ((*data).pBiDi);
116 }
117 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1getParaLevel(JNIEnv * env,jclass clazz,jlong pBiDi)118 JNIEXPORT jbyte JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getParaLevel
119   (JNIEnv * env, jclass clazz, jlong pBiDi)
120 {
121   BiDiData *data = (BiDiData *)pBiDi;
122   return ubidi_getParaLevel ((*data).pBiDi);
123 }
124 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLevels(JNIEnv * env,jclass clazz,jlong pBiDi)125 JNIEXPORT jbyteArray JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLevels
126   (JNIEnv * env, jclass clazz, jlong pBiDi)
127 {
128   UErrorCode err = 0;
129   const UBiDiLevel *levels = NULL;
130   jbyteArray result = NULL;
131   int len = 0;
132   BiDiData *data = (BiDiData *)pBiDi;
133 
134   levels = ubidi_getLevels ((*data).pBiDi, &err);
135   check_fail (env, err);
136 
137   len = ubidi_getLength ((*data).pBiDi);
138   result = (*env)->NewByteArray (env, len);
139   (*env)->SetByteArrayRegion (env, result, 0, len, (jbyte *) levels);
140 
141   return result;
142 }
143 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1countRuns(JNIEnv * env,jclass clazz,jlong pBiDi)144 JNIEXPORT jint JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1countRuns
145   (JNIEnv * env, jclass clazz, jlong pBiDi)
146 {
147   UErrorCode err = 0;
148   BiDiData *data = (BiDiData *)pBiDi;
149 
150   int count = ubidi_countRuns ((*data).pBiDi, &err);
151   check_fail (env, err);
152 
153   return count;
154 }
155 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1getRuns(JNIEnv * env,jclass clz,jlong pBiDi)156 JNIEXPORT jobjectArray JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1getRuns
157   (JNIEnv * env, jclass clz, jlong pBiDi)
158 {
159   int runCount = 0;
160   int start = 0;
161   int limit = 0;
162   int i = 0;
163   UBiDiLevel level = 0;
164   jclass run_clazz = 0;
165   jmethodID initID = 0;
166   jobject run = 0;
167   jobjectArray runs;
168   UErrorCode err = 0;
169   BiDiData *data = (BiDiData *)pBiDi;
170 
171   run_clazz = (*env)->FindClass (env, "org/apache/harmony/text/BidiRun");
172   initID = (*env)->GetMethodID (env, run_clazz, "<init>", "(III)V");
173 
174   runCount = ubidi_countRuns ((*data).pBiDi, &err);
175   check_fail (env, err);
176 
177   runs = (*env)->NewObjectArray(env, runCount,run_clazz, NULL);
178   for (i = 0; i < runCount; i++) {
179       ubidi_getLogicalRun((*data).pBiDi, start, &limit, &level);
180       run = (*env)->NewObject (env, run_clazz, initID, start, limit, level);
181       (*env)->SetObjectArrayElement(env, runs, i, run);
182       start = limit;
183   }
184   return runs;
185 }
186 
187 void
check_fail(JNIEnv * env,int err)188 check_fail (JNIEnv * env, int err)
189 {
190   char message[] = "ICU Internal Error:                     ";
191 
192   if (U_FAILURE (err))
193     {
194       sprintf (message, "ICU Internal Error: %d", err);
195       jniThrowException(env, "java/lang/RuntimeException",
196                               message);
197     }
198 }
199 
Java_org_apache_harmony_text_BidiWrapper_ubidi_1reorderVisual(JNIEnv * env,jclass clazz,jbyteArray levels,jint length)200 JNIEXPORT jintArray JNICALL Java_org_apache_harmony_text_BidiWrapper_ubidi_1reorderVisual
201   (JNIEnv * env, jclass clazz, jbyteArray levels, jint length)
202 {
203   UBiDiLevel *local_levels = 0;
204   int *local_indexMap = 0;
205   jintArray result = 0;
206 
207   local_indexMap = (int *) malloc(sizeof (int) * length);
208   local_levels = (*env)->GetByteArrayElements (env, levels, NULL);
209 
210   ubidi_reorderVisual (local_levels, length, local_indexMap);
211 
212   result = (*env)->NewIntArray (env, length);
213   (*env)->SetIntArrayRegion (env, result, 0, length, (jint *) local_indexMap);
214 
215   free(local_indexMap);
216   (*env)->ReleaseByteArrayElements (env, levels, local_levels, 0);
217 
218   return result;
219 }
220 
221 /*
222  * JNI registration
223  */
224 static JNINativeMethod gMethods[] = {
225     /* NAME                , SIGNATURE              ,       FUNCPTR */
226     { "ubidi_open"        , "()J"                                  ,
227         Java_org_apache_harmony_text_BidiWrapper_ubidi_1open          },
228     { "ubidi_close"        , "(J)V"                                 ,
229         Java_org_apache_harmony_text_BidiWrapper_ubidi_1close         },
230     { "ubidi_setPara"      , "(J[CIB[B)V"                           ,
231         Java_org_apache_harmony_text_BidiWrapper_ubidi_1setPara       },
232     { "ubidi_setLine"      , "(JII)J"                               ,
233         Java_org_apache_harmony_text_BidiWrapper_ubidi_1setLine       },
234     { "ubidi_getDirection" , "(J)I"                                 ,
235         Java_org_apache_harmony_text_BidiWrapper_ubidi_1getDirection  },
236     { "ubidi_getLength"    , "(J)I"                                 ,
237         Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLength     },
238     { "ubidi_getParaLevel" , "(J)B"                                 ,
239         Java_org_apache_harmony_text_BidiWrapper_ubidi_1getParaLevel  },
240     { "ubidi_getLevels"    , "(J)[B"                                ,
241         Java_org_apache_harmony_text_BidiWrapper_ubidi_1getLevels     },
242     { "ubidi_countRuns"    , "(J)I"                                 ,
243         Java_org_apache_harmony_text_BidiWrapper_ubidi_1countRuns     },
244     { "ubidi_getRuns"      , "(J)[Lorg/apache/harmony/text/BidiRun;",
245         Java_org_apache_harmony_text_BidiWrapper_ubidi_1getRuns       },
246     { "ubidi_reorderVisual", "([BI)[I"                              ,
247         Java_org_apache_harmony_text_BidiWrapper_ubidi_1reorderVisual },
248 };
register_org_apache_harmony_text_BidiWrapper(JNIEnv * env)249 int register_org_apache_harmony_text_BidiWrapper(JNIEnv *env)
250 {
251     return jniRegisterNativeMethods(env, "org/apache/harmony/text/BidiWrapper",
252                 gMethods, NELEM(gMethods));
253 }
254