OSDN Git Service

fe79dc12515dca8eef23ddcb583889a26555ee88
[pf3gnuchains/gcc-fork.git] / libjava / gnu / gcj / convert / natIconv.cc
1 // Input_iconv.java -- Java side of iconv() reader.
2
3 /* Copyright (C) 2000  Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 /* Author: Tom Tromey <tromey@redhat.com>.  */
12
13 #include <config.h>
14
15 #include <gcj/cni.h>
16 #include <jvm.h>
17
18 #include <gnu/gcj/convert/Input_iconv.h>
19 #include <gnu/gcj/convert/Output_iconv.h>
20 #include <java/io/UnsupportedEncodingException.h>
21
22 #ifdef HAVE_ICONV
23 #include <iconv.h>
24
25 template<typename T>
26 static inline size_t
27 iconv_adapter (size_t (*iconv_f) (iconv_t, T, size_t *, char **, size_t *),
28                iconv_t handle, char **inbuf, size_t *inavail,
29                char **outbuf, size_t *outavail)
30 {
31   return (*iconv_f) (handle, (T) inbuf, inavail, outbuf, outavail);
32 }
33
34 #endif
35
36 void
37 gnu::gcj::convert::Input_iconv::init (jstring encoding)
38 {
39 #ifdef HAVE_ICONV
40   jsize len = _Jv_GetStringUTFLength (encoding);
41   char buffer[len];
42   _Jv_GetStringUTFRegion (encoding, 0, len, buffer);
43
44   iconv_t h = iconv_open ("UCS-2", buffer);
45   if (h == (iconv_t) -1)
46     JvThrow (new java::io::UnsupportedEncodingException);
47
48   JvAssert (h != NULL);
49   handle = reinterpret_cast<gnu::gcj::RawData *> (h);
50 #else /* HAVE_ICONV */
51   // If no iconv, just throw an exception.
52   JvThrow (new java::io::UnsupportedEncodingException);
53 #endif /* HAVE_ICONV */
54 }
55
56 void
57 gnu::gcj::convert::Input_iconv::finalize (void)
58 {
59 #ifdef HAVE_ICONV
60   if (handle != NULL)
61     {
62       iconv_close ((iconv_t) handle);
63       handle = NULL;
64     }
65 #endif /* HAVE_ICONV */
66 }
67
68 jint
69 gnu::gcj::convert::Input_iconv::read (jcharArray outbuffer,
70                                       jint outpos, jint count)
71 {
72 #ifdef HAVE_ICONV
73   jbyte *bytes = elements (inbuffer);
74   jchar *out = elements (outbuffer);
75   size_t inavail = inlength - inpos;
76   size_t old_in = inavail;
77   size_t outavail = count;
78   size_t old_out = outavail;
79
80   char *inbuf = (char *) &bytes[inpos];
81   char *outbuf = (char *) &out[outpos];
82
83   size_t r = iconv_adapter (iconv, (iconv_t) handle,
84                             &inbuf, &inavail,
85                             &outbuf, &outavail);
86   // FIXME: what if R==-1?
87
88   inpos += old_in - inavail;
89   return old_out - outavail;
90 #else /* HAVE_ICONV */
91   return -1;
92 #endif /* HAVE_ICONV */
93 }
94
95 void
96 gnu::gcj::convert::Output_iconv::init (jstring encoding)
97 {
98 #ifdef HAVE_ICONV
99   jsize len = _Jv_GetStringUTFLength (encoding);
100   char buffer[len];
101   _Jv_GetStringUTFRegion (encoding, 0, len, buffer);
102
103   iconv_t h = iconv_open (buffer, "UCS-2");
104   if (h == (iconv_t) -1)
105     JvThrow (new java::io::UnsupportedEncodingException);
106
107   JvAssert (h != NULL);
108   handle = reinterpret_cast<gnu::gcj::RawData *> (h);
109 #else /* HAVE_ICONV */
110   // If no iconv, just throw an exception.
111   JvThrow (new java::io::UnsupportedEncodingException);
112 #endif /* HAVE_ICONV */
113 }
114
115 void
116 gnu::gcj::convert::Output_iconv::finalize (void)
117 {
118 #ifdef HAVE_ICONV
119   if (handle != NULL)
120     {
121       iconv_close ((iconv_t) handle);
122       handle = NULL;
123     }
124 #endif /* HAVE_ICONV */
125 }
126
127 jint
128 gnu::gcj::convert::Output_iconv::write (jcharArray inbuffer,
129                                         jint inpos, jint count)
130 {
131 #ifdef HAVE_ICONV
132   jchar *chars = elements (inbuffer);
133   jbyte *out = elements (buf);
134
135   size_t inavail = count;
136   size_t old_in = count;
137
138   size_t outavail = buf->length - count;
139   size_t old_out = outavail;
140
141   char *inbuf = (char *) &chars[inpos];
142   char *outbuf = (char *) &out[count];
143
144   size_t r = iconv_adapter (iconv, (iconv_t) handle,
145                             &inbuf, &inavail,
146                             &outbuf, &outavail);
147   // FIXME: what if R==-1?
148
149   count += old_out - outavail;
150   return old_in - inavail;
151 #else /* HAVE_ICONV */
152   return -1;
153 #endif /* HAVE_ICONV */
154 }