1/*
2 * Copyright (c) 2004, 2012, 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/**
42 * An encoder for handling Short values.  Suppports the builtin SHORT encoder.
43 *
44 * @author Alan Hudson
45 * @author Paul Sandoz
46 */
47public class ShortEncodingAlgorithm extends IntegerEncodingAlgorithm {
48
49    public final int getPrimtiveLengthFromOctetLength(int octetLength) throws EncodingAlgorithmException {
50        if (octetLength % SHORT_SIZE != 0) {
51            throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().
52                    getString("message.lengthNotMultipleOfShort", new Object[]{Integer.valueOf(SHORT_SIZE)}));
53        }
54
55        return octetLength / SHORT_SIZE;
56    }
57
58    public int getOctetLengthFromPrimitiveLength(int primitiveLength) {
59        return primitiveLength * SHORT_SIZE;
60    }
61
62    public final Object decodeFromBytes(byte[] b, int start, int length) throws EncodingAlgorithmException {
63        short[] data = new short[getPrimtiveLengthFromOctetLength(length)];
64        decodeFromBytesToShortArray(data, 0, b, start, length);
65
66        return data;
67    }
68
69    public final Object decodeFromInputStream(InputStream s) throws IOException {
70        return decodeFromInputStreamToShortArray(s);
71    }
72
73
74    public void encodeToOutputStream(Object data, OutputStream s) throws IOException {
75        if (!(data instanceof short[])) {
76            throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotShortArray"));
77        }
78
79        final short[] idata = (short[])data;
80
81        encodeToOutputStreamFromShortArray(idata, s);
82    }
83
84
85    public final Object convertFromCharacters(char[] ch, int start, int length) {
86        final CharBuffer cb = CharBuffer.wrap(ch, start, length);
87        final List shortList = new ArrayList();
88
89        matchWhiteSpaceDelimnatedWords(cb,
90                new WordListener() {
91            public void word(int start, int end) {
92                String iStringValue = cb.subSequence(start, end).toString();
93                shortList.add(Short.valueOf(iStringValue));
94            }
95        }
96        );
97
98        return generateArrayFromList(shortList);
99    }
100
101    public final void convertToCharacters(Object data, StringBuffer s) {
102        if (!(data instanceof short[])) {
103            throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotShortArray"));
104        }
105
106        final short[] idata = (short[])data;
107
108        convertToCharactersFromShortArray(idata, s);
109    }
110
111
112    public final void decodeFromBytesToShortArray(short[] sdata, int istart, byte[] b, int start, int length) {
113        final int size = length / SHORT_SIZE;
114        for (int i = 0; i < size; i++) {
115            sdata[istart++] = (short) (((b[start++] & 0xFF) << 8) |
116                    (b[start++] & 0xFF));
117        }
118    }
119
120    public final short[] decodeFromInputStreamToShortArray(InputStream s) throws IOException {
121        final List shortList = new ArrayList();
122        final byte[] b = new byte[SHORT_SIZE];
123
124        while (true) {
125            int n = s.read(b);
126            if (n != 2) {
127                if (n == -1) {
128                    break;
129                }
130
131                while(n != 2) {
132                    final int m = s.read(b, n, SHORT_SIZE - n);
133                    if (m == -1) {
134                        throw new EOFException();
135                    }
136                    n += m;
137                }
138            }
139
140            final int i = ((b[0] & 0xFF) << 8) |
141                    (b[1] & 0xFF);
142            shortList.add(Short.valueOf((short)i));
143        }
144
145        return generateArrayFromList(shortList);
146    }
147
148
149    public final void encodeToOutputStreamFromShortArray(short[] idata, OutputStream s) throws IOException {
150        for (int i = 0; i < idata.length; i++) {
151            final int bits = idata[i];
152            s.write((bits >>> 8) & 0xFF);
153            s.write(bits & 0xFF);
154        }
155    }
156
157    public final void encodeToBytes(Object array, int astart, int alength, byte[] b, int start) {
158        encodeToBytesFromShortArray((short[])array, astart, alength, b, start);
159    }
160
161    public final void encodeToBytesFromShortArray(short[] sdata, int istart, int ilength, byte[] b, int start) {
162        final int iend = istart + ilength;
163        for (int i = istart; i < iend; i++) {
164            final short bits = sdata[i];
165            b[start++] = (byte)((bits >>> 8) & 0xFF);
166            b[start++] = (byte)(bits & 0xFF);
167        }
168    }
169
170
171    public final void convertToCharactersFromShortArray(short[] sdata, StringBuffer s) {
172        final int end = sdata.length - 1;
173        for (int i = 0; i <= end; i++) {
174            s.append(Short.toString(sdata[i]));
175            if (i != end) {
176                s.append(' ');
177            }
178        }
179    }
180
181
182    public final short[] generateArrayFromList(List array) {
183        short[] sdata = new short[array.size()];
184        for (int i = 0; i < sdata.length; i++) {
185            sdata[i] = ((Short)array.get(i)).shortValue();
186        }
187
188        return sdata;
189    }
190}
191