1/*
2 * Copyright (C) 2014 Square, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package okio;
17
18import java.io.EOFException;
19import java.io.IOException;
20import java.util.zip.Deflater;
21import java.util.zip.DeflaterOutputStream;
22import java.util.zip.Inflater;
23import org.junit.Test;
24
25import static okio.TestUtil.randomBytes;
26import static okio.TestUtil.repeat;
27import static org.junit.Assert.assertEquals;
28import static org.junit.Assert.fail;
29
30public final class InflaterSourceTest {
31  @Test public void inflate() throws Exception {
32    Buffer deflated = decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tK"
33        + "tYDAF6CD5s=");
34    Buffer inflated = inflate(deflated);
35    assertEquals("God help us, we're in the hands of engineers.", inflated.readUtf8());
36  }
37
38  @Test public void inflateTruncated() throws Exception {
39    Buffer deflated = decodeBase64("eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tK"
40        + "tYDAF6CDw==");
41    try {
42      inflate(deflated);
43      fail();
44    } catch (EOFException expected) {
45    }
46  }
47
48  @Test public void inflateWellCompressed() throws Exception {
49    Buffer deflated = decodeBase64("eJztwTEBAAAAwqCs61/CEL5AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
50        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
51        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
52        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
53        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
54        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
55        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
56        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
57        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
58        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
59        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
60        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
61        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
62        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
63        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
64        + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8B"
65        + "tFeWvE=\n");
66    String original = repeat('a', 1024 * 1024);
67    Buffer inflated = inflate(deflated);
68    assertEquals(original, inflated.readUtf8());
69  }
70
71  @Test public void inflatePoorlyCompressed() throws Exception {
72    ByteString original = randomBytes(1024 * 1024);
73    Buffer deflated = deflate(original);
74    Buffer inflated = inflate(deflated);
75    assertEquals(original, inflated.readByteString());
76  }
77
78  @Test public void inflateIntoNonemptySink() throws Exception {
79    for (int i = 0; i < Segment.SIZE; i++) {
80      Buffer inflated = new Buffer().writeUtf8(repeat('a', i));
81      Buffer deflated = decodeBase64(
82          "eJxzz09RyEjNKVAoLdZRKE9VL0pVyMxTKMlIVchIzEspVshPU0jNS8/MS00tKtYDAF6CD5s=");
83      InflaterSource source = new InflaterSource(deflated, new Inflater());
84      while (source.read(inflated, Integer.MAX_VALUE) != -1) {
85      }
86      inflated.skip(i);
87      assertEquals("God help us, we're in the hands of engineers.", inflated.readUtf8());
88    }
89  }
90
91  private Buffer decodeBase64(String s) {
92    return new Buffer().write(ByteString.decodeBase64(s));
93  }
94
95  /** Use DeflaterOutputStream to deflate source. */
96  private Buffer deflate(ByteString source) throws IOException {
97    Buffer result = new Buffer();
98    Sink sink = Okio.sink(new DeflaterOutputStream(result.outputStream()));
99    sink.write(new Buffer().write(source), source.size());
100    sink.close();
101    return result;
102  }
103
104  /** Returns a new buffer containing the inflated contents of {@code deflated}. */
105  private Buffer inflate(Buffer deflated) throws IOException {
106    Buffer result = new Buffer();
107    InflaterSource source = new InflaterSource(deflated, new Inflater());
108    while (source.read(result, Integer.MAX_VALUE) != -1) {
109    }
110    return result;
111  }
112}
113