/* XXL: The eXtensible and fleXible Library for data processing Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger Head of the Database Research Group Department of Mathematics and Computer Science University of Marburg Germany This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; If not, see <http://www.gnu.org/licenses/>. http://code.google.com/p/xxl/ */ package xxl.core.io.converters; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; /** * This class provides a converter that is able to read and write arrays of * <code>boolean</code> values. First the converter reads or writes the length * of the <code>boolean</code> array, if necessary. Thereafter the * <code>boolean</code> values are read or written (8 booleans per byte). * * <p>Example usage (1). * <code><pre> * // create an boolean array * * boolean[] array = {true, false, false, true}; * * // create a byte array output stream * * ByteArrayOutputStream output = new ByteArrayOutputStream(); * * // write array to the output stream * * BooleanArrayConverter.DEFAULT_INSTANCE.write(new DataOutputStream(output), array); * * // create a byte array input stream on the output stream * * ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray()); * * // reset the array * * array = null; * * // read array from the input stream * * array = BooleanArrayConverter.DEFAULT_INSTANCE.read(new DataInputStream(input)); * * // print the array * * for (boolean b : array) * System.out.println(b); * * // close the streams after use * * input.close(); * output.close(); * </pre></code></p> * * @see DataInput * @see DataOutput * @see IOException */ public class BooleanArrayConverter extends SizeConverter<boolean[]> { /** * This instance can be used for getting a default instance of a boolean * array converter. It is similar to the <i>Singleton Design Pattern</i> * (for further details see Creational Patterns, Prototype in <i>Design * Patterns: Elements of Reusable Object-Oriented Software</i> by Erich * Gamma, Richard Helm, Ralph Johnson, and John Vlissides) except that * there are no mechanisms to avoid the creation of other instances of a * boolean array converter. */ public static final BooleanArrayConverter DEFAULT_INSTANCE = new BooleanArrayConverter(); /** * Determines the length of the conversion of a boolean array. * * @param withLengthInfo has to be <code>true</code> iff the length info of * the array has to be stored. * @param len the length of the boolean array to be stored. * @return the length of the conversion of a boolean array in bytes. */ public static int getSizeForArray(boolean withLengthInfo, int len) { return (withLengthInfo ? 4 : 0) + (len+7)>>3; // >>3 <=> /8 } /** * Determines the length of the array. If it is <code>-1</code>, then the * size information is also serialized. */ protected int arraySize; /** * Constructors a boolean array converter which not necessarily * serializes/deserializes the length of the array. * * @param arraySize if <code>-1</code> then the size is * serialized/deserialized. Else this int value represents the * number of <code>boolean</code>s which are * serialized/deserialized. */ public BooleanArrayConverter(int arraySize) { this.arraySize = arraySize; } /** * Constructors a boolean array converter which also * serializes/deserializes the length of the array. */ public BooleanArrayConverter() { this(-1); } /** * Reads an array of <code>boolean</code> values from the specified data * input and returns the restored <code>boolean</code> array. * * @param dataInput the stream to read the <code>boolean</code> array from. * @param object the <code>boolean</code> array to be restored. The size of * the <code>boolean</code> array has to be sufficient! If this * parameter is <code>null</code>, then a new array is constructed. * @return the read array of <code>boolean</code> values. * @throws IOException if I/O errors occur. */ @Override public boolean[] read(DataInput dataInput, boolean[] object) throws IOException { int len = arraySize; if (arraySize == -1) len = dataInput.readInt(); if (object == null) object = new boolean[len]; byte b = 0; for (int i = 0; i < len; i++) { if ((i&7) == 0) // i mod 8 == 0 b = dataInput.readByte(); object[i] = b<0; b <<= 1; } return object; } /** * Writes the specified array of <code>boolean</code> values to the * specified data output. * * <p>This implementation first writes the length of the array to the data * output. Thereafter the <code>boolean</code> values are written.</p> * * @param dataOutput the stream to write the <code>boolean</code> array to. * @param object the <code>boolean</code> array that should be written to * the data output. * @throws IOException includes any I/O exceptions that may occur. */ @Override public void write(DataOutput dataOutput, boolean[] object) throws IOException { byte b = 0; int i = 0; int len = arraySize; if (len == -1) { dataOutput.writeInt(object.length); len = object.length; } while (i < len) { b <<= 1; if (object[i]) b++; if ((++i&7) == 0) { dataOutput.writeByte(b); b = 0; } } if ((i&7) != 0) { b <<= 8-(i&7); dataOutput.write(b); } } /** * Determines the size of the <code>boolean</code> array in bytes. * * @param object a boolean array. * @return the size of the <code>boolean</code> array in bytes. * @see xxl.core.io.converters.SizeConverter#getSerializedSize(java.lang.Object) */ @Override public int getSerializedSize(boolean[] object) { return arraySize == -1 ? getSizeForArray(true, object.length) : getSizeForArray(false, arraySize); } }