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