package org.commcare.android.mime;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import org.apache.http.entity.mime.MIME;
import org.apache.http.entity.mime.content.AbstractContentBody;
import org.apache.james.mime4j.message.Entity;
import org.javarosa.core.io.StreamsUtil;
import org.javarosa.core.io.StreamsUtil.InputIOException;
import org.javarosa.core.io.StreamsUtil.OutputIOException;
/**
* @author ctsims
*
*/
public class EncryptedFileBody extends AbstractContentBody {
Entity entity;
File file;
Cipher cipher;
String contentType;
public EncryptedFileBody(File file, Cipher cipher, String contentType) {
super(contentType);
this.file = file;
this.cipher = cipher;
this.contentType = contentType;
}
public String getFilename() {
return file.getName();
}
public String getCharset() {
return MIME.DEFAULT_CHARSET.name();
}
public long getContentLength() {
return -1;
}
public String getTransferEncoding() {
return MIME.ENC_BINARY;
}
/*
* (non-Javadoc)
* @see org.apache.james.mime4j.message.SingleBody#writeTo(java.io.OutputStream)
*/
@Override
public void writeTo(OutputStream out) throws IOException {
//The only time this can cause issues is if the body has disappeared since construction. Don't worry about that, since
//it'll get caught when we initialize.
CipherInputStream cis = new CipherInputStream(new FileInputStream(file), cipher);
try {
StreamsUtil.writeFromInputToOutputSpecific(cis, out);
} catch(InputIOException iioe) {
//Here we want to retain the fundamental problem of the _input_ being responsible for the issue
//so we can differentiate between bad reads and bad network
throw iioe;
} catch(OutputIOException oe) {
//We want the original exception here.
throw oe.getWrapped();
}
cis.close();
}
}