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 #define MBYTE 1048576 35 36 #define GETCRITICAL_OR_RETURN(bytes, env, obj) { \ 37 bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \ 38 if (bytes == NULL) { \ 39 if ((*env)->ExceptionOccurred(env) == NULL) \ 40 JNU_ThrowInternalError(env, "Unable to get array"); \ 41 return; \ 42 } \ 43 } 44 45 #define RELEASECRITICAL(bytes, env, obj, mode) { \ 46 (*env)->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \ 47 } 48 49 #define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff))) 50 #define SWAPINT(x) ((jint)((SWAPSHORT((jshort)(x)) << 16) | \ 51 (SWAPSHORT((jshort)((x) >> 16)) & 0xffff))) 52 #define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \ 53 ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff))) 54 55 JNIEXPORT void JNICALL 56 Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jclass clazz, jobject src, 57 jlong srcPos, jlong dstAddr, jlong length) 58 { 59 jbyte *bytes; 60 size_t size; 61 jshort *srcShort, *dstShort, *endShort; 62 jshort tmpShort; 63 64 dstShort = (jshort *)jlong_to_ptr(dstAddr); 65 66 while (length > 0) { 67 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 68 69 GETCRITICAL_OR_RETURN(bytes, env, src); 70 71 srcShort = (jshort *)(bytes + srcPos); 72 endShort = srcShort + (size / sizeof(jshort)); 73 while (srcShort < endShort) { 74 tmpShort = *srcShort++; 75 *dstShort++ = SWAPSHORT(tmpShort); 76 } 77 78 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 79 80 length -= size; 81 srcPos += size; 82 } 83 } 84 85 JNIEXPORT void JNICALL 86 Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jclass clazz, jlong srcAddr, 87 jobject dst, jlong dstPos, jlong length) 88 { 89 jbyte *bytes; 90 size_t size; 91 jshort *srcShort, *dstShort, *endShort; 92 jshort tmpShort; 93 94 srcShort = (jshort *)jlong_to_ptr(srcAddr); 95 96 while (length > 0) { 97 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 98 99 GETCRITICAL_OR_RETURN(bytes, env, dst); 100 101 dstShort = (jshort *)(bytes + dstPos); 102 endShort = srcShort + (size / sizeof(jshort)); 103 while (srcShort < endShort) { 104 tmpShort = *srcShort++; 105 *dstShort++ = SWAPSHORT(tmpShort); 106 } 107 108 RELEASECRITICAL(bytes, env, dst, 0); 109 110 length -= size; 111 dstPos += size; 112 } 113 } 114 115 JNIEXPORT void JNICALL 116 Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jclass clazz, jobject src, 117 jlong srcPos, jlong dstAddr, jlong length) 118 { 119 jbyte *bytes; 120 size_t size; 121 jint *srcInt, *dstInt, *endInt; 122 jint tmpInt; 123 124 dstInt = (jint *)jlong_to_ptr(dstAddr); 125 126 while (length > 0) { 127 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 128 129 GETCRITICAL_OR_RETURN(bytes, env, src); 130 131 srcInt = (jint *)(bytes + srcPos); 132 endInt = srcInt + (size / sizeof(jint)); 133 while (srcInt < endInt) { 134 tmpInt = *srcInt++; 135 *dstInt++ = SWAPINT(tmpInt); 136 } 137 138 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 139 140 length -= size; 141 srcPos += size; 142 } 143 } 144 145 JNIEXPORT void JNICALL 146 Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jclass clazz, jlong srcAddr, 147 jobject dst, jlong dstPos, jlong length) 148 { 149 jbyte *bytes; 150 size_t size; 151 jint *srcInt, *dstInt, *endInt; 152 jint tmpInt; 153 154 srcInt = (jint *)jlong_to_ptr(srcAddr); 155 156 while (length > 0) { 157 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 158 159 GETCRITICAL_OR_RETURN(bytes, env, dst); 160 161 dstInt = (jint *)(bytes + dstPos); 162 endInt = srcInt + (size / sizeof(jint)); 163 while (srcInt < endInt) { 164 tmpInt = *srcInt++; 165 *dstInt++ = SWAPINT(tmpInt); 166 } 167 168 RELEASECRITICAL(bytes, env, dst, 0); 169 170 length -= size; 171 dstPos += size; 172 } 173 } 174 175 JNIEXPORT void JNICALL 176 Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jclass clazz, jobject src, 177 jlong srcPos, jlong dstAddr, jlong length) 178 { 179 jbyte *bytes; 180 size_t size; 181 jlong *srcLong, *dstLong, *endLong; 182 jlong tmpLong; 183 184 dstLong = (jlong *)jlong_to_ptr(dstAddr); 185 186 while (length > 0) { 187 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 188 189 GETCRITICAL_OR_RETURN(bytes, env, src); 190 191 srcLong = (jlong *)(bytes + srcPos); 192 endLong = srcLong + (size / sizeof(jlong)); 193 while (srcLong < endLong) { 194 tmpLong = *srcLong++; 195 *dstLong++ = SWAPLONG(tmpLong); 196 } 197 198 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 199 200 length -= size; 201 srcPos += size; 202 } 203 } 204 205 JNIEXPORT void JNICALL 206 Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jclass clazz, jlong srcAddr, 207 jobject dst, jlong dstPos, jlong length) 208 { 209 jbyte *bytes; 210 size_t size; 211 jlong *srcLong, *dstLong, *endLong; 212 jlong tmpLong; 213 214 srcLong = (jlong *)jlong_to_ptr(srcAddr); 215 216 while (length > 0) { 217 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 218 219 GETCRITICAL_OR_RETURN(bytes, env, dst); 220 221 dstLong = (jlong *)(bytes + dstPos); 222 endLong = srcLong + (size / sizeof(jlong)); 223 while (srcLong < endLong) { 224 tmpLong = *srcLong++; 225 *dstLong++ = SWAPLONG(tmpLong); 226 } 227 228 RELEASECRITICAL(bytes, env, dst, 0); 229 230 length -= size; 231 dstPos += size; 232 } 233 }