MultipartBody.java
/*
* Decompiled with CFR 0_132.
*
* Could not load the following classes:
* android.text.TextUtils
*/
package org.xutils.http.body;
import android.text.TextUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.xutils.common.Callback;
import org.xutils.common.util.IOUtil;
import org.xutils.common.util.KeyValue;
import org.xutils.http.ProgressHandler;
import org.xutils.http.body.BodyItemWrapper;
import org.xutils.http.body.FileBody;
import org.xutils.http.body.InputStreamBody;
import org.xutils.http.body.ProgressBody;
public class MultipartBody
implements ProgressBody {
private static byte[] BOUNDARY_PREFIX_BYTES = "--------7da3d81520810".getBytes();
private static byte[] END_BYTES = "\r\n".getBytes();
private static byte[] TWO_DASHES_BYTES = "--".getBytes();
private byte[] boundaryPostfixBytes;
private String contentType;
private String charset = "UTF-8";
private List<KeyValue> multipartParams;
private long total = 0L;
private long current = 0L;
private ProgressHandler callBackHandler;
public MultipartBody(List<KeyValue> multipartParams, String charset) {
if (!TextUtils.isEmpty((CharSequence)charset)) {
this.charset = charset;
}
this.multipartParams = multipartParams;
this.generateContentType();
CounterOutputStream counter = new CounterOutputStream();
try {
this.writeTo(counter);
this.total = counter.total.get();
}
catch (IOException e) {
this.total = -1L;
}
}
@Override
public void setProgressHandler(ProgressHandler progressHandler) {
this.callBackHandler = progressHandler;
}
private void generateContentType() {
String boundaryPostfix = Double.toHexString(Math.random() * 65535.0);
this.boundaryPostfixBytes = boundaryPostfix.getBytes();
this.contentType = "multipart/form-data; boundary=" + new String(BOUNDARY_PREFIX_BYTES) + boundaryPostfix;
}
@Override
public long getContentLength() {
return this.total;
}
@Override
public void setContentType(String subType) {
int index = this.contentType.indexOf(";");
this.contentType = "multipart/" + subType + this.contentType.substring(index);
}
@Override
public String getContentType() {
return this.contentType;
}
@Override
public void writeTo(OutputStream out) throws IOException {
if (this.callBackHandler != null && !this.callBackHandler.updateProgress(this.total, this.current, true)) {
throw new Callback.CancelledException("upload stopped!");
}
for (KeyValue kv : this.multipartParams) {
String name = kv.key;
Object value = kv.value;
if (TextUtils.isEmpty((CharSequence)name) || value == null) continue;
this.writeEntry(out, name, value);
}
this.writeLine(out, TWO_DASHES_BYTES, BOUNDARY_PREFIX_BYTES, this.boundaryPostfixBytes, TWO_DASHES_BYTES);
out.flush();
if (this.callBackHandler != null) {
this.callBackHandler.updateProgress(this.total, this.total, true);
}
}
private void writeEntry(OutputStream out, String name, Object value) throws IOException {
this.writeLine(out, TWO_DASHES_BYTES, BOUNDARY_PREFIX_BYTES, this.boundaryPostfixBytes);
String fileName = "";
String contentType = null;
if (value instanceof BodyItemWrapper) {
BodyItemWrapper wrapper = (BodyItemWrapper)value;
value = wrapper.getValue();
fileName = wrapper.getFileName();
contentType = wrapper.getContentType();
}
if (value instanceof File) {
File file = (File)value;
if (TextUtils.isEmpty((CharSequence)fileName)) {
fileName = file.getName();
}
if (TextUtils.isEmpty(contentType)) {
contentType = FileBody.getFileContentType(file);
}
this.writeLine(out, new byte[][]{MultipartBody.buildContentDisposition(name, fileName, this.charset)});
this.writeLine(out, new byte[][]{MultipartBody.buildContentType(value, contentType, this.charset)});
this.writeLine(out, new byte[0][]);
this.writeFile(out, file);
this.writeLine(out, new byte[0][]);
} else {
this.writeLine(out, new byte[][]{MultipartBody.buildContentDisposition(name, fileName, this.charset)});
this.writeLine(out, new byte[][]{MultipartBody.buildContentType(value, contentType, this.charset)});
this.writeLine(out, new byte[0][]);
if (value instanceof InputStream) {
this.writeStreamAndCloseIn(out, (InputStream)value);
this.writeLine(out, new byte[0][]);
} else {
byte[] content = value instanceof byte[] ? (byte[])value : String.valueOf(value).getBytes(this.charset);
this.writeLine(out, new byte[][]{content});
this.current += (long)content.length;
if (this.callBackHandler != null && !this.callBackHandler.updateProgress(this.total, this.current, false)) {
throw new Callback.CancelledException("upload stopped!");
}
}
}
}
private /* varargs */ void writeLine(OutputStream out, byte[] ... bs) throws IOException {
if (bs != null) {
for (byte[] b : bs) {
out.write(b);
}
}
out.write(END_BYTES);
}
private void writeFile(OutputStream out, File file) throws IOException {
if (out instanceof CounterOutputStream) {
((CounterOutputStream)out).addFile(file);
} else {
this.writeStreamAndCloseIn(out, new FileInputStream(file));
}
}
/*
* WARNING - Removed try catching itself - possible behaviour change.
*/
private void writeStreamAndCloseIn(OutputStream out, InputStream in) throws IOException {
if (out instanceof CounterOutputStream) {
((CounterOutputStream)out).addStream(in);
} else {
try {
int len;
byte[] buf = new byte[1024];
while ((len = in.read(buf)) >= 0) {
out.write(buf, 0, len);
this.current += (long)len;
if (this.callBackHandler == null || this.callBackHandler.updateProgress(this.total, this.current, false)) continue;
throw new Callback.CancelledException("upload stopped!");
}
}
finally {
IOUtil.closeQuietly(in);
}
}
}
private static byte[] buildContentDisposition(String name, String fileName, String charset) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder("Content-Disposition: form-data");
result.append("; name=\"").append(name.replace("\"", "\\\"")).append("\"");
if (!TextUtils.isEmpty((CharSequence)fileName)) {
result.append("; filename=\"").append(fileName.replace("\"", "\\\"")).append("\"");
}
return result.toString().getBytes(charset);
}
private static byte[] buildContentType(Object value, String contentType, String charset) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder("Content-Type: ");
contentType = TextUtils.isEmpty((CharSequence)contentType) ? (value instanceof String ? "text/plain; charset=" + charset : "application/octet-stream") : contentType.replaceFirst("\\/jpg$", "/jpeg");
result.append(contentType);
return result.toString().getBytes(charset);
}
private class CounterOutputStream
extends OutputStream {
final AtomicLong total = new AtomicLong(0L);
public void addFile(File file) {
if (this.total.get() == -1L) {
return;
}
this.total.addAndGet(file.length());
}
public void addStream(InputStream inputStream) {
if (this.total.get() == -1L) {
return;
}
long length = InputStreamBody.getInputStreamLength(inputStream);
if (length > 0L) {
this.total.addAndGet(length);
} else {
this.total.set(-1L);
}
}
@Override
public void write(int oneByte) throws IOException {
if (this.total.get() == -1L) {
return;
}
this.total.incrementAndGet();
}
@Override
public void write(byte[] buffer) throws IOException {
if (this.total.get() == -1L) {
return;
}
this.total.addAndGet(buffer.length);
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
if (this.total.get() == -1L) {
return;
}
this.total.addAndGet(count);
}
}
}