Merge commit 'a67f19deb0794784d1b841bc1900328103af03c5' * commit 'a67f19deb0794784d1b841bc1900328103af03c5': Adds a few utilities to ProtoBufUtil, integrating over from mainlinepull/91/head
commit
9ed5ba9170
2 changed files with 151 additions and 12 deletions
@ -0,0 +1,91 @@ |
||||
// Copyright 2008 Google Inc. All Rights Reserved.
|
||||
|
||||
package com.google.common.io.protocol; |
||||
|
||||
import java.io.*; |
||||
|
||||
/** |
||||
* An input stream backed by another input stream, where reading from the |
||||
* underlying input stream is limited to a fixed number of bytes. Also does |
||||
* some buffering. |
||||
* |
||||
*/ |
||||
public class BoundInputStream extends InputStream { |
||||
|
||||
/** Buffer size */ |
||||
static final int BUF_SIZE = 4096; |
||||
|
||||
/** Number of bytes that may still be read from the underlying stream */ |
||||
private int remaining; |
||||
|
||||
/** Small buffer to avoid making OS calls for each byte read. */ |
||||
private byte[] buf; |
||||
|
||||
/** Current position in the buffer */ |
||||
private int bufPos; |
||||
|
||||
/** Filled size of the buffer */ |
||||
private int bufSize; |
||||
|
||||
/** Underlying stream to read from */ |
||||
private InputStream base; |
||||
|
||||
public BoundInputStream(InputStream base, int len) { |
||||
this.base = base; |
||||
this.remaining = len; |
||||
|
||||
buf = new byte[Math.min(len, BUF_SIZE)]; |
||||
} |
||||
|
||||
/** |
||||
* Make sure there is at least one byte in the buffer. If not possible, |
||||
* return false. |
||||
*/ |
||||
private boolean checkBuf() throws IOException { |
||||
if (remaining <= 0) { |
||||
return false; |
||||
} |
||||
|
||||
if (bufPos >= bufSize) { |
||||
bufSize = base.read(buf, 0, Math.min(remaining, buf.length)); |
||||
if (bufSize <= 0) { |
||||
remaining = 0; |
||||
return false; |
||||
} |
||||
bufPos = 0; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
public int available() { |
||||
return bufSize - bufPos; |
||||
} |
||||
|
||||
public int read() throws IOException { |
||||
if (!checkBuf()) { |
||||
return -1; |
||||
} |
||||
remaining--; |
||||
return buf[bufPos++] & 255; |
||||
} |
||||
|
||||
public int read(byte[] data, int start, int count) throws IOException { |
||||
if (!checkBuf()) { |
||||
return -1; |
||||
} |
||||
count = Math.min(count, bufSize - bufPos); |
||||
System.arraycopy(buf, bufPos, data, start, count); |
||||
bufPos += count; |
||||
remaining -= count; |
||||
return count; |
||||
} |
||||
|
||||
/** |
||||
* How many bytes are remaining, based on the length provided to the |
||||
* constructor. The underlying stream may terminate earlier. Provided mainly |
||||
* for testing purposes. |
||||
*/ |
||||
public int getRemaining() { |
||||
return remaining; |
||||
} |
||||
} |
Loading…
Reference in new issue