Java tutorial
//package com.java2s; //* Licensed Materials - Property of IBM, Miracle A/S, and * import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.zip.GZIPInputStream; public class Main { private static final int STRING_NULL = 0; private static final int STRING_FROM_LIST = 1; private static final int STRING_PREFIX_FROM_LIST = 2; private static final int STRING_FROM_BYTES = 3; private static final int STRING_COMPRESSED = 4; private static final int STRING_PREFIX_FROM_LIST_COMPRESSED = 5; public static String readStringSmart(ByteArrayInputStream bais, List<String> knownStrings) { switch (bais.read()) { case STRING_NULL: { return null; } case STRING_FROM_LIST: { int index = getLength(bais); return knownStrings.get(index); } case STRING_PREFIX_FROM_LIST: { int index = getLength(bais); String prefix = knownStrings.get(index); return prefix + readString(bais); } case STRING_PREFIX_FROM_LIST_COMPRESSED: { int index = getLength(bais); String prefix = knownStrings.get(index); return prefix + readStringCompressed(bais); } case STRING_COMPRESSED: { return readStringCompressed(bais); } case STRING_FROM_BYTES: { return readString(bais); } default: { throw new RuntimeException("Cannot read smart string"); } } } public static int getLength(ByteArrayInputStream bais) { int lowbyte = bais.read(); if ((lowbyte & 128) == 0) { // MSB = 0 return lowbyte; } else if ((lowbyte & 64) == 0) { // MSB = 10 lowbyte -= 128; int highbyte = bais.read(); return lowbyte + highbyte * 64; } else if ((lowbyte & 32) == 0) { // MSB = 110 lowbyte -= 128 + 64; int midbyte = bais.read(); int highbyte = bais.read(); return lowbyte + midbyte * 32 + highbyte * 32 * 256; } else { throw new RuntimeException("Cannot parse length"); } } public static String readString(ByteArrayInputStream bais) { try { return new String(readData(bais), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Cannot read string", e); } } public static String readStringCompressed(ByteArrayInputStream bais) { try { return new String(readCompressedData(bais), "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("Cannot read string", e); } } public static byte[] readData(ByteArrayInputStream bais) { int len = getLength(bais); byte[] data = new byte[len]; bais.read(data, 0, len); return data; } public static byte[] readCompressedData(ByteArrayInputStream bais) { int uncompressedLength = getLength(bais); byte[] output = new byte[uncompressedLength]; byte[] compressed = readData(bais); GZIPInputStream gs; try { gs = new GZIPInputStream(new ByteArrayInputStream(compressed)); for (int i = 0; i < uncompressedLength; ++i) { output[i] = (byte) gs.read(); } } catch (IOException e) { throw new RuntimeException("Cannot decompress", e); } return output; } }