|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 package org.mozilla.gecko.background.bagheera; |
|
6 |
|
7 import java.io.UnsupportedEncodingException; |
|
8 import java.util.zip.Deflater; |
|
9 |
|
10 import ch.boye.httpclientandroidlib.HttpEntity; |
|
11 |
|
12 public class DeflateHelper { |
|
13 /** |
|
14 * Conservative upper bound for zlib size, equivalent to the first few lines |
|
15 * in zlib's deflateBound function. |
|
16 * |
|
17 * Includes zlib header. |
|
18 * |
|
19 * @param sourceLen |
|
20 * the number of bytes to compress. |
|
21 * @return the number of bytes to allocate for the compressed output. |
|
22 */ |
|
23 public static int deflateBound(final int sourceLen) { |
|
24 return sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5 + 6; |
|
25 } |
|
26 |
|
27 /** |
|
28 * Deflate the input into the output array, returning the number of bytes |
|
29 * written to output. |
|
30 */ |
|
31 public static int deflate(byte[] input, byte[] output) { |
|
32 final Deflater deflater = new Deflater(); |
|
33 deflater.setInput(input); |
|
34 deflater.finish(); |
|
35 |
|
36 final int length = deflater.deflate(output); |
|
37 deflater.end(); |
|
38 return length; |
|
39 } |
|
40 |
|
41 /** |
|
42 * Deflate the input, returning an HttpEntity that offers an accurate window |
|
43 * on the output. |
|
44 * |
|
45 * Note that this method does not trim the output array. (Test code can use |
|
46 * TestDeflation#deflateTrimmed(byte[]).) |
|
47 * |
|
48 * Trimming would be more efficient for long-term space use, but we expect this |
|
49 * entity to be transient. |
|
50 * |
|
51 * Note also that deflate can require <b>more</b> space than the input. |
|
52 * {@link #deflateBound(int)} tells us the most it will use. |
|
53 * |
|
54 * @param bytes the input to deflate. |
|
55 * @return the deflated input as an entity. |
|
56 */ |
|
57 public static HttpEntity deflateBytes(final byte[] bytes) { |
|
58 // We would like to use DeflaterInputStream here, but it's minSDK=9, and we |
|
59 // still target 8. It would also force us to use chunked Transfer-Encoding, |
|
60 // so perhaps it's for the best! |
|
61 |
|
62 final byte[] out = new byte[deflateBound(bytes.length)]; |
|
63 final int outLength = deflate(bytes, out); |
|
64 return new BoundedByteArrayEntity(out, 0, outLength); |
|
65 } |
|
66 |
|
67 public static HttpEntity deflateBody(final String payload) { |
|
68 final byte[] bytes; |
|
69 try { |
|
70 bytes = payload.getBytes("UTF-8"); |
|
71 } catch (UnsupportedEncodingException ex) { |
|
72 // This will never happen. Thanks, Java! |
|
73 throw new RuntimeException(ex); |
|
74 } |
|
75 return deflateBytes(bytes); |
|
76 } |
|
77 } |