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, *endShort; 62 unsigned char* dst; 63 64 dst = 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 = (jshort *)(bytes + srcPos + size); 73 while (srcShort < endShort) { 74 jshort tmp = SWAPSHORT(*srcShort); 75 memcpy(dst, &tmp, sizeof(jshort)); 76 srcShort++; 77 dst += sizeof(jshort); 78 } 79 80 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 81 82 length -= size; 83 srcPos += size; 84 } 85 } 86 87 JNIEXPORT void JNICALL 88 Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jclass clazz, jlong srcAddr, 89 jobject dst, jlong dstPos, jlong length) 90 { 91 jbyte *bytes; 92 size_t size; 93 jshort *dstShort; 94 95 unsigned char *src, *end; 96 src = jlong_to_ptr(srcAddr); 97 98 while (length > 0) { 99 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 100 101 GETCRITICAL_OR_RETURN(bytes, env, dst); 102 103 dstShort = (jshort *)(bytes + dstPos); 104 end = src + size; 105 while (src < end) { 106 jshort tmp; 107 memcpy(&tmp, src, sizeof(jshort)); 108 *dstShort++ = SWAPSHORT(tmp); 109 src += sizeof(jshort); 110 } 111 112 RELEASECRITICAL(bytes, env, dst, 0); 113 114 length -= size; 115 dstPos += size; 116 } 117 } 118 119 JNIEXPORT void JNICALL 120 Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jclass clazz, jobject src, 121 jlong srcPos, jlong dstAddr, jlong length) 122 { 123 jbyte *bytes; 124 size_t size; 125 jint *srcInt, *endInt; 126 unsigned char *dst; 127 128 dst = jlong_to_ptr(dstAddr); 129 130 while (length > 0) { 131 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 132 133 GETCRITICAL_OR_RETURN(bytes, env, src); 134 135 srcInt = (jint *)(bytes + srcPos); 136 endInt = (jint *)(bytes + srcPos + size); 137 while (srcInt < endInt) { 138 jint tmp = SWAPINT(*srcInt); 139 memcpy(dst, &tmp, sizeof(jint)); 140 srcInt++; 141 dst += sizeof(jint); 142 } 143 144 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 145 146 length -= size; 147 srcPos += size; 148 } 149 } 150 151 JNIEXPORT void JNICALL 152 Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jclass clazz, jlong srcAddr, 153 jobject dst, jlong dstPos, jlong length) 154 { 155 jbyte *bytes; 156 size_t size; 157 unsigned char *src, *end; 158 jint *dstInt; 159 160 src = jlong_to_ptr(srcAddr); 161 162 while (length > 0) { 163 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 164 165 GETCRITICAL_OR_RETURN(bytes, env, dst); 166 167 dstInt = (jint *)(bytes + dstPos); 168 end = src + size; 169 while (src < end) { 170 jint tmp; 171 memcpy(&tmp, src, sizeof(jint)); 172 *dstInt++ = SWAPINT(tmp); 173 src += sizeof(jint); 174 } 175 176 RELEASECRITICAL(bytes, env, dst, 0); 177 178 length -= size; 179 dstPos += size; 180 } 181 } 182 183 JNIEXPORT void JNICALL 184 Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jclass clazz, jobject src, 185 jlong srcPos, jlong dstAddr, jlong length) 186 { 187 jbyte *bytes; 188 size_t size; 189 jlong *srcLong, *endLong; 190 unsigned char* dst; 191 192 dst = jlong_to_ptr(dstAddr); 193 194 while (length > 0) { 195 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 196 197 GETCRITICAL_OR_RETURN(bytes, env, src); 198 199 srcLong = (jlong *)(bytes + srcPos); 200 endLong = (jlong *)(bytes + srcPos + size); 201 while (srcLong < endLong) { 202 jlong tmp = SWAPLONG(*srcLong); 203 memcpy(dst, &tmp, sizeof(jlong)); 204 srcLong++; 205 dst += sizeof(jlong); 206 } 207 208 RELEASECRITICAL(bytes, env, src, JNI_ABORT); 209 210 length -= size; 211 srcPos += size; 212 } 213 } 214 215 JNIEXPORT void JNICALL 216 Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jclass clazz, jlong srcAddr, 217 jobject dst, jlong dstPos, jlong length) 218 { 219 jbyte *bytes; 220 size_t size; 221 unsigned char *src, *end; 222 jlong *dstLong; 223 224 src = jlong_to_ptr(srcAddr); 225 226 while (length > 0) { 227 size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; 228 229 GETCRITICAL_OR_RETURN(bytes, env, dst); 230 231 dstLong = (jlong *)(bytes + dstPos); 232 end = src + size; 233 while (src < end) { 234 jlong tmp; 235 memcpy(&tmp, src, sizeof(jlong)); 236 *dstLong++ = SWAPLONG(tmp); 237 src += sizeof(jlong); 238 } 239 240 RELEASECRITICAL(bytes, env, dst, 0); 241 242 length -= size; 243 dstPos += size; 244 } 245 }