diff -r 88b85470e72c -r f50545b5e2f1 src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/algorithm/BooleanEncodingAlgorithm.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/algorithm/BooleanEncodingAlgorithm.java Tue Mar 06 16:09:35 2012 -0800 @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC. + */ + +package com.sun.xml.internal.fastinfoset.algorithm; + + +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.CharBuffer; +import java.util.ArrayList; +import java.util.List; + +import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException; +import com.sun.xml.internal.fastinfoset.CommonResourceBundle; + + +/** + * + * An encoder for handling boolean values. Suppports the builtin BOOLEAN encoder. + * + * @author Alan Hudson + * @author Paul Sandoz + * + */ +public class BooleanEncodingAlgorithm extends BuiltInEncodingAlgorithm { + + /** Table for setting a particular bit of a byte */ + private static final int[] BIT_TABLE = { + 1 << 7, + 1 << 6, + 1 << 5, + 1 << 4, + 1 << 3, + 1 << 2, + 1 << 1, + 1 << 0}; + + public int getPrimtiveLengthFromOctetLength(int octetLength) throws EncodingAlgorithmException { + // Cannot determine the number of boolean values from just the octet length + throw new UnsupportedOperationException(); + } + + public int getOctetLengthFromPrimitiveLength(int primitiveLength) { + if (primitiveLength < 5) { + return 1; + } else { + final int div = primitiveLength / 8; + return (div == 0) ? 2 : 1 + div; + } + } + + public final Object decodeFromBytes(byte[] b, int start, int length) throws EncodingAlgorithmException { + final int blength = getPrimtiveLengthFromOctetLength(length, b[start]); + boolean[] data = new boolean[blength]; + + decodeFromBytesToBooleanArray(data, 0, blength, b, start, length); + return data; + } + + public final Object decodeFromInputStream(InputStream s) throws IOException { + final List booleanList = new ArrayList(); + + int value = s.read(); + if (value == -1) { + throw new EOFException(); + } + final int unusedBits = (value >> 4) & 0xFF; + + int bitPosition = 4; + int bitPositionEnd = 8; + int valueNext = 0; + do { + valueNext = s.read(); + if (valueNext == -1) { + bitPositionEnd -= unusedBits; + } + + while(bitPosition < bitPositionEnd) { + booleanList.add( + Boolean.valueOf((value & BIT_TABLE[bitPosition++]) > 0)); + } + + value = valueNext; + } while (value != -1); + + return generateArrayFromList(booleanList); + } + + public void encodeToOutputStream(Object data, OutputStream s) throws IOException { + if (!(data instanceof boolean[])) { + throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotBoolean")); + } + + boolean array[] = (boolean[])data; + final int alength = array.length; + + final int mod = (alength + 4) % 8; + final int unusedBits = (mod == 0) ? 0 : 8 - mod; + + int bitPosition = 4; + int value = unusedBits << 4; + int astart = 0; + while (astart < alength) { + if (array[astart++]) { + value |= BIT_TABLE[bitPosition]; + } + + if (++bitPosition == 8) { + s.write(value); + bitPosition = value = 0; + } + } + + if (bitPosition != 8) { + s.write(value); + } + } + + public final Object convertFromCharacters(char[] ch, int start, int length) { + if (length == 0) { + return new boolean[0]; + } + + final CharBuffer cb = CharBuffer.wrap(ch, start, length); + final List booleanList = new ArrayList(); + + matchWhiteSpaceDelimnatedWords(cb, + new WordListener() { + public void word(int start, int end) { + if (cb.charAt(start) == 't') { + booleanList.add(Boolean.TRUE); + } else { + booleanList.add(Boolean.FALSE); + } + } + } + ); + + return generateArrayFromList(booleanList); + } + + public final void convertToCharacters(Object data, StringBuffer s) { + if (data == null) { + return; + } + + final boolean[] value = (boolean[]) data; + if (value.length == 0) { + return; + } + + // Insure conservately as all false + s.ensureCapacity(value.length * 5); + + final int end = value.length - 1; + for (int i = 0; i <= end; i++) { + if (value[i]) { + s.append("true"); + } else { + s.append("false"); + } + if (i != end) { + s.append(' '); + } + } + } + + public int getPrimtiveLengthFromOctetLength(int octetLength, int firstOctet) throws EncodingAlgorithmException { + final int unusedBits = (firstOctet >> 4) & 0xFF; + if (octetLength == 1) { + if (unusedBits > 3) { + throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.unusedBits4")); + } + return 4 - unusedBits; + } else { + if (unusedBits > 7) { + throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.unusedBits8")); + } + return octetLength * 8 - 4 - unusedBits; + } + } + + public final void decodeFromBytesToBooleanArray(boolean[] bdata, int bstart, int blength, byte[] b, int start, int length) { + int value = b[start++] & 0xFF; + int bitPosition = 4; + final int bend = bstart + blength; + while (bstart < bend) { + if (bitPosition == 8) { + value = b[start++] & 0xFF; + bitPosition = 0; + } + + bdata[bstart++] = (value & BIT_TABLE[bitPosition++]) > 0; + } + } + + public void encodeToBytes(Object array, int astart, int alength, byte[] b, int start) { + if (!(array instanceof boolean[])) { + throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.dataNotBoolean")); + } + + encodeToBytesFromBooleanArray((boolean[])array, astart, alength, b, start); + } + + public void encodeToBytesFromBooleanArray(boolean[] array, int astart, int alength, byte[] b, int start) { + final int mod = (alength + 4) % 8; + final int unusedBits = (mod == 0) ? 0 : 8 - mod; + + int bitPosition = 4; + int value = unusedBits << 4; + final int aend = astart + alength; + while (astart < aend) { + if (array[astart++]) { + value |= BIT_TABLE[bitPosition]; + } + + if (++bitPosition == 8) { + b[start++] = (byte)value; + bitPosition = value = 0; + } + } + + if (bitPosition > 0) { + b[start] = (byte)value; + } + } + + + /** + * + * Generate a boolean array from a list of Booleans. + * + * @param array The array + * + */ + private final boolean[] generateArrayFromList(List array) { + boolean[] bdata = new boolean[array.size()]; + for (int i = 0; i < bdata.length; i++) { + bdata[i] = ((Boolean)array.get(i)).booleanValue(); + } + + return bdata; + } + +}