EMMA Coverage Report (generated Mon Jul 24 20:33:06 CDT 2006)
[all classes][com.mysql.jdbc]

COVERAGE SUMMARY FOR SOURCE FILE [CompressedInputStream.java]

nameclass, %method, %block, %line, %
CompressedInputStream.java100% (1/1)70%  (7/10)76%  (359/472)70%  (74/105)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class CompressedInputStream100% (1/1)70%  (7/10)76%  (359/472)70%  (74/105)
read (): int 0%   (0/1)0%   (0/20)0%   (0/5)
read (byte []): int 0%   (0/1)0%   (0/7)0%   (0/1)
skip (long): long 0%   (0/1)0%   (0/26)0%   (0/7)
read (byte [], int, int): int 100% (1/1)76%  (42/55)62%  (8/13)
readFully (byte [], int, int): int 100% (1/1)77%  (27/35)78%  (7/9)
getNextPacketFromServer (): void 100% (1/1)85%  (227/266)79%  (42/53)
CompressedInputStream (Connection, InputStream): void 100% (1/1)100% (21/21)100% (7/7)
available (): int 100% (1/1)100% (18/18)100% (3/3)
close (): void 100% (1/1)100% (10/10)100% (4/4)
getNextPacketIfRequired (int): void 100% (1/1)100% (14/14)100% (3/3)

1/*
2 Copyright (C) 2002-2004 MySQL AB
3 
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of version 2 of the GNU General Public License as 
6 published by the Free Software Foundation.
7 
8 There are special exceptions to the terms and conditions of the GPL 
9 as it is applied to this software. View the full text of the 
10 exception in file EXCEPTIONS-CONNECTOR-J in the directory of this 
11 software distribution.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 
22 
23 
24 */
25package com.mysql.jdbc;
26 
27import java.io.EOFException;
28import java.io.IOException;
29import java.io.InputStream;
30 
31import java.sql.SQLException;
32 
33import java.util.zip.DataFormatException;
34import java.util.zip.Inflater;
35 
36/**
37 * Used to de-compress packets from the MySQL server when protocol-level
38 * compression is turned on.
39 * 
40 * @author Mark Matthews
41 * 
42 * @version $Id: CompressedInputStream.java,v 1.1.2.1 2005/05/13 18:58:37
43 *          mmatthews Exp $
44 */
45class CompressedInputStream extends InputStream {
46        /** The packet data after it has been un-compressed */
47        private byte[] buffer;
48 
49        /** The connection that is using us (used to read config values) */
50        private Connection connection;
51 
52        /** The stream we are reading from the server */
53        private InputStream in;
54 
55        /** The ZIP inflater used to un-compress packets */
56        private Inflater inflater;
57 
58        /**
59         * The buffer to read packet headers into
60         */
61        private byte[] packetHeaderBuffer = new byte[7];
62 
63        /** The position we are reading from */
64        private int pos = 0;
65 
66        /**
67         * Creates a new CompressedInputStream that reads the given stream from the
68         * server.
69         * 
70         * @param conn
71         *            DOCUMENT ME!
72         * @param streamFromServer
73         */
74        public CompressedInputStream(Connection conn, InputStream streamFromServer) {
75                this.connection = conn;
76                this.in = streamFromServer;
77                this.inflater = new Inflater();
78        }
79 
80        /**
81         * @see java.io.InputStream#available()
82         */
83        public int available() throws IOException {
84                if (this.buffer == null) {
85                        return this.in.available();
86                }
87 
88                return this.buffer.length - this.pos + this.in.available();
89        }
90 
91        /**
92         * @see java.io.InputStream#close()
93         */
94        public void close() throws IOException {
95                this.in.close();
96                this.buffer = null;
97                this.inflater = null;
98        }
99 
100        /**
101         * Retrieves and un-compressed (if necessary) the next packet from the
102         * server.
103         * 
104         * @throws IOException
105         *             if an I/O error occurs
106         */
107        private void getNextPacketFromServer() throws IOException {
108                byte[] uncompressedData = null;
109 
110                int lengthRead = readFully(this.packetHeaderBuffer, 0, 7);
111 
112                if (lengthRead < 7) {
113                        throw new IOException("Unexpected end of input stream");
114                }
115 
116                int compressedPacketLength = ((this.packetHeaderBuffer[0] & 0xff))
117                                + (((this.packetHeaderBuffer[1] & 0xff)) << 8)
118                                + (((this.packetHeaderBuffer[2] & 0xff)) << 16);
119 
120                int uncompressedLength = ((this.packetHeaderBuffer[4] & 0xff))
121                                + (((this.packetHeaderBuffer[5] & 0xff)) << 8)
122                                + (((this.packetHeaderBuffer[6] & 0xff)) << 16);
123 
124                if (this.connection.getTraceProtocol()) {
125                        try {
126                                this.connection.getLog().logTrace(
127                                                "Reading compressed packet of length "
128                                                                + compressedPacketLength + " uncompressed to "
129                                                                + uncompressedLength);
130                        } catch (SQLException sqlEx) {
131                                throw new IOException(sqlEx.toString()); // should never
132                                                                                                                        // happen
133                        }
134                }
135 
136                if (uncompressedLength > 0) {
137                        uncompressedData = new byte[uncompressedLength];
138 
139                        byte[] compressedBuffer = new byte[compressedPacketLength];
140 
141                        readFully(compressedBuffer, 0, compressedPacketLength);
142 
143                        try {
144                                this.inflater.reset();
145                        } catch (NullPointerException npe) {
146                                this.inflater = new Inflater();
147                        }
148 
149                        this.inflater.setInput(compressedBuffer);
150 
151                        try {
152                                this.inflater.inflate(uncompressedData);
153                        } catch (DataFormatException dfe) {
154                                throw new IOException(
155                                                "Error while uncompressing packet from server.");
156                        }
157 
158                        this.inflater.end();
159                } else {
160                        if (this.connection.getTraceProtocol()) {
161                                try {
162                                        this.connection
163                                                        .getLog()
164                                                        .logTrace(
165                                                                        "Packet didn't meet compression threshold, not uncompressing...");
166                                } catch (SQLException sqlEx) {
167                                        throw new IOException(sqlEx.toString()); // should never
168                                                                                                                                // happen
169                                }
170                        }
171 
172                        //        
173                        // Read data, note this this code is reached when using
174                        // compressed packets that have not been compressed, as well
175                        //
176                        uncompressedData = new byte[compressedPacketLength];
177                        readFully(uncompressedData, 0, compressedPacketLength);
178                }
179 
180                if (this.connection.getTraceProtocol()) {
181                        try {
182                                this.connection.getLog().logTrace(
183                                                "Uncompressed packet: \n"
184                                                                + StringUtils.dumpAsHex(uncompressedData,
185                                                                                compressedPacketLength));
186                        } catch (SQLException sqlEx) {
187                                throw new IOException(sqlEx.toString()); // should never
188                                                                                                                        // happen
189                        }
190                }
191 
192                if ((this.buffer != null) && (this.pos < this.buffer.length)) {
193                        if (this.connection.getTraceProtocol()) {
194                                try {
195                                        this.connection.getLog().logTrace(
196                                                        "Combining remaining packet with new: ");
197                                } catch (SQLException sqlEx) {
198                                        throw new IOException(sqlEx.toString()); // should never
199                                                                                                                                // happen
200                                }
201                        }
202 
203                        int remaining = this.buffer.length - this.pos;
204                        byte[] newBuffer = new byte[remaining + uncompressedData.length];
205 
206                        int newIndex = 0;
207 
208                        for (int i = this.pos; i < this.buffer.length; i++)
209                                newBuffer[newIndex++] = this.buffer[i];
210 
211                        System.arraycopy(uncompressedData, 0, newBuffer, newIndex,
212                                        uncompressedData.length);
213 
214                        uncompressedData = newBuffer;
215                }
216 
217                this.pos = 0;
218                this.buffer = uncompressedData;
219 
220                return;
221        }
222 
223        /**
224         * Determines if another packet needs to be read from the server to be able
225         * to read numBytes from the stream.
226         * 
227         * @param numBytes
228         *            the number of bytes to be read
229         * 
230         * @throws IOException
231         *             if an I/O error occors.
232         */
233        private void getNextPacketIfRequired(int numBytes) throws IOException {
234                if ((this.buffer == null)
235                                || ((this.pos + numBytes) > this.buffer.length)) {
236                        getNextPacketFromServer();
237                }
238        }
239 
240        /**
241         * @see java.io.InputStream#read()
242         */
243        public int read() throws IOException {
244                try {
245                        getNextPacketIfRequired(1);
246                } catch (IOException ioEx) {
247                        return -1;
248                }
249 
250                return this.buffer[this.pos++] & 0xff;
251        }
252 
253        /**
254         * @see java.io.InputStream#read(byte)
255         */
256        public int read(byte[] b) throws IOException {
257                return read(b, 0, b.length);
258        }
259 
260        /**
261         * @see java.io.InputStream#read(byte, int, int)
262         */
263        public int read(byte[] b, int off, int len) throws IOException {
264                if (b == null) {
265                        throw new NullPointerException();
266                } else if ((off < 0) || (off > b.length) || (len < 0)
267                                || ((off + len) > b.length) || ((off + len) < 0)) {
268                        throw new IndexOutOfBoundsException();
269                }
270 
271                if (len <= 0) {
272                        return 0;
273                }
274 
275                try {
276                        getNextPacketIfRequired(len);
277                } catch (IOException ioEx) {
278                        return -1;
279                }
280 
281                System.arraycopy(this.buffer, this.pos, b, off, len);
282                this.pos += len;
283 
284                return len;
285        }
286 
287        private final int readFully(byte[] b, int off, int len) throws IOException {
288                if (len < 0) {
289                        throw new IndexOutOfBoundsException();
290                }
291 
292                int n = 0;
293 
294                while (n < len) {
295                        int count = this.in.read(b, off + n, len - n);
296 
297                        if (count < 0) {
298                                throw new EOFException();
299                        }
300 
301                        n += count;
302                }
303 
304                return n;
305        }
306 
307        /**
308         * @see java.io.InputStream#skip(long)
309         */
310        public long skip(long n) throws IOException {
311                long count = 0;
312 
313                for (long i = 0; i < n; i++) {
314                        int bytesRead = read();
315 
316                        if (bytesRead == -1) {
317                                break;
318                        }
319 
320                        count++;
321                }
322 
323                return count;
324        }
325}

[all classes][com.mysql.jdbc]
EMMA 2.0.4217 (C) Vladimir Roubtsov