mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
08.37.2014 f21d49179409cc1f7089e08d6ad1596bfd4de47f
Facilitate compression and cryptographic operations to/from byte strings:

* added ByteStringBuilder.asOutputStream()
* added test case illustrating compression.

1 files deleted
4 files modified
214 ■■■■■ changed files
opendj-core/src/main/java/com/forgerock/opendj/util/ByteSequenceOutputStream.java 113 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/io/ASN1.java 7 ●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/io/ASN1OutputStreamWriter.java 25 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java 38 ●●●●● patch | view | raw | blame | history
opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteStringBuilderTestCase.java 31 ●●●●● patch | view | raw | blame | history
opendj-core/src/main/java/com/forgerock/opendj/util/ByteSequenceOutputStream.java
File was deleted
opendj-core/src/main/java/org/forgerock/opendj/io/ASN1.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2012-2013 ForgeRock AS.
 *      Portions copyright 2012-2014 ForgeRock AS.
 */
package org.forgerock.opendj.io;
@@ -35,8 +35,6 @@
import org.forgerock.opendj.ldap.ByteString;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import com.forgerock.opendj.util.ByteSequenceOutputStream;
/**
 * This class contains various static factory methods for creating ASN.1 readers
 * and writers.
@@ -280,8 +278,7 @@
     * @return The new ASN.1 writer.
     */
    public static ASN1Writer getWriter(final ByteStringBuilder builder) {
        final ByteSequenceOutputStream outputStream = new ByteSequenceOutputStream(builder);
        return getWriter(outputStream);
        return getWriter(builder.asOutputStream());
    }
    /**
opendj-core/src/main/java/org/forgerock/opendj/io/ASN1OutputStreamWriter.java
@@ -22,7 +22,7 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions copyright 2012-2013 ForgeRock AS.
 *      Portions copyright 2012-2014 ForgeRock AS.
 */
package org.forgerock.opendj.io;
@@ -37,7 +37,6 @@
import org.forgerock.opendj.ldap.ByteSequence;
import org.forgerock.opendj.ldap.ByteStringBuilder;
import com.forgerock.opendj.util.ByteSequenceOutputStream;
import com.forgerock.opendj.util.StaticUtils;
/**
@@ -46,7 +45,7 @@
final class ASN1OutputStreamWriter extends AbstractASN1Writer implements ASN1Writer {
    private final OutputStream rootStream;
    private OutputStream out;
    private final ArrayList<ByteSequenceOutputStream> streamStack;
    private final ArrayList<ByteStringBuilder> streamStack;
    private int stackDepth;
    /**
@@ -58,7 +57,7 @@
    ASN1OutputStreamWriter(final OutputStream stream) {
        this.out = stream;
        this.rootStream = stream;
        this.streamStack = new ArrayList<ByteSequenceOutputStream>();
        this.streamStack = new ArrayList<ByteStringBuilder>();
        this.stackDepth = -1;
    }
@@ -70,7 +69,6 @@
            writeEndSequence();
        }
        rootStream.flush();
        streamStack.clear();
        rootStream.close();
    }
@@ -104,23 +102,23 @@
            throw new IllegalStateException(message.toString());
        }
        final ByteSequenceOutputStream childStream = streamStack.get(stackDepth);
        final ByteStringBuilder childStream = streamStack.get(stackDepth);
        // Decrement the stack depth and get the parent stream
        --stackDepth;
        final OutputStream parentStream = stackDepth < 0 ? rootStream : streamStack.get(stackDepth);
        final OutputStream parentStream =
                stackDepth < 0 ? rootStream : streamStack.get(stackDepth).asOutputStream();
        // Switch to parent stream and reset the sub-stream
        out = parentStream;
        // Write the length and contents of the sub-stream
        writeLength(childStream.length());
        childStream.writeTo(parentStream);
        childStream.copyTo(parentStream);
        IO_LOG.trace("WRITE ASN.1 END SEQUENCE(length={})", childStream.length());
        childStream.reset();
        childStream.clear();
        return this;
    }
@@ -318,12 +316,11 @@
        // Make sure we have a cached sub-stream at this depth
        if (stackDepth >= streamStack.size()) {
            final ByteSequenceOutputStream subStream =
                    new ByteSequenceOutputStream(new ByteStringBuilder());
            final ByteStringBuilder subStream = new ByteStringBuilder();
            streamStack.add(subStream);
            out = subStream;
            out = subStream.asOutputStream();
        } else {
            out = streamStack.get(stackDepth);
            out = streamStack.get(stackDepth).asOutputStream();
        }
        IO_LOG.trace("WRITE ASN.1 START SEQUENCE(type=0x{})", byteToHex(type));
opendj-core/src/main/java/org/forgerock/opendj/ldap/ByteStringBuilder.java
@@ -38,6 +38,30 @@
 * A mutable sequence of bytes backed by a byte array.
 */
public final class ByteStringBuilder implements ByteSequence {
    /**
     *  Output stream implementation.
     */
    private final class OutputStreamImpl extends OutputStream {
        @Override
        public void close() {
            // Do nothing.
        }
        @Override
        public void write(final byte[] bytes) {
            append(bytes);
        }
        @Override
        public void write(final byte[] bytes, final int i, final int i1) {
            append(bytes, i, i1);
        }
        @Override
        public void write(final int i) {
            append(((byte) (i & 0xFF)));
        }
    }
    /**
     * A sub-sequence of the parent byte string builder. The sub-sequence will
@@ -655,6 +679,20 @@
    }
    /**
     * Returns an {@link OutputStream} whose write operations append data to
     * this byte string builder. The returned output stream will never throw an
     * {@link IOException} and its {@link OutputStream#close() close} method
     * does not do anything.
     *
     * @return An {@link OutputStream} whose write operations append data to
     *         this byte string builder.
     */
    public OutputStream asOutputStream() {
        // Is it worth caching this?
        return new OutputStreamImpl();
    }
    /**
     * Returns a {@link ByteSequenceReader} which can be used to incrementally
     * read and decode data from this byte string builder.
     * <p>
opendj-core/src/test/java/org/forgerock/opendj/ldap/ByteStringBuilderTestCase.java
@@ -29,8 +29,11 @@
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.InflaterOutputStream;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
@@ -151,6 +154,34 @@
        Assert.assertEquals(bsb.getBackingArray().length, 8);
    }
    @Test
    public void testAsOutputStream() throws Exception {
        final ByteStringBuilder bsb = new ByteStringBuilder();
        final OutputStream os = bsb.asOutputStream();
        os.write((byte) 0x01);
        os.write(2);
        os.write(new byte[] { 2, 3, 4, 5 }, 1, 2);
        os.close();
        Assert.assertEquals(bsb.length(), 4);
        Assert.assertEquals(bsb.toByteArray(), new byte[] { 1, 2, 3, 4 });
    }
    @Test
    public void testAsOutputStreamCompress() throws Exception {
        final ByteString data = ByteString.wrap(new byte[4000]);
        final ByteStringBuilder compressedData = new ByteStringBuilder();
        final OutputStream compressor = new DeflaterOutputStream(compressedData.asOutputStream());
        data.copyTo(compressor);
        compressor.close();
        Assert.assertTrue(compressedData.length() > 0 && compressedData.length() < 4000);
        final ByteStringBuilder decompressedData = new ByteStringBuilder();
        final OutputStream decompressor = new InflaterOutputStream(decompressedData.asOutputStream());
        compressedData.copyTo(decompressor);
        decompressor.close();
        Assert.assertEquals(decompressedData.toByteString(), data);
    }
    @DataProvider(name = "builderProvider")
    private Object[][] byteStringBuilderProvider() throws Exception {
        final ByteBuffer testBuffer = ByteBuffer.wrap(EIGHT_BYTES);