Loading tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java +11 −6 Original line number Diff line number Diff line Loading @@ -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.V1SchemeSigner; 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.Pair; import com.android.apksigner.core.util.DataSink; import com.android.apksigner.core.util.DataSinks; import com.android.apksigner.core.util.DataSource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.MessageDigest; Loading Loading @@ -593,7 +594,8 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { private final Object mLock = new Object(); private boolean mDone; private ByteArrayOutputStreamSink mBuf; private DataSink mDataSink; private ByteArrayOutputStream mDataSinkBuf; private GetJarEntryDataRequest(String entryName) { mEntryName = entryName; Loading @@ -608,10 +610,13 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { public DataSink getDataSink() { synchronized (mLock) { checkNotDone(); if (mBuf == null) { mBuf = new ByteArrayOutputStreamSink(); if (mDataSinkBuf == null) { mDataSinkBuf = new ByteArrayOutputStream(); } if (mDataSink == null) { mDataSink = DataSinks.asDataSink(mDataSinkBuf); } return mBuf; return mDataSink; } } Loading Loading @@ -644,7 +649,7 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { if (!mDone) { throw new IllegalStateException("Not yet done"); } return (mBuf != null) ? mBuf.getData() : new byte[0]; return (mDataSinkBuf != null) ? mDataSinkBuf.toByteArray() : new byte[0]; } } } Loading tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java→tools/apksigner/core/src/com/android/apksigner/core/internal/util/OutputStreamDataSink.java +78 −0 Original line number Diff line number Diff line Loading @@ -16,47 +16,63 @@ 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 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 * accepting an arbitrary amount of data. * Constructs a new {@code OutputStreamDataSink} which outputs received data into the provided * {@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 public void consume(byte[] buf, int offset, int length) { mBuf.write(buf, offset, length); public void consume(byte[] buf, int offset, int length) throws IOException { mOut.write(buf, offset, length); } @Override public void consume(ByteBuffer buf) { public void consume(ByteBuffer buf) throws IOException { if (!buf.hasRemaining()) { return; } if (buf.hasArray()) { mBuf.write( mOut.write( buf.array(), buf.arrayOffset() + buf.position(), buf.remaining()); buf.position(buf.limit()); } else { byte[] tmp = new byte[buf.remaining()]; buf.get(tmp); mBuf.write(tmp, 0, tmp.length); byte[] tmp = new byte[Math.min(buf.remaining(), MAX_READ_CHUNK_SIZE)]; while (buf.hasRemaining()) { 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(); } } tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java 0 → 100644 +36 −0 Original line number 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); } } Loading
tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java +11 −6 Original line number Diff line number Diff line Loading @@ -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.V1SchemeSigner; 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.Pair; import com.android.apksigner.core.util.DataSink; import com.android.apksigner.core.util.DataSinks; import com.android.apksigner.core.util.DataSource; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.MessageDigest; Loading Loading @@ -593,7 +594,8 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { private final Object mLock = new Object(); private boolean mDone; private ByteArrayOutputStreamSink mBuf; private DataSink mDataSink; private ByteArrayOutputStream mDataSinkBuf; private GetJarEntryDataRequest(String entryName) { mEntryName = entryName; Loading @@ -608,10 +610,13 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { public DataSink getDataSink() { synchronized (mLock) { checkNotDone(); if (mBuf == null) { mBuf = new ByteArrayOutputStreamSink(); if (mDataSinkBuf == null) { mDataSinkBuf = new ByteArrayOutputStream(); } if (mDataSink == null) { mDataSink = DataSinks.asDataSink(mDataSinkBuf); } return mBuf; return mDataSink; } } Loading Loading @@ -644,7 +649,7 @@ public class DefaultApkSignerEngine implements ApkSignerEngine { if (!mDone) { throw new IllegalStateException("Not yet done"); } return (mBuf != null) ? mBuf.getData() : new byte[0]; return (mDataSinkBuf != null) ? mDataSinkBuf.toByteArray() : new byte[0]; } } } Loading
tools/apksigner/core/src/com/android/apksigner/core/internal/util/ByteArrayOutputStreamSink.java→tools/apksigner/core/src/com/android/apksigner/core/internal/util/OutputStreamDataSink.java +78 −0 Original line number Diff line number Diff line Loading @@ -16,47 +16,63 @@ 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 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 * accepting an arbitrary amount of data. * Constructs a new {@code OutputStreamDataSink} which outputs received data into the provided * {@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 public void consume(byte[] buf, int offset, int length) { mBuf.write(buf, offset, length); public void consume(byte[] buf, int offset, int length) throws IOException { mOut.write(buf, offset, length); } @Override public void consume(ByteBuffer buf) { public void consume(ByteBuffer buf) throws IOException { if (!buf.hasRemaining()) { return; } if (buf.hasArray()) { mBuf.write( mOut.write( buf.array(), buf.arrayOffset() + buf.position(), buf.remaining()); buf.position(buf.limit()); } else { byte[] tmp = new byte[buf.remaining()]; buf.get(tmp); mBuf.write(tmp, 0, tmp.length); byte[] tmp = new byte[Math.min(buf.remaining(), MAX_READ_CHUNK_SIZE)]; while (buf.hasRemaining()) { 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(); } }
tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java 0 → 100644 +36 −0 Original line number 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); } }