mirror of
https://github.com/signalapp/Signal-Android.git
synced 2025-12-22 12:08:34 +00:00
Export backupV2 using actual desired file format.
This commit is contained in:
committed by
Cody Henthorne
parent
fb69fc5af2
commit
befa396e82
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.util
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import okio.IOException
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun ContentResolver.getLength(uri: Uri): Long? {
|
||||
return this.query(uri, arrayOf(OpenableColumns.SIZE), null, null, null)?.use { cursor ->
|
||||
if (cursor.moveToFirst()) {
|
||||
cursor.requireLongOrNull(OpenableColumns.SIZE)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} ?: openInputStream(uri)?.use { it.readLength() }
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.util
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import kotlin.jvm.Throws
|
||||
|
||||
/**
|
||||
* Reads the entire stream into a [ByteArray].
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
fun InputStream.readFully(): ByteArray {
|
||||
return StreamUtil.readFully(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills reads data from the stream into the [buffer] until it is full.
|
||||
* Throws an [IOException] if the stream doesn't have enough data to fill the buffer.
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
fun InputStream.readFully(buffer: ByteArray) {
|
||||
return StreamUtil.readFully(this, buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the specified number of bytes from the stream and returns it as a [ByteArray].
|
||||
* Throws an [IOException] if the stream doesn't have that many bytes.
|
||||
*/
|
||||
@Throws(IOException::class)
|
||||
fun InputStream.readNBytesOrThrow(length: Int): ByteArray {
|
||||
val buffer: ByteArray = ByteArray(length)
|
||||
this.readFully(buffer)
|
||||
return buffer
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
package org.signal.core.util;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Utility methods for input and output streams.
|
||||
*/
|
||||
public final class StreamUtil {
|
||||
|
||||
private static final String TAG = Log.tag(StreamUtil.class);
|
||||
|
||||
private StreamUtil() {}
|
||||
|
||||
public static void close(@Nullable Closeable closeable) {
|
||||
if (closeable == null) return;
|
||||
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static long getStreamLength(InputStream in) throws IOException {
|
||||
byte[] buffer = new byte[4096];
|
||||
int totalSize = 0;
|
||||
|
||||
int read;
|
||||
|
||||
while ((read = in.read(buffer)) != -1) {
|
||||
totalSize += read;
|
||||
}
|
||||
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
public static void readFully(InputStream in, byte[] buffer) throws IOException {
|
||||
readFully(in, buffer, buffer.length);
|
||||
}
|
||||
|
||||
public static void readFully(InputStream in, byte[] buffer, int len) throws IOException {
|
||||
int offset = 0;
|
||||
|
||||
for (;;) {
|
||||
int read = in.read(buffer, offset, len - offset);
|
||||
if (read == -1) throw new EOFException("Stream ended early, offset: " + offset + " len: " + len);
|
||||
|
||||
if (read + offset < len) offset += read;
|
||||
else return;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] readFully(InputStream in) throws IOException {
|
||||
return readFully(in, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public static byte[] readFully(InputStream in, int maxBytes) throws IOException {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[4096];
|
||||
int totalRead = 0;
|
||||
int read;
|
||||
|
||||
while ((read = in.read(buffer)) != -1) {
|
||||
bout.write(buffer, 0, read);
|
||||
totalRead += read;
|
||||
if (totalRead > maxBytes) {
|
||||
throw new IOException("Stream size limit exceeded");
|
||||
}
|
||||
}
|
||||
|
||||
in.close();
|
||||
|
||||
return bout.toByteArray();
|
||||
}
|
||||
|
||||
public static String readFullyAsString(InputStream in) throws IOException {
|
||||
return new String(readFully(in));
|
||||
}
|
||||
|
||||
public static long copy(InputStream in, OutputStream out) throws IOException {
|
||||
byte[] buffer = new byte[64 * 1024];
|
||||
int read;
|
||||
long total = 0;
|
||||
|
||||
while ((read = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, read);
|
||||
total += read;
|
||||
}
|
||||
|
||||
in.close();
|
||||
out.close();
|
||||
|
||||
return total;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.signal.core.util
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import kotlin.random.Random
|
||||
|
||||
class InputStreamExtensionTests {
|
||||
|
||||
@Test
|
||||
fun `when I call readLength, it returns the correct length`() {
|
||||
for (i in 1..10) {
|
||||
val bytes = ByteArray(Random.nextInt(from = 512, until = 8092))
|
||||
val length = bytes.inputStream().readLength()
|
||||
assertEquals(bytes.size.toLong(), length)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user