35 |
obligated to do so. If you do not wish to do so, delete this |
obligated to do so. If you do not wish to do so, delete this |
36 |
exception statement from your version. */ |
exception statement from your version. */ |
37 |
|
|
38 |
|
#include <config.h> |
39 |
|
#include <jcl.h> |
40 |
|
|
41 |
#include <stdio.h> |
#include <stdio.h> |
42 |
#include <assert.h> |
#include <assert.h> |
43 |
#include <errno.h> |
#include <errno.h> |
44 |
|
|
45 |
|
#if defined(HAVE_ICONV) |
46 |
#include <iconv.h> |
#include <iconv.h> |
47 |
|
#endif |
48 |
|
|
49 |
#include "gnu_java_nio_charset_iconv_IconvEncoder.h" |
#include "gnu_java_nio_charset_iconv_IconvEncoder.h" |
50 |
|
|
51 |
static void createRawData (JNIEnv * env, jobject obj, void *ptr); |
static void createRawData (JNIEnv * env, jobject obj, void *ptr); |
52 |
static void *getData (JNIEnv * env, jobject obj); |
static void *getData (JNIEnv * env, jobject obj); |
53 |
|
|
54 |
|
static jfieldID infid = NULL; |
55 |
|
static jfieldID outfid = NULL; |
56 |
|
|
57 |
|
/* Union used for type punning. */ |
58 |
|
union char_union |
59 |
|
{ |
60 |
|
jbyte **jb; |
61 |
|
jchar **jc; |
62 |
|
char **c; |
63 |
|
}; |
64 |
|
|
65 |
JNIEXPORT void JNICALL |
JNIEXPORT void JNICALL |
66 |
Java_gnu_java_nio_charset_iconv_IconvEncoder_openIconv (JNIEnv * env, |
Java_gnu_java_nio_charset_iconv_IconvEncoder_openIconv (JNIEnv * env, |
67 |
jobject obj, |
jobject obj, |
68 |
jstring jname) |
jstring jname) |
69 |
{ |
{ |
70 |
jclass exception; |
#if defined(HAVE_ICONV) |
71 |
iconv_t iconv_object; |
iconv_t iconv_object; |
72 |
|
jclass cls; |
73 |
|
|
74 |
const char *name = (*env)->GetStringUTFChars (env, jname, 0); |
const char *name = JCL_jstring_to_cstring (env, jname); |
75 |
|
if (name == NULL) |
76 |
|
return; |
77 |
|
|
78 |
|
/* Cache fieldIDs for use in encode function. */ |
79 |
|
if (infid == NULL || outfid == NULL) |
80 |
|
{ |
81 |
|
cls = (*env)->GetObjectClass (env, obj); |
82 |
|
infid = (*env)->GetFieldID (env, cls, "inremaining", "I"); |
83 |
|
assert (infid != 0); |
84 |
|
outfid = (*env)->GetFieldID (env, cls, "outremaining", "I"); |
85 |
|
assert (outfid != 0); |
86 |
|
} |
87 |
|
|
88 |
/* to "name" from java, native java format depends on endianness */ |
/* to "name" from java, native java format depends on endianness */ |
89 |
#ifdef WORDS_BIGENDIAN |
#ifdef WORDS_BIGENDIAN |
92 |
iconv_object = iconv_open (name, "UTF-16LE"); |
iconv_object = iconv_open (name, "UTF-16LE"); |
93 |
#endif |
#endif |
94 |
|
|
95 |
(*env)->ReleaseStringUTFChars (env, jname, name); |
JCL_free_cstring (env, jname, name); |
96 |
if ((long) iconv_object == -1L) |
if ((long) iconv_object == -1L) |
97 |
{ |
{ |
98 |
/* Throw an exception if charset not available */ |
JCL_ThrowException (env, "java/lang/IllegalArgumentException", |
99 |
(*env)->ExceptionDescribe (env); |
"Charset not available"); |
|
(*env)->ExceptionClear (env); |
|
|
exception = |
|
|
(*env)->FindClass (env, "java/lang/IllegalArgumentException"); |
|
|
assert (exception != 0); |
|
|
(*env)->ThrowNew (env, exception, "Charset not available."); |
|
100 |
return; |
return; |
101 |
} |
} |
102 |
createRawData (env, obj, (void *) iconv_object); |
createRawData (env, obj, (void *) iconv_object); |
103 |
|
#else |
104 |
|
JCL_ThrowException (env, "java/lang/IllegalArgumentException", |
105 |
|
"iconv not available"); |
106 |
|
#endif |
107 |
} |
} |
108 |
|
|
109 |
JNIEXPORT jint JNICALL |
JNIEXPORT jint JNICALL |
114 |
jint posIn, jint remIn, |
jint posIn, jint remIn, |
115 |
jint posOut, jint remOut) |
jint posOut, jint remOut) |
116 |
{ |
{ |
117 |
|
#if defined(HAVE_ICONV) |
118 |
iconv_t iconv_object = getData (env, obj); |
iconv_t iconv_object = getData (env, obj); |
|
jclass cls; |
|
|
jfieldID fid; |
|
119 |
size_t retval; |
size_t retval; |
120 |
char **in, **out; |
union char_union in, out; |
121 |
jchar *input, *inputcopy; |
jchar *input, *inputcopy; |
122 |
jbyte *output, *outputcopy; |
jbyte *output, *outputcopy; |
123 |
size_t lenIn = (size_t) remIn * 2; |
size_t lenIn = (size_t) remIn * 2; |
129 |
input += posIn; |
input += posIn; |
130 |
output += posOut; |
output += posOut; |
131 |
|
|
132 |
in = (char **) &input; |
in.jc = &input; |
133 |
out = (char **) &output; |
out.jb = &output; |
134 |
retval = iconv (iconv_object, in, &lenIn, out, &lenOut); |
retval = iconv (iconv_object, (ICONV_CONST char **) in.c, &lenIn, |
135 |
|
out.c, &lenOut); |
136 |
|
|
137 |
/* XXX: Do we need to relase the input array? It's not modified. */ |
/* XXX: Do we need to relase the input array? It's not modified. */ |
138 |
(*env)->ReleaseCharArrayElements (env, inArr, inputcopy, 0); |
(*env)->ReleaseCharArrayElements (env, inArr, inputcopy, 0); |
148 |
else |
else |
149 |
retval = 0; |
retval = 0; |
150 |
|
|
151 |
cls = (*env)->GetObjectClass (env, obj); |
(*env)->SetIntField (env, obj, infid, (jint) (lenIn >> 1)); |
152 |
fid = (*env)->GetFieldID (env, cls, "inremaining", "I"); |
(*env)->SetIntField (env, obj, outfid, (jint) lenOut); |
|
assert (fid != 0); |
|
|
(*env)->SetIntField (env, obj, fid, (jint) (lenIn >> 1)); |
|
|
fid = (*env)->GetFieldID (env, cls, "outremaining", "I"); |
|
|
assert (fid != 0); |
|
|
(*env)->SetIntField (env, obj, fid, (jint) lenOut); |
|
153 |
|
|
154 |
return (jint) retval; |
return (jint) retval; |
155 |
|
#else |
156 |
|
return -1; |
157 |
|
#endif |
158 |
} |
} |
159 |
|
|
160 |
JNIEXPORT void JNICALL |
JNIEXPORT void JNICALL |
161 |
Java_gnu_java_nio_charset_iconv_IconvEncoder_closeIconv (JNIEnv * env, |
Java_gnu_java_nio_charset_iconv_IconvEncoder_closeIconv (JNIEnv * env, |
162 |
jobject obj) |
jobject obj) |
163 |
{ |
{ |
164 |
|
#if defined(HAVE_ICONV) |
165 |
iconv_t iconv_object; |
iconv_t iconv_object; |
166 |
iconv_object = getData (env, obj); |
iconv_object = getData (env, obj); |
167 |
iconv_close (iconv_object); |
iconv_close (iconv_object); |
168 |
|
#endif |
169 |
} |
} |
170 |
|
|
171 |
|
|