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