1 /*
2 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 /*
27 */
28
29 #include "jni.h"
30 #include "jni_util.h"
31 #include "jlong.h"
32 #include <string.h>
33
34 #include "JNIHelp.h"
35
36 /*
37 * WARNING:
38 *
39 * Do not replace instances of:
40 *
41 * if (length > MBYTE)
42 * size = MBYTE;
43 * else
44 * size = length;
45 *
46 * with
47 *
48 * size = (length > MBYTE ? MBYTE : length);
49 *
50 * This expression causes a c compiler assertion failure when compiling on
51 * 32-bit sparc.
52 */
53
54 #define MBYTE 1048576
55
56 #define GETCRITICAL(bytes, env, obj) { \
57 bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \
58 if (bytes == NULL) \
59 JNU_ThrowInternalError(env, "Unable to get array"); \
60 }
61
62 #define RELEASECRITICAL(bytes, env, obj, mode) { \
63 (*env)->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \
64 }
65
66 #define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff)))
67 #define SWAPINT(x) ((jint)((SWAPSHORT((jshort)(x)) << 16) | \
68 (SWAPSHORT((jshort)((x) >> 16)) & 0xffff)))
69 #define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \
70 ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff)))
71
72 #define NATIVE_METHOD(className, functionName, signature) \
73 { #functionName, signature, (void*)(Java_java_nio_ ## className ## _ ## functionName) }
74
75 JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromShortArray(JNIEnv * env,jobject this,jobject src,jlong srcPos,jlong dstAddr,jlong length)76 Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src,
77 jlong srcPos, jlong dstAddr, jlong length)
78 {
79 jbyte *bytes;
80 size_t size;
81 jshort *srcShort, *dstShort, *endShort;
82 jshort tmpShort;
83
84 dstShort = (jshort *)jlong_to_ptr(dstAddr);
85
86 while (length > 0) {
87 /* do not change this if-else statement, see WARNING above */
88 if (length > MBYTE)
89 size = MBYTE;
90 else
91 size = (size_t)length;
92
93 GETCRITICAL(bytes, env, src);
94
95 srcShort = (jshort *)(bytes + srcPos);
96 endShort = srcShort + (size / sizeof(jshort));
97 while (srcShort < endShort) {
98 tmpShort = *srcShort++;
99 *dstShort++ = SWAPSHORT(tmpShort);
100 }
101
102 RELEASECRITICAL(bytes, env, src, JNI_ABORT);
103
104 length -= size;
105 dstAddr += size;
106 srcPos += size;
107 }
108 }
109
110 JNIEXPORT void JNICALL
Java_java_nio_Bits_copyToShortArray(JNIEnv * env,jobject this,jlong srcAddr,jobject dst,jlong dstPos,jlong length)111 Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr,
112 jobject dst, jlong dstPos, jlong length)
113 {
114 jbyte *bytes;
115 size_t size;
116 jshort *srcShort, *dstShort, *endShort;
117 jshort tmpShort;
118
119 srcShort = (jshort *)jlong_to_ptr(srcAddr);
120
121 while (length > 0) {
122 /* do not change this if-else statement, see WARNING above */
123 if (length > MBYTE)
124 size = MBYTE;
125 else
126 size = (size_t)length;
127
128 GETCRITICAL(bytes, env, dst);
129
130 dstShort = (jshort *)(bytes + dstPos);
131 endShort = srcShort + (size / sizeof(jshort));
132 while (srcShort < endShort) {
133 tmpShort = *srcShort++;
134 *dstShort++ = SWAPSHORT(tmpShort);
135 }
136
137 RELEASECRITICAL(bytes, env, dst, 0);
138
139 length -= size;
140 srcAddr += size;
141 dstPos += size;
142 }
143 }
144
145 JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromIntArray(JNIEnv * env,jobject this,jobject src,jlong srcPos,jlong dstAddr,jlong length)146 Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src,
147 jlong srcPos, jlong dstAddr, jlong length)
148 {
149 jbyte *bytes;
150 size_t size;
151 jint *srcInt, *dstInt, *endInt;
152 jint tmpInt;
153
154 dstInt = (jint *)jlong_to_ptr(dstAddr);
155
156 while (length > 0) {
157 /* do not change this code, see WARNING above */
158 if (length > MBYTE)
159 size = MBYTE;
160 else
161 size = (size_t)length;
162
163 GETCRITICAL(bytes, env, src);
164
165 srcInt = (jint *)(bytes + srcPos);
166 endInt = srcInt + (size / sizeof(jint));
167 while (srcInt < endInt) {
168 tmpInt = *srcInt++;
169 *dstInt++ = SWAPINT(tmpInt);
170 }
171
172 RELEASECRITICAL(bytes, env, src, JNI_ABORT);
173
174 length -= size;
175 dstAddr += size;
176 srcPos += size;
177 }
178 }
179
180 JNIEXPORT void JNICALL
Java_java_nio_Bits_copyToIntArray(JNIEnv * env,jobject this,jlong srcAddr,jobject dst,jlong dstPos,jlong length)181 Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr,
182 jobject dst, jlong dstPos, jlong length)
183 {
184 jbyte *bytes;
185 size_t size;
186 jint *srcInt, *dstInt, *endInt;
187 jint tmpInt;
188
189 srcInt = (jint *)jlong_to_ptr(srcAddr);
190
191 while (length > 0) {
192 /* do not change this code, see WARNING above */
193 if (length > MBYTE)
194 size = MBYTE;
195 else
196 size = (size_t)length;
197
198 GETCRITICAL(bytes, env, dst);
199
200 dstInt = (jint *)(bytes + dstPos);
201 endInt = srcInt + (size / sizeof(jint));
202 while (srcInt < endInt) {
203 tmpInt = *srcInt++;
204 *dstInt++ = SWAPINT(tmpInt);
205 }
206
207 RELEASECRITICAL(bytes, env, dst, 0);
208
209 length -= size;
210 srcAddr += size;
211 dstPos += size;
212 }
213 }
214
215 JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromLongArray(JNIEnv * env,jobject this,jobject src,jlong srcPos,jlong dstAddr,jlong length)216 Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src,
217 jlong srcPos, jlong dstAddr, jlong length)
218 {
219 jbyte *bytes;
220 size_t size;
221 jlong *srcLong, *dstLong, *endLong;
222 jlong tmpLong;
223
224 dstLong = (jlong *)jlong_to_ptr(dstAddr);
225
226 while (length > 0) {
227 /* do not change this code, see WARNING above */
228 if (length > MBYTE)
229 size = MBYTE;
230 else
231 size = (size_t)length;
232
233 GETCRITICAL(bytes, env, src);
234
235 srcLong = (jlong *)(bytes + srcPos);
236 endLong = srcLong + (size / sizeof(jlong));
237 while (srcLong < endLong) {
238 tmpLong = *srcLong++;
239 *dstLong++ = SWAPLONG(tmpLong);
240 }
241
242 RELEASECRITICAL(bytes, env, src, JNI_ABORT);
243
244 length -= size;
245 dstAddr += size;
246 srcPos += size;
247 }
248 }
249
250 JNIEXPORT void JNICALL
Java_java_nio_Bits_copyToLongArray(JNIEnv * env,jobject this,jlong srcAddr,jobject dst,jlong dstPos,jlong length)251 Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr,
252 jobject dst, jlong dstPos, jlong length)
253 {
254 jbyte *bytes;
255 size_t size;
256 jlong *srcLong, *dstLong, *endLong;
257 jlong tmpLong;
258
259 srcLong = (jlong *)jlong_to_ptr(srcAddr);
260
261 while (length > 0) {
262 /* do not change this code, see WARNING above */
263 if (length > MBYTE)
264 size = MBYTE;
265 else
266 size = (size_t)length;
267
268 GETCRITICAL(bytes, env, dst);
269
270 dstLong = (jlong *)(bytes + dstPos);
271 endLong = srcLong + (size / sizeof(jlong));
272 while (srcLong < endLong) {
273 tmpLong = *srcLong++;
274 *dstLong++ = SWAPLONG(tmpLong);
275 }
276
277 RELEASECRITICAL(bytes, env, dst, 0);
278
279 length -= size;
280 srcAddr += size;
281 dstPos += size;
282 }
283 }
284
285 static JNINativeMethod gMethods[] = {
286 NATIVE_METHOD(Bits, copyFromShortArray, "(Ljava/lang/Object;JJJ)V"),
287 NATIVE_METHOD(Bits, copyToShortArray, "(JLjava/lang/Object;JJ)V"),
288 NATIVE_METHOD(Bits, copyFromIntArray, "(Ljava/lang/Object;JJJ)V"),
289 NATIVE_METHOD(Bits, copyToIntArray, "(JLjava/lang/Object;JJ)V"),
290 NATIVE_METHOD(Bits, copyFromLongArray, "(Ljava/lang/Object;JJJ)V"),
291 NATIVE_METHOD(Bits, copyToLongArray, "(JLjava/lang/Object;JJ)V"),
292 };
293
register_java_nio_Bits(JNIEnv * env)294 void register_java_nio_Bits(JNIEnv* env) {
295 jniRegisterNativeMethods(env, "java/nio/Bits", gMethods, NELEM(gMethods));
296 }
297