blob: 0d31009141d03407f2f7059e13a7c0bc14836791 [file] [log] [blame]
/*
*******************************************************************************
* Copyright (C) 1996-2009, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
package com.ibm.icu.dev.test.util;
import java.io.DataOutput;
import java.io.IOException;
import java.io.ObjectOutput;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedSet;
import com.ibm.icu.text.UTF16;
/**
* Simple data output compressor. Nothing fancy, but much smaller footprint for ints and many strings.
*/
public final class DataOutputCompressor implements ObjectOutput {
static final boolean SHOW = false;
private ObjectOutput dataOutput;
public DataOutputCompressor(ObjectOutput dataOutput) {
this.dataOutput = dataOutput;
}
public DataOutput getDataOutput() {
return dataOutput;
}
public void setDataOutput(ObjectOutput dataOutput) {
this.dataOutput = dataOutput;
}
public void write(byte[] b) throws IOException {
dataOutput.write(b);
}
public void write(byte[] b, int off, int len) throws IOException {
dataOutput.write(b, off, len);
}
public void write(int b) throws IOException {
dataOutput.write(b);
}
public void writeBoolean(boolean v) throws IOException {
dataOutput.writeBoolean(v);
}
public void writeByte(int v) throws IOException {
dataOutput.writeByte(v);
}
public void writeBytes(String s) throws IOException {
dataOutput.writeBytes(s);
}
public void writeDouble(double v) throws IOException {
dataOutput.writeDouble(v);
}
public void writeFloat(float v) throws IOException {
dataOutput.writeFloat(v);
}
public void close() throws IOException {
dataOutput.close();
}
public void flush() throws IOException {
dataOutput.flush();
}
public String toString() {
return dataOutput.toString();
}
public void writeObject(Object obj) throws IOException {
dataOutput.writeObject(obj);
}
// ==== New Routines ====
public void writeChar(int v) throws IOException {
writeULong(v);
}
public void writeShort(int v) throws IOException {
writeLong(v);
}
public void writeUShort(int v) throws IOException {
writeULong(v);
}
public void writeInt(int v) throws IOException {
writeLong(v);
}
public void writeUInt(int v) throws IOException {
writeULong(v);
}
public void writeUTF(String str) throws IOException {
writeULong(UTF16.countCodePoint(str));
writeChars(str);
}
public void writeChars(String s) throws IOException {
int cp = 0;
for (int i = 0; i < s.length(); i += UTF16.getCharCount(cp)) {
cp = UTF16.charAt(s, i);
writeULong(cp);
}
}
public void writeLong(long v) throws IOException {
long flag = 0; // put sign bit at the bottom, and invert
if (v < 0) {
v = ~v;
flag = 1;
}
v <<= 1;
v |= flag;
while (true) {
if ((v & ~0x7FL) == 0) {
dataOutput.writeByte((byte) v);
break;
}
dataOutput.writeByte((byte) (0x80L | v));
v >>>= 7;
}
}
public void writeULong(long v) throws IOException {
while (true) { // write sequence of 7 bits, with top bit = 1 for continuation
if ((v & ~0x7FL) == 0) {
dataOutput.writeByte((byte) v);
break;
}
dataOutput.writeByte((byte) (0x80L | v));
v >>>= 7;
}
}
/**
*
*/
public void writeStringSet(SortedSet c, Map object_index) throws IOException {
if (SHOW) System.out.println("writeStringSet");
writeUInt(c.size());
int i = 0;
object_index.put(null, new Integer(i++));
WritePool trailingPool = new WritePool();
String lastString = "";
for (Iterator it = c.iterator(); it.hasNext();) {
String s = (String) it.next();
object_index.put(s, new Integer(i++));
int common = UnicodeMap.findCommonPrefix(lastString, s); // runlength encode
lastString = s;
String piece = s.substring(common);
if (SHOW) System.out.println(common);
common <<= 1;
int inPool = trailingPool.getIndex(piece);
if (inPool < 0) {
writeUInt(common);
writeUTF(piece);
trailingPool.put(piece);
} else {
writeUInt(common | 1);
writeUInt(inPool);
if (SHOW) System.out.println("\t" + inPool);
}
if (SHOW) System.out.println("\t\t" + lastString);
}
}
public static class WritePool {
private Map trailingPool = new HashMap();
private int poolCount = 0;
public int getIndex(Object o) {
Integer inPool = (Integer) trailingPool.get(o);
if (inPool == null) return -1;
return inPool.intValue();
}
public void put(Object o) {
trailingPool.put(o, new Integer(poolCount++));
}
}
/**
* @throws IOException
*
*/
public void writeCollection(Collection c, Map object_index) throws IOException {
writeUInt(c.size());
int i = 0;
object_index.put(null, new Integer(i++));
for (Iterator it = c.iterator(); it.hasNext();) {
Object s = it.next();
dataOutput.writeObject(s);
if (object_index != null) object_index.put(s, new Integer(i++));
}
}
}