提交 da1a2d35 编写于 作者: S sherman

4813885: RFE: GZIPOutputStream should implement flush using Z_SYNC_FLUSH

Summary: Added new constructors to allow flush() work in Z_SYNC_FLUSH mode
Reviewed-by: martin
上级 2cdd0629
/*
* Copyright 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
* Copyright 1996-2010 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -54,25 +54,82 @@ class GZIPOutputStream extends DeflaterOutputStream {
/**
* Creates a new output stream with the specified buffer size.
*
* <p>The new output stream instance is created as if by invoking
* the 3-argument constructor GZIPOutputStream(out, size, false).
*
* @param out the output stream
* @param size the output buffer size
* @exception IOException If an I/O error has occurred.
* @exception IllegalArgumentException if size is <= 0
*/
public GZIPOutputStream(OutputStream out, int size) throws IOException {
super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true), size);
this(out, size, false);
}
/**
* Creates a new output stream with the specified buffer size and
* flush mode.
*
* @param out the output stream
* @param size the output buffer size
* @param syncFlush
* if {@code true} invocation of the inherited
* {@link DeflaterOutputStream#flush() flush()} method of
* this instance flushes the compressor with flush mode
* {@link Deflater#SYNC_FLUSH} before flushing the output
* stream, otherwise only flushes the output stream
* @exception IOException If an I/O error has occurred.
* @exception IllegalArgumentException if size is <= 0
*
* @since 1.7
*/
public GZIPOutputStream(OutputStream out, int size, boolean syncFlush)
throws IOException
{
super(out, new Deflater(Deflater.DEFAULT_COMPRESSION, true),
size,
syncFlush);
usesDefaultDeflater = true;
writeHeader();
crc.reset();
}
/**
* Creates a new output stream with a default buffer size.
*
* <p>The new output stream instance is created as if by invoking
* the 2-argument constructor GZIPOutputStream(out, false).
*
* @param out the output stream
* @exception IOException If an I/O error has occurred.
*/
public GZIPOutputStream(OutputStream out) throws IOException {
this(out, 512);
this(out, 512, false);
}
/**
* Creates a new output stream with a default buffer size and
* the specified flush mode.
*
* @param out the output stream
* @param syncFlush
* if {@code true} invocation of the inherited
* {@link DeflaterOutputStream#flush() flush()} method of
* this instance flushes the compressor with flush mode
* {@link Deflater#SYNC_FLUSH} before flushing the output
* stream, otherwise only flushes the output stream
*
* @exception IOException If an I/O error has occurred.
*
* @since 1.7
*/
public GZIPOutputStream(OutputStream out, boolean syncFlush)
throws IOException
{
this(out, 512, syncFlush);
}
/**
......
......@@ -23,8 +23,8 @@
/**
* @test
* @bug 4206909
* @summary Test basic functionality of DeflaterOutputStream and InflaterInputStream including flush
* @bug 4206909 4813885
* @summary Test basic functionality of DeflaterOutputStream/InflaterInputStream and GZIPOutputStream/GZIPInputStream, including flush
*/
import java.io.*;
......@@ -79,23 +79,23 @@ public class InflateIn_DeflateOut {
}
private static class PairedOutputStream extends ByteArrayOutputStream {
private PairedInputStream pairedStream = null;
private PairedInputStream pairedStream = null;
public PairedOutputStream(PairedInputStream inputPair) {
super();
this.pairedStream = inputPair;
}
public PairedOutputStream(PairedInputStream inputPair) {
super();
this.pairedStream = inputPair;
}
public void flush() {
if (count > 0) {
pairedStream.addBytes(buf, count);
reset();
public void flush() {
if (count > 0) {
pairedStream.addBytes(buf, count);
reset();
}
}
}
public void close() {
flush();
}
public void close() {
flush();
}
}
private static boolean readFully(InputStream in, byte[] buf, int length)
......@@ -146,27 +146,20 @@ public class InflateIn_DeflateOut {
check(Arrays.equals(data, buf));
}
/** Check that written, flushed and read */
private static void WriteFlushRead() throws Throwable {
private static void check(InputStream is, OutputStream os)
throws Throwable
{
Random random = new Random(new Date().getTime());
PairedInputStream pis = new PairedInputStream();
InflaterInputStream iis = new InflaterInputStream(pis);
PairedOutputStream pos = new PairedOutputStream(pis);
pis.setPairedOutputStream(pos);
DeflaterOutputStream dos = new DeflaterOutputStream(pos, true);
// Large writes
// Large writes
for (int x = 0; x < 200 ; x++) {
// byte[] data = new byte[random.nextInt(1024 * 1024)];
byte[] data = new byte[1024];
byte[] buf = new byte[data.length];
random.nextBytes(data);
dos.write(data);
dos.flush();
check(readFully(iis, buf, buf.length));
os.write(data);
os.flush();
check(readFully(is, buf, buf.length));
check(Arrays.equals(data, buf));
}
......@@ -176,9 +169,9 @@ public class InflateIn_DeflateOut {
byte[] buf = new byte[data.length];
random.nextBytes(data);
dos.write(data);
dos.flush();
if (!readFully(iis, buf, buf.length)) {
os.write(data);
os.flush();
if (!readFully(is, buf, buf.length)) {
fail("Didn't read full buffer of " + buf.length);
}
check(Arrays.equals(data, buf));
......@@ -187,17 +180,16 @@ public class InflateIn_DeflateOut {
String quit = "QUIT\r\n";
// Close it out
dos.write(quit.getBytes());
dos.close();
os.write(quit.getBytes());
os.close();
StringBuilder sb = new StringBuilder();
check(readLineIfAvailable(iis, sb));
check(readLineIfAvailable(is, sb));
equal(sb.toString(), quit);
}
/** Validate that we need to use flush at least once on a line
* oriented protocol */
private static void LineOrientedProtocol() throws Throwable {
/** Check that written, flushed and read */
private static void WriteFlushRead() throws Throwable {
PairedInputStream pis = new PairedInputStream();
InflaterInputStream iis = new InflaterInputStream(pis);
......@@ -205,6 +197,24 @@ public class InflateIn_DeflateOut {
pis.setPairedOutputStream(pos);
DeflaterOutputStream dos = new DeflaterOutputStream(pos, true);
check(iis, dos);
}
private static void GZWriteFlushRead() throws Throwable {
PairedInputStream pis = new PairedInputStream();
PairedOutputStream pos = new PairedOutputStream(pis);
pis.setPairedOutputStream(pos);
GZIPOutputStream gos = new GZIPOutputStream(pos, true);
gos.flush(); // flush the head out, so gis can read
GZIPInputStream gis = new GZIPInputStream(pis);
check(gis, gos);
}
private static void checkLOP(InputStream is, OutputStream os)
throws Throwable
{
boolean flushed = false;
int count = 0;
......@@ -212,13 +222,13 @@ public class InflateIn_DeflateOut {
// flush means this test isn't testing anything
while ((count < 10 && flushed) || (count < 1000 && !flushed)) {
String command = "PING " + count + "\r\n";
dos.write(command.getBytes());
os.write(command.getBytes());
StringBuilder buf = new StringBuilder();
if (!readLineIfAvailable(iis, buf)) {
if (!readLineIfAvailable(is, buf)) {
flushed = true;
dos.flush();
check(readLineIfAvailable(iis, buf));
os.flush();
check(readLineIfAvailable(is, buf));
}
equal(buf.toString(), command);
count++;
......@@ -226,12 +236,37 @@ public class InflateIn_DeflateOut {
check(flushed);
}
/** Validate that we need to use flush at least once on a line
* oriented protocol */
private static void LineOrientedProtocol() throws Throwable {
PairedInputStream pis = new PairedInputStream();
InflaterInputStream iis = new InflaterInputStream(pis);
PairedOutputStream pos = new PairedOutputStream(pis);
pis.setPairedOutputStream(pos);
DeflaterOutputStream dos = new DeflaterOutputStream(pos, true);
checkLOP(iis, dos);
}
private static void GZLineOrientedProtocol() throws Throwable {
PairedInputStream pis = new PairedInputStream();
PairedOutputStream pos = new PairedOutputStream(pis);
pis.setPairedOutputStream(pos);
GZIPOutputStream gos = new GZIPOutputStream(pos, true);
gos.flush(); // flush the head out, so gis can read
GZIPInputStream gis = new GZIPInputStream(pis);
checkLOP(gis, gos);
}
public static void realMain(String[] args) throws Throwable {
WriteCloseRead();
WriteFlushRead();
LineOrientedProtocol();
GZWriteFlushRead();
GZLineOrientedProtocol();
}
//--------------------- Infrastructure ---------------------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册