1 package com.liviutudor.rmi.io.gzip;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6 import java.net.Socket;
7 import java.net.UnknownHostException;
8 import java.util.zip.GZIPInputStream;
9 import java.util.zip.GZIPOutputStream;
10
11 /**
12 * Socket which uses gzip to compress the data sent over the wire.
13 *
14 * @author Liviu Tudor http://about.me/liviutudor
15 */
16 class GzipSocket extends Socket {
17 /** Wrapper for the socket input stream. */
18 private GZIPInputStream inputStream;
19
20 /** Wrapper for the socket output stream. */
21 private GZIPOutputStream outputStream;
22
23 /**
24 * Creates a socket which connects to the given host on the given port.
25 *
26 * @param host
27 * Host to connect to
28 * @param port
29 * Port to connect to
30 * @throws UnknownHostException
31 * if host name or IP is wrong
32 * @throws IOException
33 * if I/O errors occur when connecting
34 */
35 public GzipSocket(String host, int port) throws UnknownHostException, IOException {
36 super(host, port);
37 }
38
39 @Override
40 public synchronized void close() throws IOException {
41 if (inputStream != null) {
42 inputStream.close();
43 inputStream = null;
44 }
45 if (outputStream != null) {
46 outputStream.flush();
47 outputStream.close();
48 outputStream = null;
49 }
50 super.close();
51 }
52
53 /**
54 * Overrides the base class method for returning the input stream for this
55 * socket and returns instead the {@link #inputStream gzip-based wrapper}.
56 * Note that this is a lazy evaluation function. NOTE: The GzipInputStream
57 * blocks on creation to read the header so this function actually blocks
58 * until data is available over the wire!
59 *
60 * @return wrapper for the base class input stream
61 * @throws IOException
62 * if I/O errors occur
63 * @see #inputStream
64 */
65 @Override
66 public synchronized InputStream getInputStream() throws IOException {
67 if (inputStream == null) {
68 inputStream = new GZIPInputStream(super.getInputStream());
69 }
70 return inputStream;
71 }
72
73 /**
74 * Overrides the base class method for returning the output stream for this
75 * socket and returns instead the {@link #outputStream gzip-based wrapper}.
76 *
77 * @return wrapper for the base class output stream
78 * @throws IOException
79 * if I/O errors occur
80 * @see #outputStream
81 */
82 @Override
83 public synchronized OutputStream getOutputStream() throws IOException {
84 if (outputStream == null) {
85 outputStream = new GZIPOutputStream(super.getOutputStream());
86 }
87 return outputStream;
88 }
89
90 @Override
91 public void shutdownInput() throws IOException {
92 // TODO: what do we need to do here?
93 super.shutdownInput();
94 }
95
96 @Override
97 public void shutdownOutput() throws IOException {
98 // TODO what do we need to do here?
99 super.shutdownOutput();
100 }
101 }