| /* ==================================================================== |
| 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. |
| ==================================================================== */ |
| |
| package org.apache.poi.util; |
| |
| import static org.junit.Assert.assertArrayEquals; |
| import static org.junit.Assert.assertEquals; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.UnsupportedEncodingException; |
| |
| import org.junit.Test; |
| |
| public class TestRLEDecompressingInputStream { |
| |
| /** |
| * Section 3.2.1 No Compression Example |
| * |
| * The following string illustrates an ASCII text string with a set of characters that cannot be compressed |
| * by the compression algorithm specified in section 2.4.1. |
| * |
| * abcdefghijklmnopqrstuv. |
| * |
| * This example is provided to demonstrate the results of compressing and decompressing the string |
| * using an interoperable implementation of the algorithm specified in section 2.4.1. |
| * |
| * The following hex array represents the compressed byte array of the example string as compressed by |
| * the compression algorithm. |
| * |
| * 01 19 B0 00 61 62 63 64 65 66 67 68 00 69 6A 6B 6C |
| * 6D 6E 6F 70 00 71 72 73 74 75 76 2E |
| * |
| * The following hex array represents the decompressed byte array of the example string as |
| * decompressed by the decompression algorithm. |
| * |
| * 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 |
| * 72 73 74 75 76 2E |
| * |
| */ |
| @Test |
| public void noCompressionExample() { |
| final byte[] compressed = { |
| 0x01, 0x19, (byte)0xB0, 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x00, 0x69, 0x6A, 0x6B, 0x6C, |
| 0x6D, 0x6E, 0x6F, 0x70, 0x00, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x2E |
| }; |
| final String expected = "abcdefghijklmnopqrstuv."; |
| checkRLEDecompression(expected, compressed); |
| } |
| |
| /** |
| * Section 3.2.2 Normal Compression Example |
| * |
| * The following string illustrates an ASCII text string with a typical set of characters that can be |
| * compressed by the compression algorithm. |
| * |
| * #aaabcdefaaaaghijaaaaaklaaamnopqaaaaaaaaaaaarstuvwxyzaaa |
| * |
| * This example is provided to demonstrate the results of compressing and decompressing the example |
| * string using an interoperable implementation of the algorithm specified in section 2.4.1. |
| * |
| * The following hex array represents the compressed byte array of the example string as compressed by |
| * the compression algorithm: |
| * |
| * 01 2F B0 00 23 61 61 61 62 63 64 65 82 66 00 70 |
| * 61 67 68 69 6A 01 38 08 61 6B 6C 00 30 6D 6E 6F |
| * 70 06 71 02 70 04 10 72 73 74 75 76 10 77 78 79 |
| * 7A 00 3C |
| * |
| * The following hex array represents the decompressed byte array of the example string as |
| * decompressed by the decompression algorithm: |
| * |
| * 23 61 61 61 62 63 64 65 66 61 61 61 61 67 68 69 |
| * 6a 61 61 61 61 61 6B 6C 61 61 61 6D 6E 6F 70 71 |
| * 61 61 61 61 61 61 61 61 61 61 61 61 72 73 74 75 |
| * 76 77 78 79 7A 61 61 61 |
| */ |
| @Test |
| public void normalCompressionExample() { |
| final byte[] compressed = { |
| 0x01, 0x2F, (byte)0xB0, 0x00, 0x23, 0x61, 0x61, 0x61, 0x62, 0x63, 0x64, 0x65, (byte)0x82, 0x66, 0x00, 0x70, |
| 0x61, 0x67, 0x68, 0x69, 0x6A, 0x01, 0x38, 0x08, 0x61, 0x6B, 0x6C, 0x00, 0x30, 0x6D, 0x6E, 0x6F, |
| 0x70, 0x06, 0x71, 0x02, 0x70, 0x04, 0x10, 0x72, 0x73, 0x74, 0x75, 0x76, 0x10, 0x77, 0x78, 0x79, |
| 0x7A, 0x00, 0x3C |
| }; |
| final String expected = "#aaabcdefaaaaghijaaaaaklaaamnopqaaaaaaaaaaaarstuvwxyzaaa"; |
| checkRLEDecompression(expected, compressed); |
| } |
| |
| /** |
| * Section 3.2.3 Maximum Compression Example |
| * |
| * The following string illustrates an ASCII text string with a typical set of characters that can be |
| * compressed by the compression algorithm. |
| * |
| * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa |
| * |
| * This example is provided to demonstrate the results of compressing and decompressing the example |
| * string using an interoperable implementation of the algorithm specified in section 2.4.1. |
| * |
| * The following hex array represents the compressed byte array of the example string as compressed by |
| * the compression algorithm: |
| * |
| * 01 03 B0 02 61 45 00 |
| * |
| * The following hex array represents the decompressed byte array of the example string as |
| * decompressed by the decompression algorithm: |
| * |
| * 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |
| * 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |
| * 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |
| * 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |
| * 61 61 61 61 61 61 61 61 61 |
| */ |
| @Test |
| public void maximumCompressionExample() { |
| final byte[] compressed = { |
| 0x01, 0x03, (byte)0xB0, 0x02, 0x61, 0x45, 0x00 |
| }; |
| final String expected = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| checkRLEDecompression(expected, compressed); |
| } |
| |
| @Test |
| public void decompress() throws IOException { |
| final byte[] compressed = { |
| 0x01, 0x03, (byte)0xB0, 0x02, 0x61, 0x45, 0x00 |
| }; |
| final byte[] expanded = RLEDecompressingInputStream.decompress(compressed); |
| final byte[] expected = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".getBytes(StringUtil.UTF8); |
| assertArrayEquals(expected, expanded); |
| } |
| |
| private static void checkRLEDecompression(String expected, byte[] runLengthEncodedData) { |
| InputStream compressedStream = new ByteArrayInputStream(runLengthEncodedData); |
| ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| try { |
| InputStream stream = new RLEDecompressingInputStream(compressedStream); |
| try { |
| IOUtils.copy(stream, out); |
| } finally { |
| out.close(); |
| stream.close(); |
| } |
| } catch (final IOException e) { |
| throw new RuntimeException(e); |
| } |
| String expanded; |
| try { |
| expanded = out.toString(StringUtil.UTF8.name()); |
| } catch (final UnsupportedEncodingException e) { |
| throw new RuntimeException(e); |
| } |
| assertEquals(expected, expanded); |
| } |
| } |