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
Java_java_io_ObjectInputStream_bytesToFloats(JNIEnv * env,jclass this,jbyteArray src,jint srcpos,jfloatArray dst,jint dstpos,jint nfloats)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
Java_java_io_ObjectInputStream_bytesToDoubles(JNIEnv * env,jclass this,jbyteArray src,jint srcpos,jdoubleArray dst,jint dstpos,jint ndoubles)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
register_java_io_ObjectInputStream(JNIEnv * env)183 void register_java_io_ObjectInputStream(JNIEnv* env) {
184 jniRegisterNativeMethods(env, "java/io/ObjectInputStream", gMethods, NELEM(gMethods));
185 }
186