Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dca955a9 authored by Alex Klyubin's avatar Alex Klyubin Committed by Gerrit Code Review
Browse files

Merge "More general OutputStreamDataSink."

parents a85e0aa8 e54b2753
Loading
Loading
Loading
Loading
+11 −6
Original line number Original line Diff line number Diff line
@@ -19,12 +19,13 @@ package com.android.apksigner.core;
import com.android.apksigner.core.internal.apk.v1.DigestAlgorithm;
import com.android.apksigner.core.internal.apk.v1.DigestAlgorithm;
import com.android.apksigner.core.internal.apk.v1.V1SchemeSigner;
import com.android.apksigner.core.internal.apk.v1.V1SchemeSigner;
import com.android.apksigner.core.internal.apk.v2.V2SchemeSigner;
import com.android.apksigner.core.internal.apk.v2.V2SchemeSigner;
import com.android.apksigner.core.internal.util.ByteArrayOutputStreamSink;
import com.android.apksigner.core.internal.util.MessageDigestSink;
import com.android.apksigner.core.internal.util.MessageDigestSink;
import com.android.apksigner.core.internal.util.Pair;
import com.android.apksigner.core.internal.util.Pair;
import com.android.apksigner.core.util.DataSink;
import com.android.apksigner.core.util.DataSink;
import com.android.apksigner.core.util.DataSinks;
import com.android.apksigner.core.util.DataSource;
import com.android.apksigner.core.util.DataSource;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.MessageDigest;
@@ -593,7 +594,8 @@ public class DefaultApkSignerEngine implements ApkSignerEngine {
        private final Object mLock = new Object();
        private final Object mLock = new Object();


        private boolean mDone;
        private boolean mDone;
        private ByteArrayOutputStreamSink mBuf;
        private DataSink mDataSink;
        private ByteArrayOutputStream mDataSinkBuf;


        private GetJarEntryDataRequest(String entryName) {
        private GetJarEntryDataRequest(String entryName) {
            mEntryName = entryName;
            mEntryName = entryName;
@@ -608,10 +610,13 @@ public class DefaultApkSignerEngine implements ApkSignerEngine {
        public DataSink getDataSink() {
        public DataSink getDataSink() {
            synchronized (mLock) {
            synchronized (mLock) {
                checkNotDone();
                checkNotDone();
                if (mBuf == null) {
                if (mDataSinkBuf == null) {
                    mBuf = new ByteArrayOutputStreamSink();
                    mDataSinkBuf = new ByteArrayOutputStream();
                }
                if (mDataSink == null) {
                    mDataSink = DataSinks.asDataSink(mDataSinkBuf);
                }
                }
                return mBuf;
                return mDataSink;
            }
            }
        }
        }


@@ -644,7 +649,7 @@ public class DefaultApkSignerEngine implements ApkSignerEngine {
                if (!mDone) {
                if (!mDone) {
                    throw new IllegalStateException("Not yet done");
                    throw new IllegalStateException("Not yet done");
                }
                }
                return (mBuf != null) ? mBuf.getData() : new byte[0];
                return (mDataSinkBuf != null) ? mDataSinkBuf.toByteArray() : new byte[0];
            }
            }
        }
        }
    }
    }
+78 −0
Original line number Original line Diff line number Diff line
@@ -16,47 +16,63 @@


package com.android.apksigner.core.internal.util;
package com.android.apksigner.core.internal.util;


import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;

import com.android.apksigner.core.util.DataSink;
import com.android.apksigner.core.util.DataSink;


import java.io.ByteArrayOutputStream;
/**
import java.nio.ByteBuffer;
 * {@link DataSink} which outputs received data into the associated {@link OutputStream}.
 */
public class OutputStreamDataSink implements DataSink {

    private static final int MAX_READ_CHUNK_SIZE = 65536;

    private final OutputStream mOut;


    /**
    /**
 * Data sink which stores all input data into an internal {@link ByteArrayOutputStream}, thus
     * Constructs a new {@code OutputStreamDataSink} which outputs received data into the provided
 * accepting an arbitrary amount of data.
     * {@link OutputStream}.
     */
     */
public class ByteArrayOutputStreamSink implements DataSink {
    public OutputStreamDataSink(OutputStream out) {
        if (out == null) {
            throw new NullPointerException("out == null");
        }
        mOut = out;
    }


    private final ByteArrayOutputStream mBuf = new ByteArrayOutputStream();
    /**
     * Returns {@link OutputStream} into which this data sink outputs received data.
     */
    public OutputStream getOutputStream() {
        return mOut;
    }


    @Override
    @Override
    public void consume(byte[] buf, int offset, int length) {
    public void consume(byte[] buf, int offset, int length) throws IOException {
        mBuf.write(buf, offset, length);
        mOut.write(buf, offset, length);
    }
    }


    @Override
    @Override
    public void consume(ByteBuffer buf) {
    public void consume(ByteBuffer buf) throws IOException {
        if (!buf.hasRemaining()) {
        if (!buf.hasRemaining()) {
            return;
            return;
        }
        }


        if (buf.hasArray()) {
        if (buf.hasArray()) {
            mBuf.write(
            mOut.write(
                    buf.array(),
                    buf.array(),
                    buf.arrayOffset() + buf.position(),
                    buf.arrayOffset() + buf.position(),
                    buf.remaining());
                    buf.remaining());
            buf.position(buf.limit());
            buf.position(buf.limit());
        } else {
        } else {
            byte[] tmp = new byte[buf.remaining()];
            byte[] tmp = new byte[Math.min(buf.remaining(), MAX_READ_CHUNK_SIZE)];
            buf.get(tmp);
            while (buf.hasRemaining()) {
            mBuf.write(tmp, 0, tmp.length);
                int chunkSize = Math.min(buf.remaining(), tmp.length);
                buf.get(tmp, 0, chunkSize);
                mOut.write(tmp, 0, chunkSize);
            }
            }
        }
        }

    /**
     * Returns the data received so far.
     */
    public byte[] getData() {
        return mBuf.toByteArray();
    }
    }
}
}
+36 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed 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 com.android.apksigner.core.util;

import java.io.OutputStream;

import com.android.apksigner.core.internal.util.OutputStreamDataSink;

/**
 * Utility methods for working with {@link DataSink} abstraction.
 */
public abstract class DataSinks {
    private DataSinks() {}

    /**
     * Returns a {@link DataSink} which outputs received data into the provided
     * {@link OutputStream}.
     */
    public static DataSink asDataSink(OutputStream out) {
        return new OutputStreamDataSink(out);
    }
}