Merge "More general OutputStreamDataSink."

This commit is contained in:
Alex Klyubin 2016-06-13 19:49:01 +00:00 committed by Gerrit Code Review
commit dca955a9bd
4 changed files with 125 additions and 68 deletions

View file

@ -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;
@ -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;
@ -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();
}
return mBuf;
if (mDataSink == null) {
mDataSink = DataSinks.asDataSink(mDataSinkBuf);
}
return mDataSink;
}
}
@ -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];
}
}
}

View file

@ -1,62 +0,0 @@
/*
* 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.internal.util;
import com.android.apksigner.core.util.DataSink;
import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
/**
* Data sink which stores all input data into an internal {@link ByteArrayOutputStream}, thus
* accepting an arbitrary amount of data.
*/
public class ByteArrayOutputStreamSink implements DataSink {
private final ByteArrayOutputStream mBuf = new ByteArrayOutputStream();
@Override
public void consume(byte[] buf, int offset, int length) {
mBuf.write(buf, offset, length);
}
@Override
public void consume(ByteBuffer buf) {
if (!buf.hasRemaining()) {
return;
}
if (buf.hasArray()) {
mBuf.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);
}
}
/**
* Returns the data received so far.
*/
public byte[] getData() {
return mBuf.toByteArray();
}
}

View file

@ -0,0 +1,78 @@
/*
* 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.internal.util;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import com.android.apksigner.core.util.DataSink;
/**
* {@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;
/**
* Constructs a new {@code OutputStreamDataSink} which outputs received data into the provided
* {@link OutputStream}.
*/
public OutputStreamDataSink(OutputStream out) {
if (out == null) {
throw new NullPointerException("out == null");
}
mOut = out;
}
/**
* 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) throws IOException {
mOut.write(buf, offset, length);
}
@Override
public void consume(ByteBuffer buf) throws IOException {
if (!buf.hasRemaining()) {
return;
}
if (buf.hasArray()) {
mOut.write(
buf.array(),
buf.arrayOffset() + buf.position(),
buf.remaining());
buf.position(buf.limit());
} else {
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);
}
}
}
}

View file

@ -0,0 +1,36 @@
/*
* 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);
}
}