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;
private final Object mLock = new Object();
private boolean mDone;
- private ByteArrayOutputStreamSink mBuf;
+ private DataSink mDataSink;
+ private ByteArrayOutputStream mDataSinkBuf;
private GetJarEntryDataRequest(String entryName) {
mEntryName = entryName;
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;
}
}
if (!mDone) {
throw new IllegalStateException("Not yet done");
}
- return (mBuf != null) ? mBuf.getData() : new byte[0];
+ return (mDataSinkBuf != null) ? mDataSinkBuf.toByteArray() : new byte[0];
}
}
}
+++ /dev/null
-/*
- * 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();
- }
-}
--- /dev/null
+/*
+ * 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);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * 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);
+ }
+}