下面列出了java.nio.ByteBuffer#hasRemaining ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void consume(ByteBuffer buf) throws IOException {
if (!buf.hasRemaining()) {
return;
}
if (buf.hasArray()) {
consume(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
buf.position(buf.limit());
return;
}
ensureAvailable(buf.remaining());
byte[] tmp = new byte[Math.min(buf.remaining(), MAX_READ_CHUNK_SIZE)];
while (buf.hasRemaining()) {
int chunkSize = Math.min(buf.remaining(), tmp.length);
buf.get(tmp, 0, chunkSize);
System.arraycopy(tmp, 0, mArray, mSize, chunkSize);
mSize += chunkSize;
}
}
SSLEngineResult wrap(ByteBuffer plainData) throws SSLException
{
_buffers.prepareForWrap(plainData);
SSLEngineResult result = doWrap();
emitWrappedData(result);
switch (result.getStatus()) {
case BUFFER_UNDERFLOW:
throw new RuntimeException("BUFFER_UNDERFLOW while wrapping!");
case BUFFER_OVERFLOW:
_buffers.grow(BufferType.OUT_CIPHER);
if (plainData != null && plainData.hasRemaining()) {
plainData.position(result.bytesConsumed());
ByteBuffer remainingData = BufferUtils.slice(plainData);
wrap(remainingData);
}
break;
case OK:
break;
case CLOSED:
_sessionClosedListener.onSessionClosed();
break;
}
return result;
}
private SHKeyShareSpec(ByteBuffer buffer) throws IOException {
// struct {
// KeyShareEntry server_share;
// } KeyShareServerHello;
if (buffer.remaining() < 5) { // 5: minimal server_share
throw new SSLProtocolException(
"Invalid key_share extension: " +
"insufficient data (length=" + buffer.remaining() + ")");
}
int namedGroupId = Record.getInt16(buffer);
byte[] keyExchange = Record.getBytes16(buffer);
if (buffer.hasRemaining()) {
throw new SSLProtocolException(
"Invalid key_share extension: unknown extra data");
}
this.serverShare = new KeyShareEntry(namedGroupId, keyExchange);
}
private int decodePrival ( final ByteBuf msg )
{
final ByteBuffer privalBuffer = ByteBuffer.wrap ( new byte[3] );
byte b;
do
{
b = msg.readByte ();
if ( b == PRI_END )
{
break;
}
if ( !privalBuffer.hasRemaining () )
{
throw new CodecException ( "PRI value must be <=3 bytes" );
}
privalBuffer.put ( b );
} while ( true );
privalBuffer.flip ();
final int prival = Integer.parseInt ( StandardCharsets.US_ASCII.decode ( privalBuffer ).toString () );
return prival;
}
public static TupleExpression deserialize(byte[] bytes, IFilterCodeSystem<?> cs) {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
TupleExpression rootTuple = null;
Stack<TupleExpression> parentStack = new Stack<>();
while (buffer.hasRemaining()) {
int opVal = BytesUtil.readVInt(buffer);
if (opVal < 0) {
parentStack.pop();
continue;
}
DataType dataType = DataType.serializer.deserialize(buffer);
// deserialize expression
TupleExpression tuple = createTupleExpression(dataType, opVal);
tuple.deserialize(cs, buffer);
if (rootTuple == null) {
// push root to stack
rootTuple = tuple;
parentStack.push(tuple);
BytesUtil.readVInt(buffer);
continue;
}
// add expression to parent
TupleExpression parentExpression = parentStack.peek();
if (parentExpression != null) {
parentExpression.addChild(tuple);
}
// push expression to stack or not based on having children or not
int hasChild = BytesUtil.readVInt(buffer);
if (hasChild == 1) {
parentStack.push(tuple);
}
}
return rootTuple;
}
private void loop() {
final String fileName = String.format("%s%d", FILE_NAME_PREFIX, id);
try {
for (int i = 0; i < iters; i += 1) {
final int writeSize = getWriteSize();
// This will allocate a HeapByteBuffer. It should not
// be a direct buffer, otherwise the write() method on
// the channel below will not create a temporary
// direct buffer for the write.
final ByteBuffer buffer = ByteBuffer.allocate(writeSize);
// Put some random data on it.
while (buffer.hasRemaining()) {
buffer.put((byte) random.nextInt());
}
buffer.rewind();
final Path file = Paths.get(fileName);
try (FileChannel outChannel = FileChannel.open(file, CREATE, TRUNCATE_EXISTING, WRITE)) {
// The write() method will create a temporary
// direct buffer for the write and attempt to cache
// it. It's important that buffer is not a
// direct buffer, otherwise the temporary buffer
// will not be created.
long res = outChannel.write(buffer);
}
if ((i + 1) % VERBOSE_PERIOD == 0) {
System.out.printf(
" Worker %3d | %8d Iters | Small %8d Large %8d | Direct %4d / %7dK\n",
id, i + 1, smallBufferCount, largeBufferCount,
directPool.getCount(), directPool.getTotalCapacity() / 1024);
}
}
} catch (IOException e) {
throw new Error("I/O error", e);
}
}
/**
* Encrypt provided buffer. Encrypted data returned by getOutNetBuffer().
*
* @param src data to encrypt
* @throws SSLException on errors
*/
void encrypt(ByteBuffer src) throws SSLException {
if (!handshakeComplete)
throw new IllegalStateException();
if (!src.hasRemaining()) {
if (outNetBuffer == null)
outNetBuffer = IoBuffer.allocate(0);
return;
}
createOutNetBuffer(src.remaining());
// Loop until there is no more data in src
while (src.hasRemaining()) {
SSLEngineResult result = sslEngine.wrap(src, outNetBuffer.buf());
if (result.getStatus() == Status.OK) {
if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK)
doTasks();
} else if (result.getStatus() == Status.BUFFER_OVERFLOW) {
outNetBuffer = IoBuffer.reallocate(outNetBuffer, outNetBuffer.capacity() << 1);
outNetBuffer.limit(outNetBuffer.capacity());
} else
throw new SSLException("SSLEngine error during encrypt: " + result.getStatus() + " src: " + src + "outNetBuffer: " + outNetBuffer);
}
outNetBuffer.flip();
}
/**
* Returns the checksum of all but the first 12 bytes of {@code dex}.
*/
public int computeChecksum() throws IOException {
Adler32 adler32 = new Adler32();
byte[] buffer = new byte[8192];
ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
data.limit(data.capacity());
data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);
while (data.hasRemaining()) {
int count = Math.min(buffer.length, data.remaining());
data.get(buffer, 0, count);
adler32.update(buffer, 0, count);
}
return (int) adler32.getValue();
}
private static ByteBuffer fill(ByteBuffer b) {
int i = 0;
while (b.hasRemaining()) {
b.put((byte) (++i & 0xff));
}
return b;
}
private RenegotiationInfoSpec(ByteBuffer m) throws IOException {
// Parse the extension.
if (!m.hasRemaining() || m.remaining() < 1) {
throw new SSLProtocolException(
"Invalid renegotiation_info extension data: " +
"insufficient data");
}
this.renegotiatedConnection = Record.getBytes8(m);
}
@Override
public void completed(Integer nwrote, ByteBuffer buf) {
long pos = updatePosition(nwrote);
if (!buf.hasRemaining()) {
// buffer has been completely written; decide if we need to
// write more
if (position >= size) {
done();
return;
}
buf = genNextBuffer();
}
channel.write(buf, pos, buf, this);
}
/**
* Updates the CRC-32C checksum with the bytes from the specified buffer.
*
* The checksum is updated with the remaining bytes in the buffer, starting
* at the buffer's position. Upon return, the buffer's position will be
* updated to its limit; its limit will not have been changed.
*/
@Override
public void update(ByteBuffer buffer) {
int pos = buffer.position();
int limit = buffer.limit();
assert (pos <= limit);
int rem = limit - pos;
if (rem <= 0) {
return;
}
if (buffer instanceof DirectBuffer) {
crc = updateDirectByteBuffer(crc, ((DirectBuffer) buffer).address(),
pos, limit);
} else if (buffer.hasArray()) {
crc = updateBytes(crc, buffer.array(), pos + buffer.arrayOffset(),
limit + buffer.arrayOffset());
} else {
byte[] b = new byte[Math.min(buffer.remaining(), 4096)];
while (buffer.hasRemaining()) {
int length = Math.min(buffer.remaining(), b.length);
buffer.get(b, 0, length);
update(b, 0, length);
}
}
buffer.position(limit);
}
@Override
public int write(String name, ByteBuffer src) throws IOException {
if (System.getSecurityManager() != null)
checkAccess(file.getPathForPermissionCheck(), false, true);
int fd = file.openForAttributeAccess(followLinks);
try {
try {
// open/create attribute file
int afd = openat(fd, nameAsBytes(file,name),
(O_CREAT|O_WRONLY|O_TRUNC|O_XATTR),
UnixFileModeAttribute.ALL_PERMISSIONS);
// wrap with channel
FileChannel fc = UnixChannelFactory.newFileChannel(afd, file.toString(), false, true);
// write value (nothing we can do if I/O error occurs)
try {
int rem = src.remaining();
while (src.hasRemaining()) {
fc.write(src);
}
return rem;
} finally {
fc.close();
}
} catch (UnixException x) {
throw new FileSystemException(file.getPathForExceptionMessage(),
null, "Unable to write extended attribute '" + name +
"': " + x.getMessage());
}
} finally {
close(fd);
}
}
public void fromByteBuffer(ByteBuffer byteBuffer) {
clear();
int i = 0;
while(byteBuffer.hasRemaining()) {
data[i] = byteBuffer.get();
i++;
}
}
/**
* Reads bytes from input, parsing them into a frame. Returns false if and only if more data is
* needed. To obtain a full frame this method must be called repeatedly until it returns true.
*/
public boolean readBytes(ByteBuffer input) throws GeneralSecurityException {
Preconditions.checkNotNull(input);
if (isComplete) {
return true;
}
// Read enough bytes to determine the length
while (buffer.position() < FRAME_LENGTH_HEADER_SIZE && input.hasRemaining()) {
buffer.put(input.get());
}
// If we have enough bytes to determine the length, read the length and ensure that our
// internal buffer is large enough.
if (buffer.position() == FRAME_LENGTH_HEADER_SIZE && input.hasRemaining()) {
ByteBuffer bufferAlias = buffer.duplicate();
bufferAlias.flip();
bufferAlias.order(ByteOrder.LITTLE_ENDIAN);
int dataLength = bufferAlias.getInt();
if (dataLength < FRAME_MESSAGE_TYPE_HEADER_SIZE || dataLength > MAX_DATA_LENGTH) {
throw new IllegalArgumentException("Invalid frame length " + dataLength);
}
// Maybe resize the buffer
int frameLength = dataLength + FRAME_LENGTH_HEADER_SIZE;
if (buffer.capacity() < frameLength) {
buffer = ByteBuffer.allocate(frameLength);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putInt(dataLength);
}
buffer.limit(frameLength);
}
// TODO: Similarly extract and check message type.
// Read the remaining data into the internal buffer.
copy(buffer, input);
if (!buffer.hasRemaining()) {
buffer.flip();
isComplete = true;
}
return isComplete;
}
protected CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
int mark = src.position();
try {
while (src.hasRemaining()) {
int b1 = src.get() & 0xff;
int inSize = 1;
if (b1 == SO) { // Shift out
if (currentState != SBCS)
return CoderResult.malformedForLength(1);
else
currentState = DBCS;
} else if (b1 == SI) {
if (currentState != DBCS)
return CoderResult.malformedForLength(1);
else
currentState = SBCS;
} else {
char c = UNMAPPABLE_DECODING;
if (currentState == SBCS) {
c = b2cSB[b1];
if (c == UNMAPPABLE_DECODING)
return CoderResult.unmappableForLength(1);
} else {
if (src.remaining() < 1)
return CoderResult.UNDERFLOW;
int b2 = src.get()&0xff;
if (b2 < b2Min || b2 > b2Max ||
(c = b2c[b1][b2 - b2Min]) == UNMAPPABLE_DECODING) {
if (!isDoubleByte(b1, b2))
return CoderResult.malformedForLength(2);
return CoderResult.unmappableForLength(2);
}
inSize++;
}
if (dst.remaining() < 1)
return CoderResult.OVERFLOW;
dst.put(c);
}
mark += inSize;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(mark);
}
}
private CoderResult decodeBufferLoop(ByteBuffer src,
CharBuffer dst)
{
int mark = src.position();
int b1 = 0, b2 = 0;
int inputSize = 0;
char outputChar = REPLACE_CHAR; // U+FFFD;
try {
while (src.hasRemaining()) {
b1 = src.get() & 0xff;
inputSize = 1;
if ((b1 & 0x80) == 0) {
outputChar = (char)b1;
} else { // Multibyte char
if ((b1 & 0xff) == 0x8f) { // JIS0212
if (src.remaining() < 2)
return CoderResult.UNDERFLOW;
b1 = src.get() & 0xff;
b2 = src.get() & 0xff;
inputSize += 2;
outputChar = decode0212(b1-0x80, b2-0x80);
} else {
// JIS0208
if (src.remaining() < 1)
return CoderResult.UNDERFLOW;
b2 = src.get() & 0xff;
inputSize++;
outputChar = decodeDouble(b1, b2);
}
}
if (outputChar == REPLACE_CHAR) {
return CoderResult.unmappableForLength(inputSize);
}
if (dst.remaining() < 1)
return CoderResult.OVERFLOW;
dst.put(outputChar);
mark += inputSize;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(mark);
}
}
@SuppressWarnings("unchecked")
private <V extends Number,A> Future<V> read(boolean isScatteringRead,
ByteBuffer dst,
ByteBuffer[] dsts,
long timeout,
TimeUnit unit,
A att,
CompletionHandler<V,? super A> handler)
{
if (!isOpen()) {
Throwable e = new ClosedChannelException();
if (handler == null)
return CompletedFuture.withFailure(e);
Invoker.invoke(this, handler, att, null, e);
return null;
}
if (remoteAddress == null)
throw new NotYetConnectedException();
boolean hasSpaceToRead = isScatteringRead || dst.hasRemaining();
boolean shutdown = false;
// check and update state
synchronized (readLock) {
if (readKilled)
throw new IllegalStateException("Reading not allowed due to timeout or cancellation");
if (reading)
throw new ReadPendingException();
if (readShutdown) {
shutdown = true;
} else {
if (hasSpaceToRead) {
reading = true;
}
}
}
// immediately complete with -1 if shutdown for read
// immediately complete with 0 if no space remaining
if (shutdown || !hasSpaceToRead) {
Number result;
if (isScatteringRead) {
result = (shutdown) ? Long.valueOf(-1L) : Long.valueOf(0L);
} else {
result = (shutdown) ? -1 : 0;
}
if (handler == null)
return CompletedFuture.withResult((V)result);
Invoker.invoke(this, handler, att, (V)result, null);
return null;
}
return implRead(isScatteringRead, dst, dsts, timeout, unit, att, handler);
}
/**
* This function is called when a Length is in the process of being decoded,
* but the lack of bytes in the buffer stopped the process.
*
* @param stream The ByteBuffer containing the PDU to decode
* @param container The container that stores the current state,
* the result and other informations.
* @return <code>true</code> if there are more bytes to read, <code>false
* </code> otherwise
*/
private static boolean treatLengthPendingState( ByteBuffer stream, Asn1Container container )
{
if ( stream.hasRemaining() )
{
TLV tlv = container.getCurrentTLV();
int length = tlv.getLength();
while ( tlv.getLengthBytesRead() < tlv.getLengthNbBytes() )
{
byte octet = stream.get();
if ( LOG.isDebugEnabled() )
{
LOG.debug( I18n.msg( I18n.MSG_01002_CURRENT_BYTE, Asn1StringUtils.dumpByte( octet ) ) );
}
tlv.incLengthBytesRead();
length = ( length << 8 ) | ( octet & 0x00FF );
if ( !stream.hasRemaining() )
{
tlv.setLength( length );
if ( tlv.getLengthBytesRead() < tlv.getLengthNbBytes() )
{
container.setState( TLVStateEnum.LENGTH_STATE_PENDING );
return END;
}
else
{
container.setState( TLVStateEnum.LENGTH_STATE_END );
return MORE;
}
}
}
tlv.setLength( length );
container.setState( TLVStateEnum.LENGTH_STATE_END );
return MORE;
}
else
{
return END;
}
}
protected CoderResult decodeBufferLoop(ByteBuffer src, CharBuffer dst) {
int mark = src.position();
try {
while (src.hasRemaining()) {
char[] cc = null;
int b1 = src.get() & 0xff;
int inSize = 1, outSize = 1;
char c = decodeSingle(b1);
if (c == UNMAPPABLE_DECODING) {
if (src.remaining() < 1)
return CoderResult.UNDERFLOW;
int b2 = src.get() & 0xff;
inSize++;
if (b2 < b2Min || b2 > b2Max)
return CoderResult.unmappableForLength(2);
c = decodeDouble(b1, b2); //bmp
if (c == UNMAPPABLE_DECODING) {
c = decodeDoubleEx(b1, b2); //supp
if (c == UNMAPPABLE_DECODING) {
c = decodeBig5(b1, b2); //big5
if (c == UNMAPPABLE_DECODING)
return CoderResult.unmappableForLength(2);
} else {
outSize = 2;
}
}
}
if (dst.remaining() < outSize)
return CoderResult.OVERFLOW;
if (outSize == 2) {
dst.put(Surrogate.high(0x20000 + c));
dst.put(Surrogate.low(0x20000 + c));
} else {
dst.put(c);
}
mark += inSize;
}
return CoderResult.UNDERFLOW;
} finally {
src.position(mark);
}
}