Class RpcGZIPOutputStream
- java.lang.Object
-
- java.io.OutputStream
-
- java.io.FilterOutputStream
-
- com.perforce.p4java.impl.mapbased.rpc.stream.RpcGZIPOutputStream
-
- All Implemented Interfaces:
java.io.Closeable
,java.io.Flushable
,java.lang.AutoCloseable
public class RpcGZIPOutputStream extends java.io.FilterOutputStream
A fairly lightweight filter output stream that implements Perforce's GZIP-based connection stream compression for Perforce clients that have the Perforce "client compression" option set.The implementation here uses the JZlib package because the standard JDK GZIP packages in java.util.zip are not able to cope cleanly with the various flush options needed on a streaming connection like this. Our use of the JZlib package is pretty boring, and is basically just a transliteration of the original C++ API code that dates from about 1999 or so. The implementation here is not thread safe in that there's a buffer in each instantiation of this stream; this could probably be tightened up if there's a need for it.
Note that this implementation requires the upper levels to ensure that the stream is flushed properly with the flush() method whenever an RPC packet is ready for sending; this ensures that GZIP block processing, etc., is done properly and the server sees correct block and stream boundaries. If this isn't done, the server may hang or you may see some very odd client-side errors. The stream should also be closed properly, but that's less of an issue.
Note that there's quite a performance penalty for using connection (a.k.a. client) compression (especially on the server), but if that's what the customer wants, that what the customer gets.
-
-
Constructor Summary
Constructors Constructor Description RpcGZIPOutputStream(java.io.OutputStream out)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
close()
Cleanly close the stream and finalize deflation (compression).void
flush()
Flush the results of previous byte deflation (compression) downstream.protected java.lang.String
getJZlibErrorStr(int errNum)
Provide a more human-readable form of the underlying JZlib compression errors.void
write(byte[] bytes)
A convenience method for write(bytes, 0, bytes.length).void
write(byte[] bytes, int offset, int len)
Deflate (compress) the passed-in bytes and -- if appropriate -- send the compressed bytes downstream to the filter's output stream.void
write(int b)
Not used.
-
-
-
Method Detail
-
write
public void write(byte[] bytes) throws java.io.IOException
A convenience method for write(bytes, 0, bytes.length).- Overrides:
write
in classjava.io.FilterOutputStream
- Throws:
java.io.IOException
- See Also:
FilterOutputStream.write(byte[])
-
write
public void write(byte[] bytes, int offset, int len) throws java.io.IOException
Deflate (compress) the passed-in bytes and -- if appropriate -- send the compressed bytes downstream to the filter's output stream.This write method does not necessarily cause a write to the server -- a write will only occur when the jzBytes buffer is full, or on a later flush. This is a consequence of the way GZIP streaming works here, and means you must ensure that a suitable flush is done at a suitable (packet) boundary. See the comments for flush() below.
- Overrides:
write
in classjava.io.FilterOutputStream
- Throws:
java.io.IOException
- See Also:
FilterOutputStream.write(byte[], int, int)
-
write
public void write(int b) throws java.io.IOException
Not used. Will cause a UnimplementedError to be thrown if called.- Overrides:
write
in classjava.io.FilterOutputStream
- Throws:
java.io.IOException
- See Also:
FilterOutputStream.write(int)
-
flush
public void flush() throws java.io.IOException
Flush the results of previous byte deflation (compression) downstream.As a consequence of the way GZIP streaming works, this flush is often the only place where bytes are actually written downstream towards the server (the earlier writes may only write to the internal buffer here). Using flush causes a compression boundary, so it should only be used after a complete packet has been put onto this stream -- i.e. users of this stream must call flush appropriately, or the server may not see packets at all.
- Specified by:
flush
in interfacejava.io.Flushable
- Overrides:
flush
in classjava.io.FilterOutputStream
- Throws:
java.io.IOException
- See Also:
FilterOutputStream.flush()
-
close
public void close() throws java.io.IOException
Cleanly close the stream and finalize deflation (compression). No one dies if you don't call this properly, but it certainly helps to close the stream cleanly.- Specified by:
close
in interfacejava.lang.AutoCloseable
- Specified by:
close
in interfacejava.io.Closeable
- Overrides:
close
in classjava.io.FilterOutputStream
- Throws:
java.io.IOException
- See Also:
FilterOutputStream.close()
-
getJZlibErrorStr
protected java.lang.String getJZlibErrorStr(int errNum)
Provide a more human-readable form of the underlying JZlib compression errors.Should be made even more human-readable sometime later -- HR.
- Parameters:
errNum
- errNum- Returns:
- error message
-
-