/* ******************************************************************************* * Copyright (C) 1996-2009, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ package com.ibm.icu.dev.test.util; import java.io.DataInput; import java.io.IOException; import java.io.ObjectInput; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import com.ibm.icu.text.UTF16; /** * Simple data input compressor. Nothing fancy, but much smaller footprint for * ints and many strings. */ public final class DataInputCompressor implements ObjectInput { static final boolean SHOW = false; private ObjectInput dataInput; private transient StringBuffer stringBuffer = new StringBuffer(); public DataInputCompressor(ObjectInput dataInput) { this.dataInput = dataInput; } public DataInput getDataInput() { return dataInput; } public void setDataInput(ObjectInput dataInput) { this.dataInput = dataInput; } public boolean readBoolean() throws IOException { return dataInput.readBoolean(); } public byte readByte() throws IOException { return dataInput.readByte(); } public int readUnsignedByte() throws IOException { return dataInput.readUnsignedByte(); } public double readDouble() throws IOException { return dataInput.readDouble(); } public float readFloat() throws IOException { return dataInput.readFloat(); } public void readFully(byte[] b) throws IOException { dataInput.readFully(b); } public void readFully(byte[] b, int off, int len) throws IOException { dataInput.readFully(b, off, len); } public int skipBytes(int n) throws IOException { return dataInput.skipBytes(n); } public String readLine() throws IOException { return dataInput.readLine(); } public int available() throws IOException { return dataInput.available(); } public void close() throws IOException { dataInput.close(); } public int read() throws IOException { return dataInput.read(); } public int read(byte[] b) throws IOException { return dataInput.read(b); } public int read(byte[] b, int off, int len) throws IOException { return dataInput.read(b, off, len); } public Object readObject() throws ClassNotFoundException, IOException { return dataInput.readObject(); } public long skip(long n) throws IOException { return dataInput.skip(n); } public String toString() { return dataInput.toString(); } // ==== New Routines ==== public char readChar() throws IOException { return (char) readULong(); } public short readShort() throws IOException { return (short) readLong(); } public int readUnsignedShort() throws IOException { return (int) readULong(); } public int readUShort() throws IOException { return (int) readULong(); } public int readInt() throws IOException { return (int) readLong(); } public int readUInt() throws IOException { return (int) readULong(); } public String readChars(int len) throws IOException { stringBuffer.setLength(0); for (int i = 0; i < len; ++i) { int cp = (int) readULong(); UTF16.append(stringBuffer, cp); } return stringBuffer.toString(); } public String readUTF() throws IOException { int len = (int) readULong(); return readChars(len); } public long readLong() throws IOException { long result = 0; int offset = 0; while (true) { long input = readByte(); result |= (input & 0x7F) << offset; if ((input & 0x80) == 0) break; offset += 7; } boolean negative = (result & 1) != 0; // get sign bit from the bottom, // and invert result >>>= 1; if (negative) result = ~result; return result; } public long readULong() throws IOException { long result = 0; int offset = 0; while (true) { // read sequence of 7 bits, with top bit = 1 for // continuation int input = readByte(); result |= (input & 0x7F) << offset; if ((input & 0x80) == 0) return result; offset += 7; } } /** * */ public Object[] readStringSet(Collection availableValues) throws IOException { int size = readUInt(); if (SHOW) System.out.println("readStringSet"); Object[] valuesList = new Object[size + 1]; // first item is null String lastString = ""; ReadPool trailingPool = new ReadPool(); for (int i = 0; i < size; ++i) { int common = readUInt(); boolean inPool = (common & 1) != 0; common >>>= 1; if (SHOW) System.out.println(common); String current; if (inPool) { int poolIndex = readUInt(); if (SHOW) System.out.println("\t" + poolIndex); current = (String) trailingPool.get(poolIndex); } else { current = readUTF(); trailingPool.add(current); } valuesList[i + 1] = lastString = lastString.substring(0, common) + current; if (SHOW) System.out.println("\t\t" + lastString); if (availableValues != null) availableValues.add(current); } return valuesList; } public static class ReadPool { private List trailingPool = new ArrayList(); public Object get(int index) { return trailingPool.get(index); } public void add(Object o) { trailingPool.add(o); } } /** * @throws IOException * @throws ClassNotFoundException * */ public Object[] readCollection(LinkedHashSet availableValues) throws ClassNotFoundException, IOException { int size = readUInt(); Object[] valuesList = new Object[size + 1]; for (int i = 0; i < size; ++i) { valuesList[i + 1] = readObject(); } return valuesList; } }