/*
* 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 <string.h>
#include "JNIHelp.h"
/*
* WARNING:
*
* Do not replace instances of:
*
* if (length > MBYTE)
* size = MBYTE;
* else
* size = length;
*
* with
*
* size = (length > MBYTE ? MBYTE : length);
*
* This expression causes a c compiler assertion failure when compiling on
* 32-bit sparc.
*/
#define MBYTE 1048576
#define GETCRITICAL(bytes, env, obj) { \
bytes = (*env)->GetPrimitiveArrayCritical(env, obj, NULL); \
if (bytes == NULL) \
JNU_ThrowInternalError(env, "Unable to get array"); \
}
#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)))
#define NATIVE_METHOD(className, functionName, signature) \
{ #functionName, signature, (void*)(Java_java_nio_ ## className ## _ ## functionName) }
JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromShortArray(JNIEnv *env, jobject this, jobject src,
jlong srcPos, jlong dstAddr, jlong length)
{
jbyte *bytes;
size_t size;
jshort *srcShort, *dstShort, *endShort;
jshort tmpShort;
dstShort = (jshort *)jlong_to_ptr(dstAddr);
while (length > 0) {
/* do not change this if-else statement, see WARNING above */
if (length > MBYTE)
size = MBYTE;
else
size = (size_t)length;
GETCRITICAL(bytes, env, src);
srcShort = (jshort *)(bytes + srcPos);
endShort = srcShort + (size / sizeof(jshort));
while (srcShort < endShort) {
tmpShort = *srcShort++;
*dstShort++ = SWAPSHORT(tmpShort);
}
RELEASECRITICAL(bytes, env, src, JNI_ABORT);
length -= size;
dstAddr += size;
srcPos += size;
}
}
JNIEXPORT void JNICALL
Java_java_nio_Bits_copyToShortArray(JNIEnv *env, jobject this, jlong srcAddr,
jobject dst, jlong dstPos, jlong length)
{
jbyte *bytes;
size_t size;
jshort *srcShort, *dstShort, *endShort;
jshort tmpShort;
srcShort = (jshort *)jlong_to_ptr(srcAddr);
while (length > 0) {
/* do not change this if-else statement, see WARNING above */
if (length > MBYTE)
size = MBYTE;
else
size = (size_t)length;
GETCRITICAL(bytes, env, dst);
dstShort = (jshort *)(bytes + dstPos);
endShort = srcShort + (size / sizeof(jshort));
while (srcShort < endShort) {
tmpShort = *srcShort++;
*dstShort++ = SWAPSHORT(tmpShort);
}
RELEASECRITICAL(bytes, env, dst, 0);
length -= size;
srcAddr += size;
dstPos += size;
}
}
JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromIntArray(JNIEnv *env, jobject this, jobject src,
jlong srcPos, jlong dstAddr, jlong length)
{
jbyte *bytes;
size_t size;
jint *srcInt, *dstInt, *endInt;
jint tmpInt;
dstInt = (jint *)jlong_to_ptr(dstAddr);
while (length > 0) {
/* do not change this code, see WARNING above */
if (length > MBYTE)
size = MBYTE;
else
size = (size_t)length;
GETCRITICAL(bytes, env, src);
srcInt = (jint *)(bytes + srcPos);
endInt = srcInt + (size / sizeof(jint));
while (srcInt < endInt) {
tmpInt = *srcInt++;
*dstInt++ = SWAPINT(tmpInt);
}
RELEASECRITICAL(bytes, env, src, JNI_ABORT);
length -= size;
dstAddr += size;
srcPos += size;
}
}
JNIEXPORT void JNICALL
Java_java_nio_Bits_copyToIntArray(JNIEnv *env, jobject this, jlong srcAddr,
jobject dst, jlong dstPos, jlong length)
{
jbyte *bytes;
size_t size;
jint *srcInt, *dstInt, *endInt;
jint tmpInt;
srcInt = (jint *)jlong_to_ptr(srcAddr);
while (length > 0) {
/* do not change this code, see WARNING above */
if (length > MBYTE)
size = MBYTE;
else
size = (size_t)length;
GETCRITICAL(bytes, env, dst);
dstInt = (jint *)(bytes + dstPos);
endInt = srcInt + (size / sizeof(jint));
while (srcInt < endInt) {
tmpInt = *srcInt++;
*dstInt++ = SWAPINT(tmpInt);
}
RELEASECRITICAL(bytes, env, dst, 0);
length -= size;
srcAddr += size;
dstPos += size;
}
}
JNIEXPORT void JNICALL
Java_java_nio_Bits_copyFromLongArray(JNIEnv *env, jobject this, jobject src,
jlong srcPos, jlong dstAddr, jlong length)
{
jbyte *bytes;
size_t size;
jlong *srcLong, *dstLong, *endLong;
jlong tmpLong;
dstLong = (jlong *)jlong_to_ptr(dstAddr);
while (length > 0) {
/* do not change this code, see WARNING above */
if (length > MBYTE)
size = MBYTE;
else
size = (size_t)length;
GETCRITICAL(bytes, env, src);
srcLong = (jlong *)(bytes + srcPos);
endLong = srcLong + (size / sizeof(jlong));
while (srcLong < endLong) {
tmpLong = *srcLong++;
*dstLong++ = SWAPLONG(tmpLong);
}
RELEASECRITICAL(bytes, env, src, JNI_ABORT);
length -= size;
dstAddr += size;
srcPos += size;
}
}
JNIEXPORT void JNICALL
Java_java_nio_Bits_copyToLongArray(JNIEnv *env, jobject this, jlong srcAddr,
jobject dst, jlong dstPos, jlong length)
{
jbyte *bytes;
size_t size;
jlong *srcLong, *dstLong, *endLong;
jlong tmpLong;
srcLong = (jlong *)jlong_to_ptr(srcAddr);
while (length > 0) {
/* do not change this code, see WARNING above */
if (length > MBYTE)
size = MBYTE;
else
size = (size_t)length;
GETCRITICAL(bytes, env, dst);
dstLong = (jlong *)(bytes + dstPos);
endLong = srcLong + (size / sizeof(jlong));
while (srcLong < endLong) {
tmpLong = *srcLong++;
*dstLong++ = SWAPLONG(tmpLong);
}
RELEASECRITICAL(bytes, env, dst, 0);
length -= size;
srcAddr += size;
dstPos += size;
}
}
static JNINativeMethod gMethods[] = {
NATIVE_METHOD(Bits, copyFromShortArray, "(Ljava/lang/Object;JJJ)V"),
NATIVE_METHOD(Bits, copyToShortArray, "(JLjava/lang/Object;JJ)V"),
NATIVE_METHOD(Bits, copyFromIntArray, "(Ljava/lang/Object;JJJ)V"),
NATIVE_METHOD(Bits, copyToIntArray, "(JLjava/lang/Object;JJ)V"),
NATIVE_METHOD(Bits, copyFromLongArray, "(Ljava/lang/Object;JJJ)V"),
NATIVE_METHOD(Bits, copyToLongArray, "(JLjava/lang/Object;JJ)V"),
};
void register_java_nio_Bits(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/nio/Bits", gMethods, NELEM(gMethods));
}