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