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 | */ |
45 | JNIEXPORT void JNICALL |
46 | Java_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 | */ |
112 | JNIEXPORT void JNICALL |
113 | Java_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 | |