001: //##header
002: /*
003: *******************************************************************************
004: * Copyright (C) 1996-2006, International Business Machines Corporation and *
005: * others. All Rights Reserved. *
006: *******************************************************************************
007: */
008: //#ifndef FOUNDATION
009: package com.ibm.icu.dev.test.util;
010:
011: import java.io.DataOutput;
012: import java.io.IOException;
013: import java.io.ObjectOutput;
014: import java.util.Collection;
015: import java.util.HashMap;
016: import java.util.Iterator; //import java.util.LinkedHashMap;
017: import java.util.Map;
018: import java.util.SortedSet; //import java.util.TreeSet;
019:
020: //import com.ibm.icu.impl.Utility;
021: import com.ibm.icu.text.UTF16;
022:
023: /**
024: * Simple data output compressor. Nothing fancy, but much smaller footprint for ints and many strings.
025: */
026: public final class DataOutputCompressor implements ObjectOutput {
027: static final boolean SHOW = false;
028:
029: private ObjectOutput dataOutput;
030:
031: public DataOutputCompressor(ObjectOutput dataOutput) {
032: this .dataOutput = dataOutput;
033: }
034:
035: public DataOutput getDataOutput() {
036: return dataOutput;
037: }
038:
039: public void setDataOutput(ObjectOutput dataOutput) {
040: this .dataOutput = dataOutput;
041: }
042:
043: public void write(byte[] b) throws IOException {
044: dataOutput.write(b);
045: }
046:
047: public void write(byte[] b, int off, int len) throws IOException {
048: dataOutput.write(b, off, len);
049: }
050:
051: public void write(int b) throws IOException {
052: dataOutput.write(b);
053: }
054:
055: public void writeBoolean(boolean v) throws IOException {
056: dataOutput.writeBoolean(v);
057: }
058:
059: public void writeByte(int v) throws IOException {
060: dataOutput.writeByte(v);
061: }
062:
063: public void writeBytes(String s) throws IOException {
064: dataOutput.writeBytes(s);
065: }
066:
067: public void writeDouble(double v) throws IOException {
068: dataOutput.writeDouble(v);
069: }
070:
071: public void writeFloat(float v) throws IOException {
072: dataOutput.writeFloat(v);
073: }
074:
075: public void close() throws IOException {
076: dataOutput.close();
077: }
078:
079: public void flush() throws IOException {
080: dataOutput.flush();
081: }
082:
083: public String toString() {
084: return dataOutput.toString();
085: }
086:
087: public void writeObject(Object obj) throws IOException {
088: dataOutput.writeObject(obj);
089: }
090:
091: // ==== New Routines ====
092:
093: public void writeChar(int v) throws IOException {
094: writeULong(v);
095: }
096:
097: public void writeShort(int v) throws IOException {
098: writeLong(v);
099: }
100:
101: public void writeUShort(int v) throws IOException {
102: writeULong(v);
103: }
104:
105: public void writeInt(int v) throws IOException {
106: writeLong(v);
107: }
108:
109: public void writeUInt(int v) throws IOException {
110: writeULong(v);
111: }
112:
113: public void writeUTF(String str) throws IOException {
114: writeULong(UTF16.countCodePoint(str));
115: writeChars(str);
116: }
117:
118: public void writeChars(String s) throws IOException {
119: int cp = 0;
120: for (int i = 0; i < s.length(); i += UTF16.getCharCount(cp)) {
121: cp = UTF16.charAt(s, i);
122: writeULong(cp);
123: }
124: }
125:
126: public void writeLong(long v) throws IOException {
127: long flag = 0; // put sign bit at the bottom, and invert
128: if (v < 0) {
129: v = ~v;
130: flag = 1;
131: }
132: v <<= 1;
133: v |= flag;
134: while (true) {
135: if ((v & ~0x7FL) == 0) {
136: dataOutput.writeByte((byte) v);
137: break;
138: }
139: dataOutput.writeByte((byte) (0x80L | v));
140: v >>>= 7;
141: }
142: }
143:
144: public void writeULong(long v) throws IOException {
145: while (true) { // write sequence of 7 bits, with top bit = 1 for continuation
146: if ((v & ~0x7FL) == 0) {
147: dataOutput.writeByte((byte) v);
148: break;
149: }
150: dataOutput.writeByte((byte) (0x80L | v));
151: v >>>= 7;
152: }
153: }
154:
155: /**
156: *
157: */
158: public void writeStringSet(SortedSet c, Map object_index)
159: throws IOException {
160: if (SHOW)
161: System.out.println("writeStringSet");
162: writeUInt(c.size());
163: int i = 0;
164: object_index.put(null, new Integer(i++));
165: WritePool trailingPool = new WritePool();
166: int poolCount = 0;
167: String lastString = "";
168: for (Iterator it = c.iterator(); it.hasNext();) {
169: String s = (String) it.next();
170: object_index.put(s, new Integer(i++));
171: int common = UnicodeMap.findCommon(lastString, s); // runlength encode
172: lastString = s;
173: String piece = s.substring(common);
174: if (SHOW)
175: System.out.println(common);
176: common <<= 1;
177: int inPool = trailingPool.getIndex(piece);
178: if (inPool < 0) {
179: writeUInt(common);
180: writeUTF(piece);
181: trailingPool.put(piece);
182: } else {
183: writeUInt(common | 1);
184: writeUInt(inPool);
185: if (SHOW)
186: System.out.println("\t" + inPool);
187: }
188: if (SHOW)
189: System.out.println("\t\t" + lastString);
190: }
191: }
192:
193: public static class WritePool {
194: private Map trailingPool = new HashMap();
195: private int poolCount = 0;
196:
197: public int getIndex(Object o) {
198: Integer inPool = (Integer) trailingPool.get(o);
199: if (inPool == null)
200: return -1;
201: return inPool.intValue();
202: }
203:
204: public void put(Object o) {
205: trailingPool.put(o, new Integer(poolCount++));
206: }
207: }
208:
209: /**
210: * @throws IOException
211: *
212: */
213: public void writeCollection(Collection c, Map object_index)
214: throws IOException {
215: writeUInt(c.size());
216: int i = 0;
217: object_index.put(null, new Integer(i++));
218: for (Iterator it = c.iterator(); it.hasNext();) {
219: Object s = it.next();
220: dataOutput.writeObject(s);
221: if (object_index != null)
222: object_index.put(s, new Integer(i++));
223: }
224: }
225: }
226:
227: //#endif
|