Home | History | Annotate | Download | only in native
      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
     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
    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
    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
    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
    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
    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 
    294 void register_java_nio_Bits(JNIEnv* env) {
    295     jniRegisterNativeMethods(env, "java/nio/Bits", gMethods, NELEM(gMethods));
    296 }
    297