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