package org.apache.lucene.document; /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.zip.Deflater; import java.util.zip.Inflater; import java.util.zip.DataFormatException; import java.io.ByteArrayOutputStream; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.UnicodeUtil; /** Simple utility class providing static methods to * compress and decompress binary data for stored fields. * This class uses java.util.zip.Deflater and Inflater * classes to compress and decompress. */ public class CompressionTools { // Export only static methods private CompressionTools() {} /** Compresses the specified byte range using the * specified compressionLevel (constants are defined in * java.util.zip.Deflater). */ public static byte[] compress(byte[] value, int offset, int length, int compressionLevel) { /* Create an expandable byte array to hold the compressed data. * You cannot use an array that's the same size as the orginal because * there is no guarantee that the compressed data will be smaller than * the uncompressed data. */ ByteArrayOutputStream bos = new ByteArrayOutputStream(length); Deflater compressor = new Deflater(); try { compressor.setLevel(compressionLevel); compressor.setInput(value, offset, length); compressor.finish(); // Compress the data final byte[] buf = new byte[1024]; while (!compressor.finished()) { int count = compressor.deflate(buf); bos.write(buf, 0, count); } } finally { compressor.end(); } return bos.toByteArray(); } /** Compresses the specified byte range, with default BEST_COMPRESSION level */ public static byte[] compress(byte[] value, int offset, int length) { return compress(value, offset, length, Deflater.BEST_COMPRESSION); } /** Compresses all bytes in the array, with default BEST_COMPRESSION level */ public static byte[] compress(byte[] value) { return compress(value, 0, value.length, Deflater.BEST_COMPRESSION); } /** Compresses the String value, with default BEST_COMPRESSION level */ public static byte[] compressString(String value) { return compressString(value, Deflater.BEST_COMPRESSION); } /** Compresses the String value using the specified * compressionLevel (constants are defined in * java.util.zip.Deflater). */ public static byte[] compressString(String value, int compressionLevel) { BytesRef result = new BytesRef(); UnicodeUtil.UTF16toUTF8(value, 0, value.length(), result); return compress(result.bytes, 0, result.length, compressionLevel); } /** Decompress the byte array previously returned by * compress */ public static byte[] decompress(byte[] value) throws DataFormatException { // Create an expandable byte array to hold the decompressed data ByteArrayOutputStream bos = new ByteArrayOutputStream(value.length); Inflater decompressor = new Inflater(); try { decompressor.setInput(value); // Decompress the data final byte[] buf = new byte[1024]; while (!decompressor.finished()) { int count = decompressor.inflate(buf); bos.write(buf, 0, count); } } finally { decompressor.end(); } return bos.toByteArray(); } /** Decompress the byte array previously returned by * compressString back into a String */ public static String decompressString(byte[] value) throws DataFormatException { UnicodeUtil.UTF16Result result = new UnicodeUtil.UTF16Result(); final byte[] bytes = decompress(value); UnicodeUtil.UTF8toUTF16(bytes, 0, bytes.length, result); return new String(result.result, 0, result.length); } }