com.undefinedlabs.scope.deps.okhttp3.ResponseBody Maven / Gradle / Ivy
Show all versions of scope-deps Show documentation
package com.undefinedlabs.scope.deps.okhttp3;
import com.undefinedlabs.scope.deps.okhttp3.internal.Util;
import com.undefinedlabs.scope.deps.okio.Buffer;
import com.undefinedlabs.scope.deps.okio.BufferedSource;
import java.io.*;
import java.nio.charset.Charset;
import static com.undefinedlabs.scope.deps.okhttp3.internal.Util.UTF_8;
public abstract class ResponseBody implements Closeable {
/** Multiple calls to {@link #charStream()} must return the same instance. */
private Reader reader;
public abstract MediaType contentType();
/**
* Returns the number of bytes in that will returned by {@link #bytes}, or {@link #byteStream}, or
* -1 if unknown.
*/
public abstract long contentLength();
public final InputStream byteStream() {
return source().inputStream();
}
public abstract BufferedSource source();
/**
* Returns the response as a byte array.
*
* This method loads entire response body into memory. If the response body is very large this
* may trigger an {@link OutOfMemoryError}. Prefer to stream the response body if this is a
* possibility for your response.
*/
public final byte[] bytes() throws IOException {
long contentLength = contentLength();
if (contentLength > Integer.MAX_VALUE) {
throw new IOException("Cannot buffer entire body for content length: " + contentLength);
}
BufferedSource source = source();
byte[] bytes;
try {
bytes = source.readByteArray();
} finally {
Util.closeQuietly(source);
}
if (contentLength != -1 && contentLength != bytes.length) {
throw new IOException("Content-Length ("
+ contentLength
+ ") and stream length ("
+ bytes.length
+ ") disagree");
}
return bytes;
}
/**
* Returns the response as a character stream decoded with the charset of the Content-Type header.
* If that header is either absent or lacks a charset, this will attempt to decode the response
* body in accordance to its BOM or
* UTF-8.
*/
public final Reader charStream() {
Reader r = reader;
return r != null ? r : (reader = new BomAwareReader(source(), charset()));
}
/**
* Returns the response as a string decoded with the charset of the Content-Type header. If that
* header is either absent or lacks a charset, this will attempt to decode the response body in
* accordance to its BOM or UTF-8.
* Closes {@link ResponseBody} automatically.
*
*
This method loads entire response body into memory. If the response body is very large this
* may trigger an {@link OutOfMemoryError}. Prefer to stream the response body if this is a
* possibility for your response.
*/
public final String string() throws IOException {
BufferedSource source = source();
try {
Charset charset = Util.bomAwareCharset(source, charset());
return source.readString(charset);
} finally {
Util.closeQuietly(source);
}
}
private Charset charset() {
MediaType contentType = contentType();
return contentType != null ? contentType.charset(UTF_8) : UTF_8;
}
@Override public void close() {
Util.closeQuietly(source());
}
/**
* Returns a new response body that transmits {@code content}. If {@code contentType} is non-null
* and lacks a charset, this will use UTF-8.
*/
public static ResponseBody create(MediaType contentType, String content) {
Charset charset = UTF_8;
if (contentType != null) {
charset = contentType.charset();
if (charset == null) {
charset = UTF_8;
contentType = MediaType.parse(contentType + "; charset=utf-8");
}
}
Buffer buffer = new Buffer().writeString(content, charset);
return create(contentType, buffer.size(), buffer);
}
/** Returns a new response body that transmits {@code content}. */
public static ResponseBody create(final MediaType contentType, byte[] content) {
Buffer buffer = new Buffer().write(content);
return create(contentType, content.length, buffer);
}
/** Returns a new response body that transmits {@code content}. */
public static ResponseBody create(final MediaType contentType,
final long contentLength, final BufferedSource content) {
if (content == null) throw new NullPointerException("source == null");
return new ResponseBody() {
@Override public MediaType contentType() {
return contentType;
}
@Override public long contentLength() {
return contentLength;
}
@Override public BufferedSource source() {
return content;
}
};
}
static final class BomAwareReader extends Reader {
private final BufferedSource source;
private final Charset charset;
private boolean closed;
private Reader delegate;
BomAwareReader(BufferedSource source, Charset charset) {
this.source = source;
this.charset = charset;
}
@Override public int read(char[] cbuf, int off, int len) throws IOException {
if (closed) throw new IOException("Stream closed");
Reader delegate = this.delegate;
if (delegate == null) {
Charset charset = Util.bomAwareCharset(source, this.charset);
delegate = this.delegate = new InputStreamReader(source.inputStream(), charset);
}
return delegate.read(cbuf, off, len);
}
@Override public void close() throws IOException {
closed = true;
if (delegate != null) {
delegate.close();
} else {
source.close();
}
}
}
}