1/*
2 * Copyright (c) 2004, 2013, 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 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
27
28package com.sun.xml.internal.fastinfoset.algorithm;
29
30import java.io.EOFException;
31import java.io.IOException;
32import java.io.InputStream;
33import java.io.OutputStream;
34import java.nio.CharBuffer;
35import java.util.ArrayList;
36import java.util.List;
37import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
38import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
39
40
41
42public class FloatEncodingAlgorithm extends IEEE754FloatingPointEncodingAlgorithm {
43
44    public final int getPrimtiveLengthFromOctetLength(int octetLength) throws EncodingAlgorithmException {
45        if (octetLength % FLOAT_SIZE != 0) {
46            throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().
47                    getString("message.lengthNotMultipleOfFloat", new Object[]{Integer.valueOf(FLOAT_SIZE)}));
48        }
49
50        return octetLength / FLOAT_SIZE;
51    }
52
53    public int getOctetLengthFromPrimitiveLength(int primitiveLength) {
54        return primitiveLength * FLOAT_SIZE;
55    }
56
57    public final Object decodeFromBytes(byte[] b, int start, int length) throws EncodingAlgorithmException {
58        float[] data = new float[getPrimtiveLengthFromOctetLength(length)];
59        decodeFromBytesToFloatArray(data, 0, b, start, length);
60
61        return data;
62    }
63
64    public final Object decodeFromInputStream(InputStream s) throws IOException {
65        return decodeFromInputStreamToFloatArray(s);
66    }
67
68
69    public void encodeToOutputStream(Object data, OutputStream s) throws IOException {
70        if (!(data instanceof float[])) {
71            throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotFloat"));
72        }
73
74        final float[] fdata = (float[])data;
75
76        encodeToOutputStreamFromFloatArray(fdata, s);
77    }
78
79    public final Object convertFromCharacters(char[] ch, int start, int length) {
80        final CharBuffer cb = CharBuffer.wrap(ch, start, length);
81        final List floatList = new ArrayList();
82
83        matchWhiteSpaceDelimnatedWords(cb,
84                new WordListener() {
85            public void word(int start, int end) {
86                String fStringValue = cb.subSequence(start, end).toString();
87                floatList.add(Float.valueOf(fStringValue));
88            }
89        }
90        );
91
92        return generateArrayFromList(floatList);
93    }
94
95    public final void convertToCharacters(Object data, StringBuffer s) {
96        if (!(data instanceof float[])) {
97            throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotFloat"));
98        }
99
100        final float[] fdata = (float[])data;
101
102        convertToCharactersFromFloatArray(fdata, s);
103    }
104
105
106    public final void decodeFromBytesToFloatArray(float[] data, int fstart, byte[] b, int start, int length) {
107        final int size = length / FLOAT_SIZE;
108        for (int i = 0; i < size; i++) {
109            final int bits = ((b[start++] & 0xFF) << 24) |
110                    ((b[start++] & 0xFF) << 16) |
111                    ((b[start++] & 0xFF) << 8) |
112                    (b[start++] & 0xFF);
113            data[fstart++] = Float.intBitsToFloat(bits);
114        }
115    }
116
117    public final float[] decodeFromInputStreamToFloatArray(InputStream s) throws IOException {
118        final List floatList = new ArrayList();
119        final byte[] b = new byte[FLOAT_SIZE];
120
121        while (true) {
122            int n = s.read(b);
123            if (n != 4) {
124                if (n == -1) {
125                    break;
126                }
127
128                while(n != 4) {
129                    final int m = s.read(b, n, FLOAT_SIZE - n);
130                    if (m == -1) {
131                        throw new EOFException();
132                    }
133                    n += m;
134                }
135            }
136
137            final int bits = ((b[0] & 0xFF) << 24) |
138                    ((b[1] & 0xFF) << 16) |
139                    ((b[2] & 0xFF) << 8) |
140                    (b[3] & 0xFF);
141            floatList.add(Float.valueOf(Float.intBitsToFloat(bits)));
142        }
143
144        return generateArrayFromList(floatList);
145    }
146
147
148    public final void encodeToOutputStreamFromFloatArray(float[] fdata, OutputStream s) throws IOException {
149        for (int i = 0; i < fdata.length; i++) {
150            final int bits = Float.floatToIntBits(fdata[i]);
151            s.write((bits >>> 24) & 0xFF);
152            s.write((bits >>> 16) & 0xFF);
153            s.write((bits >>> 8) & 0xFF);
154            s.write(bits & 0xFF);
155        }
156    }
157
158    public final void encodeToBytes(Object array, int astart, int alength, byte[] b, int start) {
159        encodeToBytesFromFloatArray((float[])array, astart, alength, b, start);
160    }
161
162    public final void encodeToBytesFromFloatArray(float[] fdata, int fstart, int flength, byte[] b, int start) {
163        final int fend = fstart + flength;
164        for (int i = fstart; i < fend; i++) {
165            final int bits = Float.floatToIntBits(fdata[i]);
166            b[start++] = (byte)((bits >>> 24) & 0xFF);
167            b[start++] = (byte)((bits >>> 16) & 0xFF);
168            b[start++] = (byte)((bits >>>  8) & 0xFF);
169            b[start++] = (byte)(bits & 0xFF);
170        }
171    }
172
173
174    public final void convertToCharactersFromFloatArray(float[] fdata, StringBuffer s) {
175        final int end = fdata.length - 1;
176        for (int i = 0; i <= end; i++) {
177            s.append(Float.toString(fdata[i]));
178            if (i != end) {
179                s.append(' ');
180            }
181        }
182    }
183
184
185    public final float[] generateArrayFromList(List array) {
186        float[] fdata = new float[array.size()];
187        for (int i = 0; i < fdata.length; i++) {
188            fdata[i] = ((Float)array.get(i)).floatValue();
189        }
190
191        return fdata;
192    }
193
194}
195