@Test public void deflateWithClose() throws Exception { Buffer data = new Buffer(); String original = "They're moving in herds. They do move in herds."; data.writeUtf8(original); Buffer sink = new Buffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); deflaterSink.write(data, data.size()); deflaterSink.close(); Buffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8()); }
@Test public void deflateWithSyncFlush() throws Exception { String original = "Yes, yes, yes. That's why we're taking extreme precautions."; Buffer data = new Buffer(); data.writeUtf8(original); Buffer sink = new Buffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); deflaterSink.write(data, data.size()); deflaterSink.flush(); Buffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8()); }
Writer(BufferedSink sink, boolean client) { this.sink = sink; this.client = client; Deflater deflater = new Deflater(); deflater.setDictionary(DICTIONARY); headerBlockBuffer = new Buffer(); headerBlockOut = Okio.buffer(new DeflaterSink(headerBlockBuffer, deflater)); }
@Override public void flush() throws IOException { deflaterSink.flush(); }
@Override public void write(Buffer source, long byteCount) throws IOException { if (byteCount < 0) throw new IllegalArgumentException("byteCount < 0: " + byteCount); if (byteCount == 0) return; updateCrc(source, byteCount); deflaterSink.write(source, byteCount); }
void finishDeflate() throws IOException { deflater.finish(); deflate(false); }
@Override public void close() throws IOException { if (closed) return; // Emit deflated data to the underlying sink. If this fails, we still need // to close the deflater and the sink; otherwise we risk leaking resources. Throwable thrown = null; try { finishDeflate(); } catch (Throwable e) { thrown = e; } try { deflater.end(); } catch (Throwable e) { if (thrown == null) thrown = e; } try { sink.close(); } catch (Throwable e) { if (thrown == null) thrown = e; } closed = true; if (thrown != null) Util.sneakyRethrow(thrown); }
Writer(BufferedSink sink, boolean client) { this.sink = sink; this.client = client; Deflater deflater = new Deflater(); deflater.setDictionary(DICTIONARY); headerBlockBuffer = new Buffer(); headerBlockOut = Okio.buffer(new DeflaterSink(headerBlockBuffer, deflater)); }
@Override public void flush() throws IOException { deflate(true); sink.flush(); }
@Override public void close() throws IOException { if (closed) return; // This method delegates to the DeflaterSink for finishing the deflate process // but keeps responsibility for releasing the deflater's resources. This is // necessary because writeFooter needs to query the processed byte count which // only works when the deflater is still open. Throwable thrown = null; try { deflaterSink.finishDeflate(); writeFooter(); } catch (Throwable e) { thrown = e; } try { deflater.end(); } catch (Throwable e) { if (thrown == null) thrown = e; } try { sink.close(); } catch (Throwable e) { if (thrown == null) thrown = e; } closed = true; if (thrown != null) Util.sneakyRethrow(thrown); }
@Test public void deflatePoorlyCompressed() throws IOException { ByteString original = randomBytes(1024 * 1024); Buffer data = new Buffer(); data.write(original); Buffer sink = new Buffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); deflaterSink.write(data, data.size()); deflaterSink.close(); Buffer inflated = inflate(sink); assertEquals(original, inflated.readByteString()); }
Writer(BufferedSink sink, boolean client) { this.sink = sink; this.client = client; Deflater deflater = new Deflater(); deflater.setDictionary(DICTIONARY); headerBlockBuffer = new Buffer(); headerBlockOut = Okio.buffer(new DeflaterSink(headerBlockBuffer, deflater)); }
@Override public void write(Buffer source, long byteCount) throws IOException { checkOffsetAndCount(source.size, 0, byteCount); while (byteCount > 0) { // Share bytes from the head segment of 'source' with the deflater. Segment head = source.head; int toDeflate = (int) Math.min(byteCount, head.limit - head.pos); deflater.setInput(head.data, head.pos, toDeflate); // Deflate those bytes into sink. deflate(false); // Mark those bytes as read. source.size -= toDeflate; head.pos += toDeflate; if (head.pos == head.limit) { source.head = head.pop(); SegmentPool.recycle(head); } byteCount -= toDeflate; } }
@Test public void deflateWellCompressed() throws IOException { String original = repeat('a', 1024 * 1024); Buffer data = new Buffer(); data.writeUtf8(original); Buffer sink = new Buffer(); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); deflaterSink.write(data, data.size()); deflaterSink.close(); Buffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8()); }
public GzipSink(Sink sink) { if (sink == null) throw new IllegalArgumentException("sink == null"); this.deflater = new Deflater(DEFAULT_COMPRESSION, true /* No wrap */); this.sink = Okio.buffer(sink); this.deflaterSink = new DeflaterSink(this.sink, deflater); writeHeader(); }
@Test public void multipleSegmentsWithoutCompression() throws IOException { Buffer buffer = new Buffer(); Deflater deflater = new Deflater(); deflater.setLevel(Deflater.NO_COMPRESSION); DeflaterSink deflaterSink = new DeflaterSink(buffer, deflater); int byteCount = SEGMENT_SIZE * 4; deflaterSink.write(new Buffer().writeUtf8(repeat('a', byteCount)), byteCount); deflaterSink.close(); assertEquals(repeat('a', byteCount), inflate(buffer).readUtf8(byteCount)); }
@Test public void deflateIntoNonemptySink() throws Exception { String original = "They're moving in herds. They do move in herds."; // Exercise all possible offsets for the outgoing segment. for (int i = 0; i < SEGMENT_SIZE; i++) { Buffer data = new Buffer().writeUtf8(original); Buffer sink = new Buffer().writeUtf8(repeat('a', i)); DeflaterSink deflaterSink = new DeflaterSink(sink, new Deflater()); deflaterSink.write(data, data.size()); deflaterSink.close(); sink.skip(i); Buffer inflated = inflate(sink); assertEquals(original, inflated.readUtf8()); } }
/** * This test deflates a single segment of without compression because that's * the easiest way to force close() to emit a large amount of data to the * underlying sink. */ @Test public void closeWithExceptionWhenWritingAndClosing() throws IOException { MockSink mockSink = new MockSink(); mockSink.scheduleThrow(0, new IOException("first")); mockSink.scheduleThrow(1, new IOException("second")); Deflater deflater = new Deflater(); deflater.setLevel(Deflater.NO_COMPRESSION); DeflaterSink deflaterSink = new DeflaterSink(mockSink, deflater); deflaterSink.write(new Buffer().writeUtf8(repeat('a', SEGMENT_SIZE)), SEGMENT_SIZE); try { deflaterSink.close(); fail(); } catch (IOException expected) { assertEquals("first", expected.getMessage()); } mockSink.assertLogContains("close()"); }