Loading tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java +11 −6 Original line number Original line 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.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; Loading Loading @@ -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; Loading @@ -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; } } } } Loading Loading @@ -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]; } } } } } } 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 Original line Diff line number Diff line Loading @@ -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(); } } } } tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java 0 → 100644 +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); } } Loading
tools/apksigner/core/src/com/android/apksigner/core/DefaultApkSignerEngine.java +11 −6 Original line number Original line 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.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; Loading Loading @@ -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; Loading @@ -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; } } } } Loading Loading @@ -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]; } } } } } } 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 Original line Diff line number Diff line Loading @@ -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(); } } } }
tools/apksigner/core/src/com/android/apksigner/core/util/DataSinks.java 0 → 100644 +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); } }