Example usage for io.netty.buffer ByteBuf readableBytes

List of usage examples for io.netty.buffer ByteBuf readableBytes

Introduction

In this page you can find the example usage for io.netty.buffer ByteBuf readableBytes.

Prototype

public abstract int readableBytes();

Source Link

Document

Returns the number of readable bytes which is equal to (this.writerIndex - this.readerIndex) .

Usage

From source file:com.github.sparkfy.network.protocol.MessageWithHeader.java

License:Apache License

/**
 * Construct a new MessageWithHeader./*  w w w  . ja  va  2s.  c om*/
 *
 * @param managedBuffer the {@link ManagedBuffer} that the message body came from. This needs to
 *                      be passed in so that the buffer can be freed when this message is
 *                      deallocated. Ownership of the caller's reference to this buffer is
 *                      transferred to this class, so if the caller wants to continue to use the
 *                      ManagedBuffer in other messages then they will need to call retain() on
 *                      it before passing it to this constructor. This may be null if and only if
 *                      `body` is a {@link FileRegion}.
 * @param header the message header.
 * @param body the message body. Must be either a {@link ByteBuf} or a {@link FileRegion}.
 * @param bodyLength the length of the message body, in bytes.
   */
MessageWithHeader(ManagedBuffer managedBuffer, ByteBuf header, Object body, long bodyLength) {
    Preconditions.checkArgument(body instanceof ByteBuf || body instanceof FileRegion,
            "Body must be a ByteBuf or a FileRegion.");
    this.managedBuffer = managedBuffer;
    this.header = header;
    this.headerLength = header.readableBytes();
    this.body = body;
    this.bodyLength = bodyLength;
}

From source file:com.github.sparkfy.network.protocol.MessageWithHeaderSuite.java

License:Apache License

@Test
public void testByteBufBody() throws Exception {
    ByteBuf header = Unpooled.copyLong(42);
    ByteBuf bodyPassedToNettyManagedBuffer = Unpooled.copyLong(84);
    assertEquals(1, header.refCnt());//from  w  w w  .ja  v  a  2 s.c  o  m
    assertEquals(1, bodyPassedToNettyManagedBuffer.refCnt());
    ManagedBuffer managedBuf = new NettyManagedBuffer(bodyPassedToNettyManagedBuffer);

    Object body = managedBuf.convertToNetty();
    assertEquals(2, bodyPassedToNettyManagedBuffer.refCnt());
    assertEquals(1, header.refCnt());

    MessageWithHeader msg = new MessageWithHeader(managedBuf, header, body, managedBuf.size());
    ByteBuf result = doWrite(msg, 1);
    assertEquals(msg.count(), result.readableBytes());
    assertEquals(42, result.readLong());
    assertEquals(84, result.readLong());

    assert (msg.release());
    assertEquals(0, bodyPassedToNettyManagedBuffer.refCnt());
    assertEquals(0, header.refCnt());
}

From source file:com.github.sparkfy.network.protocol.MessageWithHeaderSuite.java

License:Apache License

private void testFileRegionBody(int totalWrites, int writesPerCall) throws Exception {
    ByteBuf header = Unpooled.copyLong(42);
    int headerLength = header.readableBytes();
    TestFileRegion region = new TestFileRegion(totalWrites, writesPerCall);
    MessageWithHeader msg = new MessageWithHeader(null, header, region, region.count());

    ByteBuf result = doWrite(msg, totalWrites / writesPerCall);
    assertEquals(headerLength + region.count(), result.readableBytes());
    assertEquals(42, result.readLong());
    for (long i = 0; i < 8; i++) {
        assertEquals(i, result.readLong());
    }//from  w  w w.j  av a2 s.  c o  m
    assert (msg.release());
}

From source file:com.github.sparkfy.network.protocol.StreamChunkId.java

License:Apache License

public static StreamChunkId decode(ByteBuf buffer) {
    assert buffer.readableBytes() >= 8 + 4;
    long streamId = buffer.readLong();
    int chunkIndex = buffer.readInt();
    return new StreamChunkId(streamId, chunkIndex);
}

From source file:com.github.sparkfy.network.util.TransportFrameDecoder.java

License:Apache License

@Override
public void channelRead(ChannelHandlerContext ctx, Object data) throws Exception {
    ByteBuf in = (ByteBuf) data;
    buffers.add(in);//ww  w . j av  a 2 s . c o m
    totalSize += in.readableBytes();

    while (!buffers.isEmpty()) {
        // First, feed the interceptor, and if it's still, active, try again.
        if (interceptor != null) {
            ByteBuf first = buffers.getFirst();
            int available = first.readableBytes();
            if (feedInterceptor(first)) {
                assert !first.isReadable() : "Interceptor still active but buffer has data.";
            }

            int read = available - first.readableBytes();
            if (read == available) {
                buffers.removeFirst().release();
            }
            totalSize -= read;
        } else {
            // Interceptor is not active, so try to decode one frame.
            ByteBuf frame = decodeNext();
            if (frame == null) {
                break;
            }
            ctx.fireChannelRead(frame);
        }
    }
}

From source file:com.github.sparkfy.network.util.TransportFrameDecoder.java

License:Apache License

private long decodeFrameSize() {
    if (nextFrameSize != UNKNOWN_FRAME_SIZE || totalSize < LENGTH_SIZE) {
        return nextFrameSize;
    }//from  w w  w.ja  v  a  2 s  . c o  m

    // We know there's enough data. If the first buffer contains all the data, great. Otherwise,
    // hold the bytes for the frame length in a composite buffer until we have enough data to read
    // the frame size. Normally, it should be rare to need more than one buffer to read the frame
    // size.
    ByteBuf first = buffers.getFirst();
    if (first.readableBytes() >= LENGTH_SIZE) {
        nextFrameSize = first.readLong() - LENGTH_SIZE;
        totalSize -= LENGTH_SIZE;
        if (!first.isReadable()) {
            buffers.removeFirst().release();
        }
        return nextFrameSize;
    }

    while (frameLenBuf.readableBytes() < LENGTH_SIZE) {
        ByteBuf next = buffers.getFirst();
        int toRead = Math.min(next.readableBytes(), LENGTH_SIZE - frameLenBuf.readableBytes());
        frameLenBuf.writeBytes(next, toRead);
        if (!next.isReadable()) {
            buffers.removeFirst().release();
        }
    }

    nextFrameSize = frameLenBuf.readLong() - LENGTH_SIZE;
    totalSize -= LENGTH_SIZE;
    frameLenBuf.clear();
    return nextFrameSize;
}

From source file:com.github.sparkfy.network.util.TransportFrameDecoder.java

License:Apache License

private ByteBuf decodeNext() throws Exception {
    long frameSize = decodeFrameSize();
    if (frameSize == UNKNOWN_FRAME_SIZE || totalSize < frameSize) {
        return null;
    }/*from ww w.  j  av a2s. co  m*/

    // Reset size for next frame.
    nextFrameSize = UNKNOWN_FRAME_SIZE;

    Preconditions.checkArgument(frameSize < MAX_FRAME_SIZE, "Too large frame: %s", frameSize);
    Preconditions.checkArgument(frameSize > 0, "Frame length should be positive: %s", frameSize);

    // If the first buffer holds the entire frame, return it.
    int remaining = (int) frameSize;
    if (buffers.getFirst().readableBytes() >= remaining) {
        return nextBufferForFrame(remaining);
    }

    // Otherwise, create a composite buffer.
    CompositeByteBuf frame = buffers.getFirst().alloc().compositeBuffer();
    while (remaining > 0) {
        ByteBuf next = nextBufferForFrame(remaining);
        remaining -= next.readableBytes();
        frame.addComponent(next).writerIndex(frame.writerIndex() + next.readableBytes());
    }
    assert remaining == 0;
    return frame;
}

From source file:com.github.sparkfy.network.util.TransportFrameDecoder.java

License:Apache License

/**
 * Takes the first buffer in the internal list, and either adjust it to fit in the frame
 * (by taking a slice out of it) or remove it from the internal list.
 */// w  ww.ja v  a2  s.c o  m
private ByteBuf nextBufferForFrame(int bytesToRead) {
    ByteBuf buf = buffers.getFirst();
    ByteBuf frame;

    if (buf.readableBytes() > bytesToRead) {
        frame = buf.retain().readSlice(bytesToRead);
        totalSize -= bytesToRead;
    } else {
        frame = buf;
        buffers.removeFirst();
        totalSize -= frame.readableBytes();
    }

    return frame;
}

From source file:com.github.sylvek.wsmqttfwd.decoder.ConnectDecoder.java

License:Open Source License

@Override
public ConnectMessage decode(AttributeMap ctx, ByteBuf in) throws UnsupportedEncodingException {
    in.resetReaderIndex();//from  w  w  w .ja v  a2 s.  c  o m
    //Common decoding part
    ConnectMessage message = new ConnectMessage();
    if (!decodeCommonHeader(message, 0x00, in)) {
        in.resetReaderIndex();
        return null;
    }
    int remainingLength = message.getRemainingLength();
    int start = in.readerIndex();

    int protocolNameLen = in.readUnsignedShort();
    byte[] encProtoName;
    String protoName;
    Attribute<Integer> versionAttr = ctx.attr(PROTOCOL_VERSION);
    switch (protocolNameLen) {
    case 6:
        //MQTT version 3.1 "MQIsdp"
        //ProtocolName 8 bytes or 6 bytes
        if (in.readableBytes() < 10) {
            in.resetReaderIndex();
            return null;
        }

        encProtoName = new byte[6];
        in.readBytes(encProtoName);
        protoName = new String(encProtoName, "UTF-8");
        if (!"MQIsdp".equals(protoName)) {
            in.resetReaderIndex();
            throw new CorruptedFrameException("Invalid protoName: " + protoName);
        }
        message.setProtocolName(protoName);

        versionAttr.set((int) Utils.VERSION_3_1);
        break;
    case 4:
        //MQTT version 3.1.1 "MQTT"
        //ProtocolName 6 bytes
        if (in.readableBytes() < 8) {
            in.resetReaderIndex();
            return null;
        }
        encProtoName = new byte[4];
        in.readBytes(encProtoName);
        protoName = new String(encProtoName, "UTF-8");
        if (!"MQTT".equals(protoName)) {
            in.resetReaderIndex();
            throw new CorruptedFrameException("Invalid protoName: " + protoName);
        }
        message.setProtocolName(protoName);
        versionAttr.set((int) Utils.VERSION_3_1_1);
        break;
    default:
        //protocol broken
        throw new CorruptedFrameException("Invalid protoName size: " + protocolNameLen);
    }

    //ProtocolVersion 1 byte (value 0x03 for 3.1, 0x04 for 3.1.1)
    message.setProtocolVersion(in.readByte());
    if (message.getProtocolVersion() == Utils.VERSION_3_1_1) {
        //if 3.1.1, check the flags (dup, retain and qos == 0)
        if (message.isDupFlag() || message.isRetainFlag()
                || message.getQos() != AbstractMessage.QOSType.MOST_ONE) {
            throw new CorruptedFrameException("Received a CONNECT with fixed header flags != 0");
        }

        //check if this is another connect from the same client on the same session
        Attribute<Boolean> connectAttr = ctx.attr(ConnectDecoder.CONNECT_STATUS);
        Boolean alreadyConnected = connectAttr.get();
        if (alreadyConnected == null) {
            //never set
            connectAttr.set(true);
        } else if (alreadyConnected) {
            throw new CorruptedFrameException("Received a second CONNECT on the same network connection");
        }
    }

    //Connection flag
    byte connFlags = in.readByte();
    if (message.getProtocolVersion() == Utils.VERSION_3_1_1) {
        if ((connFlags & 0x01) != 0) { //bit(0) of connection flags is != 0
            throw new CorruptedFrameException("Received a CONNECT with connectionFlags[0(bit)] != 0");
        }
    }

    boolean cleanSession = ((connFlags & 0x02) >> 1) == 1;
    boolean willFlag = ((connFlags & 0x04) >> 2) == 1;
    byte willQos = (byte) ((connFlags & 0x18) >> 3);
    if (willQos > 2) {
        in.resetReaderIndex();
        throw new CorruptedFrameException("Expected will QoS in range 0..2 but found: " + willQos);
    }
    boolean willRetain = ((connFlags & 0x20) >> 5) == 1;
    boolean passwordFlag = ((connFlags & 0x40) >> 6) == 1;
    boolean userFlag = ((connFlags & 0x80) >> 7) == 1;
    //a password is true iff user is true.
    if (!userFlag && passwordFlag) {
        in.resetReaderIndex();
        throw new CorruptedFrameException(
                "Expected password flag to true if the user flag is true but was: " + passwordFlag);
    }
    message.setCleanSession(cleanSession);
    message.setWillFlag(willFlag);
    message.setWillQos(willQos);
    message.setWillRetain(willRetain);
    message.setPasswordFlag(passwordFlag);
    message.setUserFlag(userFlag);

    //Keep Alive timer 2 bytes
    //int keepAlive = Utils.readWord(in);
    int keepAlive = in.readUnsignedShort();
    message.setKeepAlive(keepAlive);

    if ((remainingLength == 12 && message.getProtocolVersion() == Utils.VERSION_3_1)
            || (remainingLength == 10 && message.getProtocolVersion() == Utils.VERSION_3_1_1)) {
        return message;
    }

    //Decode the ClientID
    String clientID = Utils.decodeString(in);
    if (clientID == null) {
        in.resetReaderIndex();
        return null;
    }
    message.setClientID(clientID);

    //Decode willTopic
    if (willFlag) {
        String willTopic = Utils.decodeString(in);
        if (willTopic == null) {
            in.resetReaderIndex();
            return null;
        }
        message.setWillTopic(willTopic);
    }

    //Decode willMessage
    if (willFlag) {
        byte[] willMessage = Utils.readFixedLengthContent(in);
        if (willMessage == null) {
            in.resetReaderIndex();
            return null;
        }
        message.setWillMessage(willMessage);
    }

    //Compatibility check with v3.0, remaining length has precedence over
    //the user and password flags
    int readed = in.readerIndex() - start;
    if (readed == remainingLength) {
        return message;
    }

    //Decode username
    if (userFlag) {
        String userName = Utils.decodeString(in);
        if (userName == null) {
            in.resetReaderIndex();
            return null;
        }
        message.setUsername(userName);
    }

    readed = in.readerIndex() - start;
    if (readed == remainingLength) {
        return message;
    }

    //Decode password
    if (passwordFlag) {
        byte[] password = Utils.readFixedLengthContent(in);
        if (password == null) {
            in.resetReaderIndex();
            return null;
        }
        message.setPassword(password);
    }

    return message;
}

From source file:com.github.sylvek.wsmqttfwd.decoder.DemuxDecoder.java

License:Open Source License

private boolean genericDecodeCommonHeader(AbstractMessage message, Integer expectedFlagsOpt, ByteBuf in) {
    //Common decoding part
    if (in.readableBytes() < 2) {
        return false;
    }/*w w  w .j  a va 2s . co m*/
    byte h1 = in.readByte();
    byte messageType = (byte) ((h1 & 0x00F0) >> 4);

    byte flags = (byte) (h1 & 0x0F);
    if (expectedFlagsOpt != null) {
        int expectedFlags = expectedFlagsOpt;
        if ((byte) expectedFlags != flags) {
            String hexExpected = Integer.toHexString(expectedFlags);
            String hexReceived = Integer.toHexString(flags);
            throw new CorruptedFrameException(
                    String.format("Received a message with fixed header flags (%s) != expected (%s)",
                            hexReceived, hexExpected));
        }
    }

    boolean dupFlag = ((byte) ((h1 & 0x0008) >> 3) == 1);
    byte qosLevel = (byte) ((h1 & 0x0006) >> 1);
    boolean retainFlag = ((byte) (h1 & 0x0001) == 1);
    int remainingLength = Utils.decodeRemainingLength(in);
    if (remainingLength == -1) {
        return false;
    }

    message.setMessageType(messageType);
    message.setDupFlag(dupFlag);
    try {
        message.setQos(AbstractMessage.QOSType.valueOf(qosLevel));
    } catch (IllegalArgumentException e) {
        throw new CorruptedFrameException(String.format("Received an invalid QOS: %s", e.getMessage()), e);
    }
    message.setRetainFlag(retainFlag);
    message.setRemainingLength(remainingLength);
    return true;
}