1 /* 2 * Copyright (c) 1999, 2013, 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_util.h" 27 #include "jdk_util.h" 28 29 #include "java_lang_Float.h" 30 #include "java_lang_Double.h" 31 #include "java_io_ObjectOutputStream.h" 32 33 /* 34 * Class: java_io_ObjectOutputStream 35 * Method: floatsToBytes 36 * Signature: ([FI[BII)V 37 * 38 * Convert nfloats float values to their byte representations. Float values 39 * are read from array src starting at offset srcpos and written to array 40 * dst starting at offset dstpos. 41 */ 42 JNIEXPORT void JNICALL 43 Java_java_io_ObjectOutputStream_floatsToBytes(JNIEnv *env, 44 jclass this, 45 jfloatArray src, 46 jint srcpos, 47 jbyteArray dst, 48 jint dstpos, 49 jint nfloats) 50 { 51 union { 52 int i; 53 float f; 54 } u; 55 jfloat *floats; 56 jbyte *bytes; 57 jsize srcend; 58 jint ival; 59 float fval; 60 61 if (nfloats == 0) 62 return; 63 64 /* fetch source array */ 65 if (src == NULL) { 66 JNU_ThrowNullPointerException(env, NULL); 67 return; 68 } 69 floats = (*env)->GetPrimitiveArrayCritical(env, src, NULL); 70 if (floats == NULL) /* exception thrown */ 71 return; 72 73 /* fetch dest array */ 74 if (dst == NULL) { 75 (*env)->ReleasePrimitiveArrayCritical(env, src, floats, JNI_ABORT); 76 JNU_ThrowNullPointerException(env, NULL); 77 return; 78 } 79 bytes = (*env)->GetPrimitiveArrayCritical(env, dst, NULL); 80 if (bytes == NULL) { /* exception thrown */ 81 (*env)->ReleasePrimitiveArrayCritical(env, src, floats, JNI_ABORT); 82 return; 83 } 84 85 /* do conversion */ 86 srcend = srcpos + nfloats; 87 for ( ; srcpos < srcend; srcpos++) { 88 fval = (float) floats[srcpos]; 89 if (ISNANF(fval)) { /* collapse NaNs */ 90 ival = 0x7fc00000; 91 } else { 92 u.f = fval; 93 ival = (jint) u.i; 94 } 95 bytes[dstpos++] = (ival >> 24) & 0xFF; 96 bytes[dstpos++] = (ival >> 16) & 0xFF; 97 bytes[dstpos++] = (ival >> 8) & 0xFF; 98 bytes[dstpos++] = (ival >> 0) & 0xFF; 99 } 100 101 (*env)->ReleasePrimitiveArrayCritical(env, src, floats, JNI_ABORT); 102 (*env)->ReleasePrimitiveArrayCritical(env, dst, bytes, 0); 103 } 104 105 /* 106 * Class: java_io_ObjectOutputStream 107 * Method: doublesToBytes 108 * Signature: ([DI[BII)V 109 * 110 * Convert ndoubles double values to their byte representations. Double 111 * values are read from array src starting at offset srcpos and written to 112 * array dst starting at offset dstpos. 113 */ 114 JNIEXPORT void JNICALL 115 Java_java_io_ObjectOutputStream_doublesToBytes(JNIEnv *env, 116 jclass this, 117 jdoubleArray src, 118 jint srcpos, 119 jbyteArray dst, 120 jint dstpos, 121 jint ndoubles) 122 { 123 union { 124 jlong l; 125 double d; 126 } u; 127 jdouble *doubles; 128 jbyte *bytes; 129 jsize srcend; 130 jdouble dval; 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 doubles = (*env)->GetPrimitiveArrayCritical(env, src, NULL); 142 if (doubles == NULL) /* exception thrown */ 143 return; 144 145 /* fetch dest array */ 146 if (dst == NULL) { 147 (*env)->ReleasePrimitiveArrayCritical(env, src, doubles, JNI_ABORT); 148 JNU_ThrowNullPointerException(env, NULL); 149 return; 150 } 151 bytes = (*env)->GetPrimitiveArrayCritical(env, dst, NULL); 152 if (bytes == NULL) { /* exception thrown */ 153 (*env)->ReleasePrimitiveArrayCritical(env, src, doubles, JNI_ABORT); 154 return; 155 } 156 157 /* do conversion */ 158 srcend = srcpos + ndoubles; 159 for ( ; srcpos < srcend; srcpos++) { 160 dval = doubles[srcpos]; 161 if (ISNAND((double) dval)) { /* collapse NaNs */ 162 lval = jint_to_jlong(0x7ff80000); 163 lval = jlong_shl(lval, 32); 164 } else { 165 jdouble_to_jlong_bits(&dval); 166 u.d = (double) dval; 167 lval = u.l; 168 } 169 bytes[dstpos++] = (lval >> 56) & 0xFF; 170 bytes[dstpos++] = (lval >> 48) & 0xFF; 171 bytes[dstpos++] = (lval >> 40) & 0xFF; 172 bytes[dstpos++] = (lval >> 32) & 0xFF; 173 bytes[dstpos++] = (lval >> 24) & 0xFF; 174 bytes[dstpos++] = (lval >> 16) & 0xFF; 175 bytes[dstpos++] = (lval >> 8) & 0xFF; 176 bytes[dstpos++] = (lval >> 0) & 0xFF; 177 } 178 179 (*env)->ReleasePrimitiveArrayCritical(env, src, doubles, JNI_ABORT); 180 (*env)->ReleasePrimitiveArrayCritical(env, dst, bytes, 0); 181 }