Commit 3cfb04b6 authored by Torsten Grote's avatar Torsten Grote

Establish some rules for handling InputStreams

* Methods shouldn't place any special requirements on the streams
  passed into them
* This implies that if a stream's going to be marked and reset,
  that should all happen within one method
* This also implies that if a method needs to mark and reset a stream,
  it should wrap the stream in a BufferedInputStream before doing so,
  rather than requiring a markable stream to be passed in
parent e85fbfb9
......@@ -16,6 +16,7 @@ import org.briarproject.briar.api.messaging.Attachment;
import org.briarproject.briar.api.messaging.AttachmentHeader;
import org.briarproject.briar.api.messaging.MessagingManager;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
......@@ -92,14 +93,13 @@ class AttachmentController {
/**
* Creates {@link AttachmentItem}s from the passed headers and Attachments.
* Note: This marks the {@link Attachment}'s {@link InputStream}
* and closes the streams.
*
* Note: This closes the {@link Attachment}'s {@link InputStream}.
*/
List<AttachmentItem> getAttachmentItems(
List<Pair<AttachmentHeader, Attachment>> attachments) {
List<AttachmentItem> items = new ArrayList<>(attachments.size());
for (Pair<AttachmentHeader, Attachment> a : attachments) {
a.getSecond().getStream().mark(Integer.MAX_VALUE);
AttachmentItem item =
getAttachmentItem(a.getFirst(), a.getSecond());
items.add(item);
......@@ -109,16 +109,14 @@ class AttachmentController {
/**
* Creates an {@link AttachmentItem} from the {@link Attachment}'s
* {@link InputStream}.
* Note: Requires a resettable InputStream
* with the beginning already marked.
* The stream will be closed when this method returns.
* {@link InputStream} which will be closed when this method returns.
*/
AttachmentItem getAttachmentItem(AttachmentHeader h, Attachment a) {
MessageId messageId = h.getMessageId();
Size size = new Size();
InputStream is = a.getStream();
InputStream is = new BufferedInputStream(a.getStream());
is.mark(Integer.MAX_VALUE);
try {
// use exif to get size
if (h.getContentType().equals("image/jpeg")) {
......@@ -190,13 +188,6 @@ class AttachmentController {
options.outMimeType);
}
static String getContentTypeFromBitmap(InputStream is) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
return options.outMimeType;
}
private Size getThumbnailSize(int width, int height, String mimeType) {
float widthPercentage = maxWidth / (float) width;
float heightPercentage = maxHeight / (float) height;
......
......@@ -31,7 +31,6 @@ import org.briarproject.briar.api.messaging.PrivateMessage;
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
......@@ -48,7 +47,6 @@ import static org.briarproject.bramble.util.IoUtils.tryToClose;
import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now;
import static org.briarproject.briar.android.conversation.AttachmentController.getContentTypeFromBitmap;
import static org.briarproject.briar.android.util.UiUtils.observeForeverOnce;
@NotNullByDefault
......@@ -140,7 +138,6 @@ public class ConversationViewModel extends AndroidViewModel {
observeForeverOnce(messagingGroupId, groupId -> {
if (groupId == null) return;
// calls through to creating and storing the message
// (wouldn't Kotlin's co-routines be nice here?)
storeAttachments(groupId, text, uris, timestamp);
});
}
......@@ -185,12 +182,14 @@ public class ConversationViewModel extends AndroidViewModel {
getApplication().getContentResolver();
is = contentResolver.openInputStream(uri);
if (is == null) throw new IOException();
is = new BufferedInputStream(is); // adds support for reset()
is.mark(Integer.MAX_VALUE);
String contentType = contentResolver.getType(uri);
if (contentType == null) contentType = getContentTypeFromBitmap(is);
if (contentType == null) throw new IOException("null content type");
AttachmentHeader h = messagingManager
.addLocalAttachment(groupId, timestamp, contentType, is);
is.close();
// re-open stream to get AttachmentItem
is = contentResolver.openInputStream(uri);
if (is == null) throw new IOException();
AttachmentItem item = attachmentController
.getAttachmentItem(h, new Attachment(is));
return new Pair<>(h, item);
......
......@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.conversation.ConversationManager.ConversationClient;
import java.io.IOException;
import java.io.InputStream;
@NotNullByDefault
......@@ -37,7 +38,7 @@ public interface MessagingManager extends ConversationClient {
* Stores a local attachment message.
*/
AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp,
String contentType, InputStream is) throws DbException;
String contentType, InputStream is) throws DbException, IOException;
/**
* Returns the ID of the contact with the given private conversation.
......
......@@ -33,6 +33,7 @@ import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
import org.briarproject.briar.client.ConversationClientImpl;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
......@@ -154,8 +155,9 @@ class MessagingManagerImpl extends ConversationClientImpl
@Override
public AttachmentHeader addLocalAttachment(GroupId groupId, long timestamp,
String contentType, InputStream is) {
String contentType, InputStream is) throws IOException {
// TODO add real implementation
if (is.available() == 0) throw new IOException();
byte[] b = new byte[MessageId.LENGTH];
new Random().nextBytes(b);
return new AttachmentHeader(new MessageId(b), "image/png");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment