package com.android.volley.toolbox.multipart;
import com.android.volley.Response.ProgressListener;
import org.apache.http.protocol.HTTP;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import static com.android.volley.misc.MultipartUtils.BINARY;
import static com.android.volley.misc.MultipartUtils.COLON_SPACE;
import static com.android.volley.misc.MultipartUtils.CRLF_BYTES;
import static com.android.volley.misc.MultipartUtils.FILENAME;
import static com.android.volley.misc.MultipartUtils.FORM_DATA;
import static com.android.volley.misc.MultipartUtils.HEADER_CONTENT_DISPOSITION;
import static com.android.volley.misc.MultipartUtils.HEADER_CONTENT_TRANSFER_ENCODING;
import static com.android.volley.misc.MultipartUtils.HEADER_CONTENT_TYPE;
import static com.android.volley.misc.MultipartUtils.SEMICOLON_SPACE;
/**
* @author <a href="mailto:vit at cleverua.com">Vitaliy Khudenko</a>
*/
public final class FilePart extends BasePart {
private final File file;
private ProgressListener mProgressListener;
/**
* @param name String - name of parameter (may not be <code>null</code>).
* @param file File (may not be <code>null</code>).
* @param filename String. If <code>null</code> is passed,
* then <code>file.getName()</code> is used.
* @param contentType String. If <code>null</code> is passed,
* then default "application/octet-stream" is used.
*
* @throws IllegalArgumentException if either <code>file</code>
* or <code>name</code> is <code>null</code>.
*/
public FilePart(String name, File file, String filename, String contentType) {
if (file == null) {
throw new IllegalArgumentException("File may not be null"); //$NON-NLS-1$
}
if (name == null) {
throw new IllegalArgumentException("Name may not be null"); //$NON-NLS-1$
}
this.file = file;
final String partName = UrlEncodingHelper.encode(name, HTTP.DEFAULT_PROTOCOL_CHARSET);
final String partFilename = UrlEncodingHelper.encode(
(filename == null) ? file.getName() : filename,
HTTP.DEFAULT_PROTOCOL_CHARSET
);
final String partContentType = (contentType == null) ? HTTP.DEFAULT_CONTENT_TYPE : contentType;
headersProvider = new IHeadersProvider() {
public String getContentDisposition() {
return String.format(HEADER_CONTENT_DISPOSITION + COLON_SPACE + FORM_DATA + SEMICOLON_SPACE + FILENAME, partName, partFilename);
}
public String getContentType() {
return HEADER_CONTENT_TYPE + COLON_SPACE + partContentType;
}
public String getContentTransferEncoding() {
return HEADER_CONTENT_TRANSFER_ENCODING + COLON_SPACE + BINARY;
}
};
}
public void setProgressListener(ProgressListener listner){
mProgressListener = listner;
}
public long getContentLength(Boundary boundary) {
return getHeader(boundary).length + file.length() + CRLF_BYTES.length;
}
@Override
public void writeTo(OutputStream out, Boundary boundary) throws IOException {
out.write(getHeader(boundary));
if (mProgressListener != null) {
InputStream in = new FileInputStream(file);
try {
int transferredBytes = 0;
int totalSize = (int) file.length();
byte[] tmp = new byte[4096];
int l;
while ((l = in.read(tmp)) != -1) {
out.write(tmp, 0, l);
transferredBytes += l;
mProgressListener.onProgress(transferredBytes, totalSize);
}
} finally {
in.close();
}
} else {
InputStream in = new FileInputStream(file);
try {
byte[] tmp = new byte[4096];
int l;
while ((l = in.read(tmp)) != -1) {
out.write(tmp, 0, l);
}
} finally {
in.close();
}
}
out.write(CRLF_BYTES);
}
}