You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2016/09/20 12:01:20 UTC
svn commit: r1761561 - in /qpid/java/trunk:
broker-core/src/main/java/org/apache/qpid/server/queue/
broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/
broker-plugins/management-http/src/main/java/org/apache/qpid/serv...
Author: orudyy
Date: Tue Sep 20 12:01:20 2016
New Revision: 1761561
URL: http://svn.apache.org/viewvc?rev=1761561&view=rev
Log:
QPID-7408: Replace GZIPOutputStreamAdapter with GunzipOutputStream extending InflaterOutputStream
Added:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/GunzipOutputStream.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/LimitingOutputStream.java
qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GunzipOutputStreamTest.java
- copied, changed from r1761411, qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GZIPOutputStreamAdapterTest.java
Removed:
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/GZIPOutputStreamAdapter.java
qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GZIPOutputStreamAdapterTest.java
Modified:
qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
Modified: qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java?rev=1761561&r1=1761560&r2=1761561&view=diff
==============================================================================
--- qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java (original)
+++ qpid/java/trunk/broker-core/src/main/java/org/apache/qpid/server/queue/AbstractQueue.java Tue Sep 20 12:01:20 2016
@@ -110,6 +110,7 @@ import org.apache.qpid.server.util.Serve
import org.apache.qpid.server.util.StateChangeListener;
import org.apache.qpid.server.virtualhost.VirtualHostUnavailableException;
import org.apache.qpid.transport.TransportException;
+import org.apache.qpid.util.GZIPUtils;
public abstract class AbstractQueue<X extends AbstractQueue<X>>
extends AbstractConfiguredObject<X>
@@ -2791,18 +2792,16 @@ public abstract class AbstractQueue<X ex
public void write(OutputStream outputStream) throws IOException
{
ServerMessage message = _messageReference.getMessage();
- int length = (int) (_limit == UNLIMITED ? message.getSize() : _limit);
+ int length = (int) ((_limit == UNLIMITED || GZIPUtils.GZIP_CONTENT_ENCODING.equals(getContentEncoding())) ? message.getSize() : _limit);
Collection<QpidByteBuffer> content = message.getContent(0, length);
try
{
for (QpidByteBuffer b : content)
{
-
int len = b.remaining();
byte[] data = new byte[len];
b.get(data);
outputStream.write(data);
-
}
}
finally
Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/GunzipOutputStream.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/GunzipOutputStream.java?rev=1761561&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/GunzipOutputStream.java (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/GunzipOutputStream.java Tue Sep 20 12:01:20 2016
@@ -0,0 +1,305 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.management.plugin;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.zip.CRC32;
+import java.util.zip.CheckedOutputStream;
+import java.util.zip.Deflater;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterOutputStream;
+
+public class GunzipOutputStream extends InflaterOutputStream
+{
+ private final GZIPHeader _header = new GZIPHeader();
+ private final GZIPTrailer _trailer = new GZIPTrailer();
+ private final byte[] _singleByteArray = new byte[1];
+ private StreamState _streamState = StreamState.HEADER_PARSING;
+ private final CRC32 _crc;
+
+ public GunzipOutputStream(final OutputStream targetOutputStream)
+ {
+ super(new CheckedOutputStream(targetOutputStream, new CRC32()), new Inflater(true));
+ _crc = (CRC32)((CheckedOutputStream)out).getChecksum();
+ }
+
+ @Override
+ public void write(final byte data[], final int offset, final int length) throws IOException
+ {
+ ByteArrayInputStream bais = new ByteArrayInputStream(data, offset, length);
+ int b;
+ while ((b = bais.read()) != -1)
+ {
+ if (_streamState == StreamState.DONE)
+ {
+ // another member is coming
+ _streamState = StreamState.HEADER_PARSING;
+ _crc.reset();
+ _header.reset();
+ _trailer.reset();
+ inf.reset();
+ }
+
+ if (_streamState == StreamState.HEADER_PARSING)
+ {
+ _header.headerByte(b);
+ if (_header.getState() == HeaderState.DONE)
+ {
+ _streamState = StreamState.INFLATING;
+ continue;
+ }
+ }
+
+ if (_streamState == StreamState.INFLATING)
+ {
+ _singleByteArray[0] = (byte) b;
+ super.write(_singleByteArray, 0, 1);
+
+ if (inf.finished())
+ {
+ _streamState = StreamState.TRAILER_PARSING;
+ continue;
+ }
+ }
+
+ if (_streamState == StreamState.TRAILER_PARSING)
+ {
+ if (_trailer.trailerByte(b))
+ {
+ _trailer.verify(_crc);
+ _streamState = StreamState.DONE;
+ continue;
+ }
+ }
+ }
+ }
+
+ private enum StreamState
+ {
+ HEADER_PARSING, INFLATING, TRAILER_PARSING, DONE
+ }
+
+ private enum HeaderState
+ {
+ ID1, ID2, CM, FLG, MTIME_0, MTIME_1, MTIME_2, MTIME_3, XFL, OS, XLEN_0, XLEN_1, FEXTRA, FNAME, FCOMMENT, CRC16_0, CRC16_1, DONE
+ }
+
+ private class GZIPHeader
+ {
+ private static final int GZIP_MAGIC_1 = 0x1F;
+ private static final int GZIP_MAGIC_2 = 0x8B;
+ private static final int SUPPORTED_COMPRESSION_METHOD = Deflater.DEFLATED;
+ private HeaderState _state = HeaderState.ID1;
+ private byte _flags;
+ private byte _xlen0;
+ private int _xlen;
+ private int _fExtraCounter;
+
+ private void headerByte(int headerByte) throws IOException
+ {
+ int b = headerByte & 0xff;
+ switch (_state)
+ {
+ case ID1:
+ if (b != GZIP_MAGIC_1)
+ {
+ throw new IOException(String.format("Incorrect first magic byte: got '%X' but expected '%X'",
+ headerByte,
+ GZIP_MAGIC_1));
+ }
+ _state = HeaderState.ID2;
+ break;
+ case ID2:
+ if (b != GZIP_MAGIC_2)
+ {
+ throw new IOException(String.format("Incorrect second magic byte: got '%X' but expected '%X'",
+ headerByte,
+ GZIP_MAGIC_2));
+ }
+ _state = HeaderState.CM;
+ break;
+ case CM:
+ if (b != SUPPORTED_COMPRESSION_METHOD)
+ {
+ throw new IOException(String.format("Unexpected compression method : '%X'", b));
+ }
+ _state = HeaderState.FLG;
+ break;
+ case FLG:
+ _flags = (byte) b;
+ _state = HeaderState.MTIME_0;
+ break;
+ case MTIME_0:
+ _state = HeaderState.MTIME_1;
+ break;
+ case MTIME_1:
+ _state = HeaderState.MTIME_2;
+ break;
+ case MTIME_2:
+ _state = HeaderState.MTIME_3;
+ break;
+ case MTIME_3:
+ _state = HeaderState.XFL;
+ break;
+ case XFL:
+ _state = HeaderState.OS;
+ break;
+ case OS:
+ adjustStateAccordingToFlags();
+ break;
+ case XLEN_0:
+ _xlen0 = (byte) b;
+ _state = HeaderState.XLEN_1;
+ break;
+ case XLEN_1:
+ _xlen = b << 8 | _xlen0;
+ _state = HeaderState.FEXTRA;
+ break;
+ case FEXTRA:
+ _fExtraCounter++;
+ if (_fExtraCounter == _xlen)
+ {
+ adjustStateAccordingToFlags(HeaderState.XLEN_0);
+ }
+ break;
+ case FNAME:
+ if (b == 0)
+ {
+ adjustStateAccordingToFlags(HeaderState.XLEN_0, HeaderState.FNAME);
+ }
+ break;
+ case FCOMMENT:
+ if (b == 0)
+ {
+ adjustStateAccordingToFlags(HeaderState.XLEN_0, HeaderState.FNAME, HeaderState.FCOMMENT);
+ }
+ break;
+ case CRC16_0:
+ _state = HeaderState.CRC16_1;
+ break;
+ case CRC16_1:
+ _state = HeaderState.DONE;
+ break;
+ default:
+ throw new IOException("Unexpected state " + _state);
+ }
+ }
+
+ private void adjustStateAccordingToFlags(HeaderState... previousStates)
+ {
+ EnumSet<HeaderState> previous = previousStates.length == 0
+ ? EnumSet.noneOf(HeaderState.class)
+ : EnumSet.copyOf(Arrays.asList(previousStates));
+ if ((_flags & (byte) 4) != 0 && !previous.contains(HeaderState.XLEN_0))
+ {
+ _state = HeaderState.XLEN_0;
+ }
+ else if ((_flags & (byte) 8) != 0 && !previous.contains(HeaderState.FNAME))
+ {
+ _state = HeaderState.FNAME;
+ }
+ else if ((_flags & (byte) 16) != 0 && !previous.contains(HeaderState.FCOMMENT))
+ {
+ _state = HeaderState.FCOMMENT;
+ }
+ else if ((_flags & (byte) 2) != 0 && !previous.contains(HeaderState.CRC16_0))
+ {
+ _state = HeaderState.CRC16_0;
+ }
+ else
+ {
+ _state = HeaderState.DONE;
+ }
+ }
+
+ private HeaderState getState()
+ {
+ return _state;
+ }
+
+ private void reset()
+ {
+ _state = HeaderState.ID1;
+ _flags = 0;
+ _xlen0 = 0;
+ _xlen = 0;
+ _fExtraCounter = 0;
+ }
+ }
+
+ private class GZIPTrailer
+ {
+ private static final int TRAILER_SIZE = 8;
+ private static final long SIZE_MASK = 0xffffffffL;
+ private byte[] _trailerBytes = new byte[TRAILER_SIZE];
+ private int _receivedByteIndex;
+
+ private boolean trailerByte(int b) throws IOException
+ {
+ if (_receivedByteIndex < TRAILER_SIZE)
+ {
+ _trailerBytes[_receivedByteIndex++] = (byte) (b & 0xff);
+ return _receivedByteIndex == TRAILER_SIZE;
+ }
+ else
+ {
+ throw new IOException(
+ "Received bytes exceeds GZIP trailer length. Multipe memeber support is not implemented");
+ }
+ }
+
+ private void verify(CRC32 crc) throws IOException
+ {
+ try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(_trailerBytes)))
+ {
+ long crc32 = readLittleEndianInt(in);
+ if (crc32 != crc.getValue())
+ {
+ throw new IOException("crc32 mismatch. Gzip-compressed data is corrupted");
+ }
+ long isize = readLittleEndianInt(in);
+ if (isize != (inf.getBytesWritten() & SIZE_MASK))
+ {
+ throw new IOException("Uncompressed size mismatch. Gzip-compressed data is corrupted");
+ }
+ }
+ }
+
+ private long readLittleEndianInt(final DataInputStream inData) throws IOException
+ {
+ return inData.readUnsignedByte()
+ | (inData.readUnsignedByte() << 8)
+ | (inData.readUnsignedByte() << 16)
+ | (((long) inData.readUnsignedByte()) << 24);
+ }
+
+ private void reset()
+ {
+ _receivedByteIndex = 0;
+ }
+
+ }
+}
Added: qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/LimitingOutputStream.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/LimitingOutputStream.java?rev=1761561&view=auto
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/LimitingOutputStream.java (added)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/LimitingOutputStream.java Tue Sep 20 12:01:20 2016
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.qpid.server.management.plugin;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class LimitingOutputStream extends OutputStream
+{
+ private final OutputStream _outputStream;
+ private final long _limit;
+ private long _counter;
+
+ public LimitingOutputStream(OutputStream outputStream, long limit)
+ {
+ _outputStream = outputStream;
+ _limit = limit;
+ }
+
+ @Override
+ public void write(final int b) throws IOException
+ {
+ if (_counter < _limit)
+ {
+ _outputStream.write(b);
+ _counter++;
+ }
+ }
+
+ @Override
+ public void write(final byte[] b, final int off, final int len) throws IOException
+ {
+ if (_counter < _limit)
+ {
+ int written = Math.min(len, (int)(_limit - _counter));
+ _outputStream.write(b, off, written);
+ _counter += written;
+ }
+ }
+
+ @Override
+ public void write(final byte[] b) throws IOException
+ {
+ write(b, 0, b.length);
+ }
+
+ @Override
+ public void flush() throws IOException
+ {
+ _outputStream.flush();
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ _outputStream.close();
+ }
+}
Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java?rev=1761561&r1=1761560&r2=1761561&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/AbstractServlet.java Tue Sep 20 12:01:20 2016
@@ -32,6 +32,7 @@ import java.security.PrivilegedException
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.zip.GZIPOutputStream;
import javax.security.auth.Subject;
import javax.servlet.ServletConfig;
@@ -41,21 +42,21 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.qpid.server.model.Content;
-import org.apache.qpid.server.model.CustomRestHeaders;
-import org.apache.qpid.server.model.RestContentHeader;
-
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.qpid.server.management.plugin.GunzipOutputStream;
import org.apache.qpid.server.management.plugin.HttpManagementConfiguration;
import org.apache.qpid.server.management.plugin.HttpManagementUtil;
+import org.apache.qpid.server.management.plugin.LimitingOutputStream;
import org.apache.qpid.server.model.Broker;
import org.apache.qpid.server.model.ConfiguredObjectJacksonModule;
+import org.apache.qpid.server.model.Content;
+import org.apache.qpid.server.model.CustomRestHeaders;
+import org.apache.qpid.server.model.RestContentHeader;
import org.apache.qpid.server.util.ConnectionScopedRuntimeException;
-import org.apache.qpid.server.management.plugin.GZIPOutputStreamAdapter;
public abstract class AbstractServlet extends HttpServlet
{
@@ -328,6 +329,27 @@ public abstract class AbstractServlet ex
throws IOException
{
Map<String, Object> headers = getResponseHeaders(content);
+
+ try (OutputStream os = getOutputStream(request, response, headers))
+ {
+ response.setStatus(HttpServletResponse.SC_OK);
+ for (Map.Entry<String, Object> entry : headers.entrySet())
+ {
+ response.setHeader(entry.getKey(), String.valueOf(entry.getValue()));
+ }
+ content.write(os);
+ }
+ catch (IOException e)
+ {
+ LOGGER.warn("Unexpected exception processing request", e);
+ sendJsonErrorResponse(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ }
+ }
+
+ private OutputStream getOutputStream(final HttpServletRequest request,
+ final HttpServletResponse response,
+ Map<String, Object> headers) throws IOException
+ {
boolean isGzipCompressed = GZIP_CONTENT_ENCODING.equals(headers.get(CONTENT_ENCODING_HEADER.toUpperCase()));
boolean isCompressingAccepted = HttpManagementUtil.isCompressingAccepted(request, _managementConfiguration);
if (isGzipCompressed && !isCompressingAccepted)
@@ -339,25 +361,35 @@ public abstract class AbstractServlet ex
{
limit = Long.parseLong(String.valueOf(headers.get(CONTENT_LIMIT.toUpperCase())));
}
+ OutputStream stream = response.getOutputStream();
- try (OutputStream os = isGzipCompressed && isCompressingAccepted && limit < 0
- ? response.getOutputStream()
- : isGzipCompressed && (!isCompressingAccepted || limit >= 0)
- ? new GZIPOutputStreamAdapter(getOutputStream(request, response), limit)
- : getOutputStream(request, response))
+ if (isGzipCompressed)
{
- response.setStatus(HttpServletResponse.SC_OK);
- for (Map.Entry<String, Object> entry : headers.entrySet())
+ if (!isCompressingAccepted)
{
- response.setHeader(entry.getKey(), String.valueOf(entry.getValue()));
+ if (limit > 0)
+ {
+ stream = new LimitingOutputStream(stream, limit);
+ }
+ stream = new GunzipOutputStream(stream);
+ }
+ else
+ {
+ if (limit > 0)
+ {
+ stream = new GunzipOutputStream(new LimitingOutputStream(new GZIPOutputStream(stream), limit));
+ }
}
- content.write(os);
}
- catch (IOException e)
+ else
{
- LOGGER.warn("Unexpected exception processing request", e);
- sendJsonErrorResponse(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
+ if (isCompressingAccepted)
+ {
+ stream = new GZIPOutputStream(stream);
+ }
}
+
+ return stream;
}
private Map<String, Object> getResponseHeaders(final Object content)
Copied: qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GunzipOutputStreamTest.java (from r1761411, qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GZIPOutputStreamAdapterTest.java)
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GunzipOutputStreamTest.java?p2=qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GunzipOutputStreamTest.java&p1=qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GZIPOutputStreamAdapterTest.java&r1=1761411&r2=1761561&rev=1761561&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GZIPOutputStreamAdapterTest.java (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/test/java/org/apache/qpid/server/management/plugin/GunzipOutputStreamTest.java Tue Sep 20 12:01:20 2016
@@ -24,37 +24,65 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;
+import javax.xml.bind.DatatypeConverter;
+
import org.apache.qpid.test.utils.QpidTestCase;
-public class GZIPOutputStreamAdapterTest extends QpidTestCase
+public class GunzipOutputStreamTest extends QpidTestCase
{
+ // base64 encoded content of 'gzip -N test.txt' containing text: This is test
+ private static final String GZIP_CONTENT_WITH_EMBEDDED_FILE_NAME =
+ "H4sICIAM4FcAA3Rlc3QudHh0AAvJyCxWAKKS1OISANCadxgMAAAA";
+
+ // base64 encoded content of 'gzip -c -N test.txt > test.txt.gz ; gzip -c -N test1.txt >> test.txt.gz'
+ // containing texts "This is test" and "Another test text" accordingly
+ private static final String GZIP_CONTENT_WITH_MULTIPLE_MEMBERS =
+ "H4sICNoV4VcAA3Rlc3QudHh0AAvJyCxWAKKS1OISANCadxgMAAAA"
+ + "H4sICOQV4VcAA3Rlc3QxLnR4dABzzMsvyUgtUihJLS4BEhUlAHeK0kERAAAA";
+ private static final String TEST_TEXT = "This is test";
+ private static final String TEST_TEXT2 = "Another test text";
public void testDecompressing() throws IOException
{
String testText = generateTestText();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- GZIPOutputStreamAdapter adapter = new GZIPOutputStreamAdapter(outputStream, 128, -1);
+ GunzipOutputStream adapter = new GunzipOutputStream(outputStream);
compressAndDecompressWithAdapter(testText, adapter);
assertEquals("Unexpected content", testText, new String(outputStream.toByteArray()));
}
- public void testDecompressingLimited() throws IOException
+ public void testDecompressingWithFileName() throws IOException
{
- String testText = generateTestText();
+ byte[] data = DatatypeConverter.parseBase64Binary(GZIP_CONTENT_WITH_EMBEDDED_FILE_NAME);
+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- GZIPOutputStreamAdapter adapter = new GZIPOutputStreamAdapter(outputStream, 128, testText.length() / 2);
+ GunzipOutputStream adapter = new GunzipOutputStream(outputStream);
+ adapter.write(data);
- compressAndDecompressWithAdapter(testText, adapter);
+ assertEquals("Unexpected content", TEST_TEXT, new String(outputStream.toByteArray()));
+ }
+
+ public void testDecompressingMultipleMembers() throws IOException
+ {
+ byte[] data = DatatypeConverter.parseBase64Binary(GZIP_CONTENT_WITH_MULTIPLE_MEMBERS);
+
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ GunzipOutputStream adapter = new GunzipOutputStream(outputStream);
+ for (int i = 0; i < data.length; i++)
+ {
+ adapter.write(data[i]);
+ }
- assertEquals("Unexpected content",
- testText.substring(0, testText.length() / 2),
- new String(outputStream.toByteArray()));
+ StringBuilder expected = new StringBuilder(TEST_TEXT);
+ expected.append(TEST_TEXT2);
+ assertEquals("Unexpected content", expected.toString(), new String(outputStream.toByteArray()));
}
- private void compressAndDecompressWithAdapter(final String testText, final GZIPOutputStreamAdapter adapter) throws IOException
+ private void compressAndDecompressWithAdapter(final String testText, final GunzipOutputStream adapter)
+ throws IOException
{
byte[] data = compress(testText);
byte[] buffer = new byte[256];
@@ -64,7 +92,7 @@ public class GZIPOutputStreamAdapterTest
{
int length = Math.min(remaining, buffer.length);
System.arraycopy(data, written, buffer, 0, length);
- adapter.write(buffer);
+ adapter.write(buffer, 0, length);
written += length;
remaining -= length;
}
@@ -86,8 +114,16 @@ public class GZIPOutputStreamAdapterTest
int i = 0;
while (sb.length() < 5000)
{
- sb.append(" A simple test text ").append(i++);
+ if (i % 2 == 0)
+ {
+ sb.append(TEST_TEXT);
+ }
+ else
+ {
+ sb.append(TEST_TEXT2);
+ }
+ sb.append(" ").append(i++);
}
return sb.toString();
}
-}
\ No newline at end of file
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org