package org.apache.harmony.luni.internal.net.www.protocol.http;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
/**
* An HTTP body with alternating chunk sizes and chunk bodies. Chunks are
* buffered until {@code maxChunkLength} bytes are ready, at which point the
* chunk is written and the buffer is cleared.
*/
final class ChunkedOutputStream extends AbstractHttpOutputStream {
private static final byte[] CRLF = { '\r', '\n' };
private static final byte[] HEX_DIGITS = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
private static final byte[] FINAL_CHUNK = new byte[] { '0', '\r', '\n', '\r', '\n' };
/** Scratch space for up to 8 hex digits, and then a constant CRLF */
private final byte[] hex = { 0, 0, 0, 0, 0, 0, 0, 0, '\r', '\n' };
private final OutputStream socketOut;
private final int maxChunkLength;
private final ByteArrayOutputStream bufferedChunk;
public ChunkedOutputStream(OutputStream socketOut, int maxChunkLength) {
this.socketOut = socketOut;
this.maxChunkLength = Math.max(1, dataLength(maxChunkLength));
this.bufferedChunk = new ByteArrayOutputStream(maxChunkLength);
}
/**
* Returns the amount of data that can be transmitted in a chunk whose total
* length (data+headers) is {@code dataPlusHeaderLength}. This is presumably
* useful to match sizes with wire-protocol packets.
*/
private int dataLength(int dataPlusHeaderLength) {
int headerLength = 4; // "\r\n" after the size plus another "\r\n" after the data
for (int i = dataPlusHeaderLength - headerLength; i > 0; i >>= 4) {
headerLength++;
}
return dataPlusHeaderLength - headerLength;
}
@Override public synchronized void write(byte[] buffer, int offset, int count)
throws IOException {
checkNotClosed();
checkBounds(buffer, offset, count);
while (count > 0) {
int numBytesWritten;
if (bufferedChunk.size() > 0 || count < maxChunkLength) {
// fill the buffered chunk and then maybe write that to the stream
numBytesWritten = Math.min(count, maxChunkLength - bufferedChunk.size());
// TODO: skip unnecessary copies from buffer->bufferedChunk?
bufferedChunk.write(buffer, offset, numBytesWritten);
if (bufferedChunk.size() == maxChunkLength) {
writeBufferedChunkToSocket();
}
} else {
// write a single chunk of size maxChunkLength to the stream
numBytesWritten = maxChunkLength;
writeHex(numBytesWritten);
socketOut.write(buffer, offset, numBytesWritten);
socketOut.write(CRLF);
}
offset += numBytesWritten;
count -= numBytesWritten;
}
}
/**
* Equivalent to, but cheaper than writing Integer.toHexString().getBytes()
* followed by CRLF.
*/
private void writeHex(int i) throws IOException {
int cursor = 8;
do {
hex[--cursor] = HEX_DIGITS[i & 0xf];
} while ((i >>>= 4) != 0);
socketOut.write(hex, cursor, hex.length - cursor);
}
@Override public synchronized void flush() throws IOException {
if (closed) {
return; // don't throw; this stream might have been closed on the caller's behalf
}
writeBufferedChunkToSocket();
socketOut.flush();
}
@Override public synchronized void close() throws IOException {
if (closed) {
return;
}
closed = true;
writeBufferedChunkToSocket();
socketOut.write(FINAL_CHUNK);
}
private void writeBufferedChunkToSocket() throws IOException {
int size = bufferedChunk.size();
if (size <= 0) {
return;
}
writeHex(size);
bufferedChunk.writeTo(socketOut);
bufferedChunk.reset();
socketOut.write(CRLF);
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
ChunkedOutputStream.rar_Bodies_chunk _chunk http_http chunk_htt
共1个文件
java:1个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 143 浏览量
2022-09-20
20:58:10
上传
评论
收藏 1KB RAR 举报
温馨提示
An HTTP body with alternating chunk sizes and chunk bodies.
资源推荐
资源详情
资源评论
收起资源包目录
ChunkedOutputStream.rar (1个子文件)
ChunkedOutputStream.java 4KB
共 1 条
- 1
资源评论
邓凌佳
- 粉丝: 65
- 资源: 1万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功