/* * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* */ #include "jni.h" #include "jni_util.h" #include "jlong.h" #include #define MBYTE 1048576 #define GETCRITICAL_OR_RETURN(bytes, env, obj) { \ bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \ if (bytes == NULL) { \ if ((*env)->ExceptionOccurred(env) == NULL) \ JNU_ThrowInternalError(env, "Unable to get array"); \ return; \ } \ } #define RELEASECRITICAL(bytes, env, obj, mode) { \ (*env)->ReleasePrimitiveArrayCritical(env, obj, bytes, mode); \ } #define SWAPSHORT(x) ((jshort)(((x) << 8) | (((x) >> 8) & 0xff))) #define SWAPINT(x) ((jint)((SWAPSHORT((jshort)(x)) << 16) | \ (SWAPSHORT((jshort)((x) >> 16)) & 0xffff))) #define SWAPLONG(x) ((jlong)(((jlong)SWAPINT((jint)(x)) << 32) | \ ((jlong)SWAPINT((jint)((x) >> 32)) & 0xffffffff))) JNIEXPORT void JNICALL Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jclass clazz, jobject src, jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; size_t size; jshort *srcShort, *endShort; unsigned char* dst; dst = jlong_to_ptr(dstAddr); while (length > 0) { size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, src); srcShort = (jshort *)(bytes + srcPos); endShort = (jshort *)(bytes + srcPos + size); while (srcShort < endShort) { jshort tmp = SWAPSHORT(*srcShort); memcpy(dst, &tmp, sizeof(jshort)); srcShort++; dst += sizeof(jshort); } RELEASECRITICAL(bytes, env, src, JNI_ABORT); length -= size; srcPos += size; } } JNIEXPORT void JNICALL Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jclass clazz, jlong srcAddr, jobject dst, jlong dstPos, jlong length) { jbyte *bytes; size_t size; jshort *dstShort; unsigned char *src, *end; src = jlong_to_ptr(srcAddr); while (length > 0) { size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, dst); dstShort = (jshort *)(bytes + dstPos); end = src + size; while (src < end) { jshort tmp; memcpy(&tmp, src, sizeof(jshort)); *dstShort++ = SWAPSHORT(tmp); src += sizeof(jshort); } RELEASECRITICAL(bytes, env, dst, 0); length -= size; dstPos += size; } } JNIEXPORT void JNICALL Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jclass clazz, jobject src, jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; size_t size; jint *srcInt, *endInt; unsigned char *dst; dst = jlong_to_ptr(dstAddr); while (length > 0) { size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, src); srcInt = (jint *)(bytes + srcPos); endInt = (jint *)(bytes + srcPos + size); while (srcInt < endInt) { jint tmp = SWAPINT(*srcInt); memcpy(dst, &tmp, sizeof(jint)); srcInt++; dst += sizeof(jint); } RELEASECRITICAL(bytes, env, src, JNI_ABORT); length -= size; srcPos += size; } } JNIEXPORT void JNICALL Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jclass clazz, jlong srcAddr, jobject dst, jlong dstPos, jlong length) { jbyte *bytes; size_t size; unsigned char *src, *end; jint *dstInt; src = jlong_to_ptr(srcAddr); while (length > 0) { size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, dst); dstInt = (jint *)(bytes + dstPos); end = src + size; while (src < end) { jint tmp; memcpy(&tmp, src, sizeof(jint)); *dstInt++ = SWAPINT(tmp); src += sizeof(jint); } RELEASECRITICAL(bytes, env, dst, 0); length -= size; dstPos += size; } } JNIEXPORT void JNICALL Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jclass clazz, jobject src, jlong srcPos, jlong dstAddr, jlong length) { jbyte *bytes; size_t size; jlong *srcLong, *endLong; unsigned char* dst; dst = jlong_to_ptr(dstAddr); while (length > 0) { size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, src); srcLong = (jlong *)(bytes + srcPos); endLong = (jlong *)(bytes + srcPos + size); while (srcLong < endLong) { jlong tmp = SWAPLONG(*srcLong); memcpy(dst, &tmp, sizeof(jlong)); srcLong++; dst += sizeof(jlong); } RELEASECRITICAL(bytes, env, src, JNI_ABORT); length -= size; srcPos += size; } } JNIEXPORT void JNICALL Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jclass clazz, jlong srcAddr, jobject dst, jlong dstPos, jlong length) { jbyte *bytes; size_t size; unsigned char *src, *end; jlong *dstLong; src = jlong_to_ptr(srcAddr); while (length > 0) { size = (length < MBYTE) ? (size_t)length : (size_t)MBYTE; GETCRITICAL_OR_RETURN(bytes, env, dst); dstLong = (jlong *)(bytes + dstPos); end = src + size; while (src < end) { jlong tmp; memcpy(&tmp, src, sizeof(jlong)); *dstLong++ = SWAPLONG(tmp); src += sizeof(jlong); } RELEASECRITICAL(bytes, env, dst, 0); length -= size; dstPos += size; } }