Home | History | Annotate | Download | only in native
      1 /*
      2  * Copyright (c) 1999, 2000, 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  * Class:     java_io_ObjectOutputStream
     39  * Method:    floatsToBytes
     40  * Signature: ([FI[BII)V
     41  *
     42  * Convert nfloats float values to their byte representations.  Float values
     43  * are read from array src starting at offset srcpos and written to array
     44  * dst starting at offset dstpos.
     45  */
     46 JNIEXPORT void JNICALL
     47 Java_java_io_ObjectOutputStream_floatsToBytes(JNIEnv *env,
     48                                               jclass this,
     49                                               jfloatArray src,
     50                                               jint srcpos,
     51                                               jbyteArray dst,
     52                                               jint dstpos,
     53                                               jint nfloats)
     54 {
     55     union {
     56         int i;
     57         float f;
     58     } u;
     59     jfloat *floats;
     60     jbyte *bytes;
     61     jsize srcend;
     62     jint ival;
     63     float fval;
     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     floats = (*env)->GetPrimitiveArrayCritical(env, src, NULL);
     74     if (floats == NULL)         /* exception thrown */
     75         return;
     76 
     77     /* fetch dest array */
     78     if (dst == NULL) {
     79         (*env)->ReleasePrimitiveArrayCritical(env, src, floats, JNI_ABORT);
     80         JNU_ThrowNullPointerException(env, NULL);
     81         return;
     82     }
     83     bytes = (*env)->GetPrimitiveArrayCritical(env, dst, NULL);
     84     if (bytes == NULL) {        /* exception thrown */
     85         (*env)->ReleasePrimitiveArrayCritical(env, src, floats, JNI_ABORT);
     86         return;
     87     }
     88 
     89     /* do conversion */
     90     srcend = srcpos + nfloats;
     91     for ( ; srcpos < srcend; srcpos++) {
     92         fval = (float) floats[srcpos];
     93         if (JVM_IsNaN(fval)) {          /* collapse NaNs */
     94             ival = 0x7fc00000;
     95         } else {
     96             u.f = fval;
     97             ival = (jint) u.i;
     98         }
     99         bytes[dstpos++] = (ival >> 24) & 0xFF;
    100         bytes[dstpos++] = (ival >> 16) & 0xFF;
    101         bytes[dstpos++] = (ival >> 8) & 0xFF;
    102         bytes[dstpos++] = (ival >> 0) & 0xFF;
    103     }
    104 
    105     (*env)->ReleasePrimitiveArrayCritical(env, src, floats, JNI_ABORT);
    106     (*env)->ReleasePrimitiveArrayCritical(env, dst, bytes, 0);
    107 }
    108 
    109 /*
    110  * Class:     java_io_ObjectOutputStream
    111  * Method:    doublesToBytes
    112  * Signature: ([DI[BII)V
    113  *
    114  * Convert ndoubles double values to their byte representations.  Double
    115  * values are read from array src starting at offset srcpos and written to
    116  * array dst starting at offset dstpos.
    117  */
    118 JNIEXPORT void JNICALL
    119 Java_java_io_ObjectOutputStream_doublesToBytes(JNIEnv *env,
    120                                                jclass this,
    121                                                jdoubleArray src,
    122                                                jint srcpos,
    123                                                jbyteArray dst,
    124                                                jint dstpos,
    125                                                jint ndoubles)
    126 {
    127     union {
    128         jlong l;
    129         double d;
    130     } u;
    131     jdouble *doubles;
    132     jbyte *bytes;
    133     jsize srcend;
    134     jdouble dval;
    135     jlong lval;
    136 
    137     if (ndoubles == 0)
    138         return;
    139 
    140     /* fetch source array */
    141     if (src == NULL) {
    142         JNU_ThrowNullPointerException(env, NULL);
    143         return;
    144     }
    145     doubles = (*env)->GetPrimitiveArrayCritical(env, src, NULL);
    146     if (doubles == NULL)                /* exception thrown */
    147         return;
    148 
    149     /* fetch dest array */
    150     if (dst == NULL) {
    151         (*env)->ReleasePrimitiveArrayCritical(env, src, doubles, JNI_ABORT);
    152         JNU_ThrowNullPointerException(env, NULL);
    153         return;
    154     }
    155     bytes = (*env)->GetPrimitiveArrayCritical(env, dst, NULL);
    156     if (bytes == NULL) {        /* exception thrown */
    157         (*env)->ReleasePrimitiveArrayCritical(env, src, doubles, JNI_ABORT);
    158         return;
    159     }
    160 
    161     /* do conversion */
    162     srcend = srcpos + ndoubles;
    163     for ( ; srcpos < srcend; srcpos++) {
    164         dval = doubles[srcpos];
    165         if (JVM_IsNaN((double) dval)) {         /* collapse NaNs */
    166             lval = jint_to_jlong(0x7ff80000);
    167             lval = jlong_shl(lval, 32);
    168         } else {
    169             jdouble_to_jlong_bits(&dval);
    170             u.d = (double) dval;
    171             lval = u.l;
    172         }
    173         bytes[dstpos++] = (lval >> 56) & 0xFF;
    174         bytes[dstpos++] = (lval >> 48) & 0xFF;
    175         bytes[dstpos++] = (lval >> 40) & 0xFF;
    176         bytes[dstpos++] = (lval >> 32) & 0xFF;
    177         bytes[dstpos++] = (lval >> 24) & 0xFF;
    178         bytes[dstpos++] = (lval >> 16) & 0xFF;
    179         bytes[dstpos++] = (lval >> 8) & 0xFF;
    180         bytes[dstpos++] = (lval >> 0) & 0xFF;
    181     }
    182 
    183     (*env)->ReleasePrimitiveArrayCritical(env, src, doubles, JNI_ABORT);
    184     (*env)->ReleasePrimitiveArrayCritical(env, dst, bytes, 0);
    185 }
    186 
    187 static JNINativeMethod gMethods[] = {
    188     NATIVE_METHOD(ObjectOutputStream, floatsToBytes, "([FI[BII)V"),
    189     NATIVE_METHOD(ObjectOutputStream, doublesToBytes, "([DI[BII)V"),
    190 };
    191 
    192 void register_java_io_ObjectOutputStream(JNIEnv* env) {
    193     jniRegisterNativeMethods(env, "java/io/ObjectOutputStream", gMethods, NELEM(gMethods));
    194 }
    195