Home | History | Annotate | Download | only in native
      1 /*
      2  * Copyright (c) 1996, 2011, 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 #include "jni.h"
     27 #include "jvm.h"
     28 #include "jni_util.h"
     29 #include "jlong.h"
     30 
     31 #include <nativehelper/JNIHelp.h>
     32 
     33 #define NATIVE_METHOD(className, functionName, signature) \
     34 { #functionName, signature, (void*)(Java_java_io_ ## className ## _ ## functionName) }
     35 
     36 
     37 
     38 /*
     39  * Class:     java_io_ObjectInputStream
     40  * Method:    bytesToFloats
     41  * Signature: ([BI[FII)V
     42  *
     43  * Reconstitutes nfloats float values from their byte representations.  Byte
     44  * values are read from array src starting at offset srcpos; the resulting
     45  * float values are written to array dst starting at dstpos.
     46  */
     47 JNIEXPORT void JNICALL
     48 Java_java_io_ObjectInputStream_bytesToFloats(JNIEnv *env,
     49                                              jclass this,
     50                                              jbyteArray src,
     51                                              jint srcpos,
     52                                              jfloatArray dst,
     53                                              jint dstpos,
     54                                              jint nfloats)
     55 {
     56     union {
     57         int i;
     58         float f;
     59     } u;
     60     jfloat *floats;
     61     jbyte *bytes;
     62     jsize dstend;
     63     jint ival;
     64 
     65     if (nfloats == 0)
     66         return;
     67 
     68     /* fetch source array */
     69     if (src == NULL) {
     70         JNU_ThrowNullPointerException(env, NULL);
     71         return;
     72     }
     73     bytes = (*env)->GetPrimitiveArrayCritical(env, src, NULL);
     74     if (bytes == NULL)          /* exception thrown */
     75         return;
     76 
     77     /* fetch dest array */
     78     if (dst == NULL) {
     79         (*env)->ReleasePrimitiveArrayCritical(env, src, bytes, JNI_ABORT);
     80         JNU_ThrowNullPointerException(env, NULL);
     81         return;
     82     }
     83     floats = (*env)->GetPrimitiveArrayCritical(env, dst, NULL);
     84     if (floats == NULL) {       /* exception thrown */
     85         (*env)->ReleasePrimitiveArrayCritical(env, src, bytes, JNI_ABORT);
     86         return;
     87     }
     88 
     89     /* do conversion */
     90     dstend = dstpos + nfloats;
     91     for ( ; dstpos < dstend; dstpos++) {
     92         ival = ((bytes[srcpos + 0] & 0xFF) << 24) +
     93                ((bytes[srcpos + 1] & 0xFF) << 16) +
     94                ((bytes[srcpos + 2] & 0xFF) << 8) +
     95                ((bytes[srcpos + 3] & 0xFF) << 0);
     96         u.i = (long) ival;
     97         floats[dstpos] = (jfloat) u.f;
     98         srcpos += 4;
     99     }
    100 
    101     (*env)->ReleasePrimitiveArrayCritical(env, src, bytes, JNI_ABORT);
    102     (*env)->ReleasePrimitiveArrayCritical(env, dst, floats, 0);
    103 }
    104 
    105 /*
    106  * Class:     java_io_ObjectInputStream
    107  * Method:    bytesToDoubles
    108  * Signature: ([BI[DII)V
    109  *
    110  * Reconstitutes ndoubles double values from their byte representations.
    111  * Byte values are read from array src starting at offset srcpos; the
    112  * resulting double values are written to array dst starting at dstpos.
    113  */
    114 JNIEXPORT void JNICALL
    115 Java_java_io_ObjectInputStream_bytesToDoubles(JNIEnv *env,
    116                                               jclass this,
    117                                               jbyteArray src,
    118                                               jint srcpos,
    119                                               jdoubleArray dst,
    120                                               jint dstpos,
    121                                               jint ndoubles)
    122 
    123 {
    124     union {
    125         jlong l;
    126         double d;
    127     } u;
    128     jdouble *doubles;
    129     jbyte *bytes;
    130     jsize dstend;
    131     jlong lval;
    132 
    133     if (ndoubles == 0)
    134         return;
    135 
    136     /* fetch source array */
    137     if (src == NULL) {
    138         JNU_ThrowNullPointerException(env, NULL);
    139         return;
    140     }
    141     bytes = (*env)->GetPrimitiveArrayCritical(env, src, NULL);
    142     if (bytes == NULL)          /* exception thrown */
    143         return;
    144 
    145     /* fetch dest array */
    146     if (dst == NULL) {
    147         (*env)->ReleasePrimitiveArrayCritical(env, src, bytes, JNI_ABORT);
    148         JNU_ThrowNullPointerException(env, NULL);
    149         return;
    150     }
    151     doubles = (*env)->GetPrimitiveArrayCritical(env, dst, NULL);
    152     if (doubles == NULL) {      /* exception thrown */
    153         (*env)->ReleasePrimitiveArrayCritical(env, src, bytes, JNI_ABORT);
    154         return;
    155     }
    156 
    157     /* do conversion */
    158     dstend = dstpos + ndoubles;
    159     for ( ; dstpos < dstend; dstpos++) {
    160         lval = (((jlong) bytes[srcpos + 0] & 0xFF) << 56) +
    161                (((jlong) bytes[srcpos + 1] & 0xFF) << 48) +
    162                (((jlong) bytes[srcpos + 2] & 0xFF) << 40) +
    163                (((jlong) bytes[srcpos + 3] & 0xFF) << 32) +
    164                (((jlong) bytes[srcpos + 4] & 0xFF) << 24) +
    165                (((jlong) bytes[srcpos + 5] & 0xFF) << 16) +
    166                (((jlong) bytes[srcpos + 6] & 0xFF) << 8) +
    167                (((jlong) bytes[srcpos + 7] & 0xFF) << 0);
    168         jlong_to_jdouble_bits(&lval);
    169         u.l = lval;
    170         doubles[dstpos] = (jdouble) u.d;
    171         srcpos += 8;
    172     }
    173 
    174     (*env)->ReleasePrimitiveArrayCritical(env, src, bytes, JNI_ABORT);
    175     (*env)->ReleasePrimitiveArrayCritical(env, dst, doubles, 0);
    176 }
    177 
    178 static JNINativeMethod gMethods[] = {
    179     NATIVE_METHOD(ObjectInputStream, bytesToFloats, "([BI[FII)V"),
    180     NATIVE_METHOD(ObjectInputStream, bytesToDoubles, "([BI[DII)V"),
    181 };
    182 
    183 void register_java_io_ObjectInputStream(JNIEnv* env) {
    184     jniRegisterNativeMethods(env, "java/io/ObjectInputStream", gMethods, NELEM(gMethods));
    185 }
    186