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