List of usage examples for io.netty.buffer ByteBuf isReadable
public abstract boolean isReadable();
From source file:io.netlibs.bgp.netty.protocol.open.CapabilityCodec.java
License:Apache License
public static List<Capability> decodeCapabilities(final ByteBuf buffer) { final List<Capability> caps = new LinkedList<Capability>(); while (buffer.isReadable()) { caps.add(decodeCapability(buffer)); }//from w ww. ja va 2 s . c om return caps; }
From source file:io.reactivex.netty.pipeline.ByteArrayPipelineConfigurator.java
License:Apache License
@Override public void configureNewPipeline(ChannelPipeline pipeline) { pipeline.addLast(new ChannelDuplexHandler() { @Override//from w ww. j a va 2s .c o m public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { boolean handled = false; if (ByteBuf.class.isAssignableFrom(msg.getClass())) { ByteBuf byteBuf = (ByteBuf) msg; if (byteBuf.isReadable()) { int readableBytes = byteBuf.readableBytes(); byte[] msgToPass = new byte[readableBytes]; byteBuf.readBytes(msgToPass); handled = true; ctx.fireChannelRead(msgToPass); } } if (!handled) { super.channelRead(ctx, msg); } } @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if (msg instanceof byte[]) { byte[] msgAsBytes = (byte[]) msg; ByteBuf byteBuf = ctx.alloc().buffer(msgAsBytes.length).writeBytes(msgAsBytes); super.write(ctx, byteBuf, promise); } else { super.write(ctx, msg, promise); // pass-through } } }); }
From source file:io.reactivex.netty.protocol.http.client.ClientRequestResponseConverter.java
License:Apache License
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { Class<?> recievedMsgClass = msg.getClass(); /**/*w w w . j a va2s . c om*/ * Issue: https://github.com/Netflix/RxNetty/issues/129 * The contentSubject changes in a different method userEventTriggered() when the connection is reused. If the * connection reuse event is generated as part of execution of this method (for the specific issue, as part of * super.channelRead(ctx, rxResponse); below) it will so happen that we invoke onComplete (below code when the * first response completes) on the new subject as opposed to the old response subject. */ @SuppressWarnings("rawtypes") final PublishSubject subjectToUse = contentSubject; if (HttpResponse.class.isAssignableFrom(recievedMsgClass)) { responseReceiveStartTimeMillis = Clock.newStartTimeMillis(); eventsSubject.onEvent(HttpClientMetricsEvent.RESPONSE_HEADER_RECEIVED); @SuppressWarnings({ "rawtypes", "unchecked" }) HttpResponse response = (HttpResponse) msg; @SuppressWarnings({ "rawtypes", "unchecked" }) HttpClientResponse rxResponse = new HttpClientResponse(response, subjectToUse); Long keepAliveTimeoutSeconds = rxResponse.getKeepAliveTimeoutSeconds(); if (null != keepAliveTimeoutSeconds) { ctx.channel().attr(KEEP_ALIVE_TIMEOUT_MILLIS_ATTR).set(keepAliveTimeoutSeconds * 1000); } if (!rxResponse.getHeaders().isKeepAlive()) { ctx.channel().attr(DISCARD_CONNECTION).set(true); } super.channelRead(ctx, rxResponse); // For FullHttpResponse, this assumes that after this call returns, // someone has subscribed to the content observable, if not the content will be lost. } if (HttpContent.class.isAssignableFrom(recievedMsgClass)) {// This will be executed if the incoming message is a FullHttpResponse or only HttpContent. eventsSubject.onEvent(HttpClientMetricsEvent.RESPONSE_CONTENT_RECEIVED); ByteBuf content = ((ByteBufHolder) msg).content(); if (content.isReadable()) { invokeContentOnNext(content); } if (LastHttpContent.class.isAssignableFrom(recievedMsgClass)) { eventsSubject.onEvent(HttpClientMetricsEvent.RESPONSE_RECEIVE_COMPLETE, Clock.onEndMillis(responseReceiveStartTimeMillis)); subjectToUse.onCompleted(); } } else if (!HttpResponse.class.isAssignableFrom(recievedMsgClass)) { invokeContentOnNext(msg); } }
From source file:io.reactivex.netty.protocol.http.sse.ServerSentEventDecoder.java
License:Apache License
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (null == sseEncodingCharset) { throw new IllegalArgumentException("Can not read SSE data as UTF-8 charset is not available."); }/*from w ww . j a va 2 s . co m*/ while (in.isReadable()) { final int readerIndexAtStart = in.readerIndex(); switch (state) { case SkipColonAndWhiteSpaces: if (skipColonAndWhiteSpaces(in)) { state = State.ReadFieldValue; } break; case SkipLineDelimitersAndSpaces: if (skipLineDelimiters(in)) { state = State.ReadFieldName; } break; case DiscardTillEOL: if (skipTillEOL(in)) { state = State.SkipLineDelimitersAndSpaces; } break; case ReadFieldName: final int indexOfColon = scanAndFindColon(in); if (-1 == indexOfColon) { // No colon found // Accumulate data into the field name buffer. if (null == incompleteData) { incompleteData = ctx.alloc().buffer(); } // accumulate into incomplete data buffer to be used when the full data arrives. incompleteData.writeBytes(in); } else { int fieldNameLengthInTheCurrentBuffer = indexOfColon - readerIndexAtStart; ByteBuf fieldNameBuffer; if (null != incompleteData) { // Read the remaining data into the temporary buffer in.readBytes(incompleteData, fieldNameLengthInTheCurrentBuffer); fieldNameBuffer = incompleteData; incompleteData = null; } else { // Consume the data from the input buffer. fieldNameBuffer = ctx.alloc().buffer(fieldNameLengthInTheCurrentBuffer, fieldNameLengthInTheCurrentBuffer); in.readBytes(fieldNameBuffer, fieldNameLengthInTheCurrentBuffer); } state = State.SkipColonAndWhiteSpaces; // We have read the field name, next we should skip colon & WS. try { currentFieldType = readCurrentFieldTypeFromBuffer(fieldNameBuffer); } finally { if (null == currentFieldType) { state = State.DiscardTillEOL; // Ignore this event completely. } fieldNameBuffer.release(); } } break; case ReadFieldValue: final int endOfLineStartIndex = scanAndFindEndOfLine(in); if (-1 == endOfLineStartIndex) { // End of line not found, accumulate data into a temporary buffer. if (null == incompleteData) { incompleteData = ctx.alloc().buffer(in.readableBytes()); } // accumulate into incomplete data buffer to be used when the full data arrives. incompleteData.writeBytes(in); } else { // Read the data till end of line into the value buffer. final int bytesAvailableInThisIteration = endOfLineStartIndex - readerIndexAtStart; if (null == incompleteData) { incompleteData = ctx.alloc().buffer(bytesAvailableInThisIteration, bytesAvailableInThisIteration); } incompleteData.writeBytes(in, bytesAvailableInThisIteration); switch (currentFieldType) { case Data: if (incompleteData.isReadable()) { out.add(ServerSentEvent.withEventIdAndType(lastEventId, lastEventType, incompleteData)); } else { incompleteData.release(); } break; case Id: if (incompleteData.isReadable()) { lastEventId = incompleteData; } else { incompleteData.release(); lastEventId = null; } break; case EventType: if (incompleteData.isReadable()) { lastEventType = incompleteData; } else { incompleteData.release(); lastEventType = null; } break; } /** * Since all data is read, reset the incomplete data to null. Release of this buffer happens in * the following ways * 1) If this was a data buffer, it is released when ServerSentEvent is released. * 2) If this was an eventId buffer, it is released when next Id arrives or when the connection * is closed. * 3) If this was an eventType buffer, it is released when next type arrives or when the connection * is closed. */ incompleteData = null; state = State.SkipLineDelimitersAndSpaces; // Skip line delimiters after reading a field value completely. } break; } } }
From source file:io.reactivex.netty.protocol.http.sse.ServerSentEventEncoder.java
License:Apache License
@Override protected void encode(ChannelHandlerContext ctx, ServerSentEvent serverSentEvent, ByteBuf out) throws Exception { if (serverSentEvent.hasEventType()) { // Write event type, if available out.writeBytes(EVENT_PREFIX_BYTES); out.writeBytes(serverSentEvent.getEventType()); out.writeBytes(NEW_LINE_AS_BYTES); }/* w w w.j a v a 2s . c o m*/ if (serverSentEvent.hasEventId()) { // Write event id, if available out.writeBytes(ID_PREFIX_AS_BYTES); out.writeBytes(serverSentEvent.getEventId()); out.writeBytes(NEW_LINE_AS_BYTES); } final ByteBuf content = serverSentEvent.content(); if (splitSseData) { while (content.isReadable()) { // Scan the buffer and split on new line into multiple data lines. final int readerIndexAtStart = content.readerIndex(); int newLineIndex = content.forEachByte(new ByteBufProcessor() { @Override public boolean process(byte value) throws Exception { return (char) value != '\n'; } }); if (-1 == newLineIndex) { // No new line, write the buffer as is. out.writeBytes(DATA_PREFIX_AS_BYTES); out.writeBytes(content); out.writeBytes(NEW_LINE_AS_BYTES); } else { // Write the buffer till the new line and then iterate this loop out.writeBytes(DATA_PREFIX_AS_BYTES); out.writeBytes(content, newLineIndex - readerIndexAtStart); content.readerIndex(content.readerIndex() + 1); out.writeBytes(NEW_LINE_AS_BYTES); } } } else { // write the buffer with data prefix and new line post fix. out.writeBytes(DATA_PREFIX_AS_BYTES); out.writeBytes(content); out.writeBytes(NEW_LINE_AS_BYTES); } }
From source file:io.reactivex.netty.RxEventPipelineConfigurator.java
License:Apache License
@Override public void configureNewPipeline(ChannelPipeline pipeline) { pipeline.addLast(new ChannelDuplexHandler() { @Override//from w w w . ja va2 s .co m public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { boolean handled = false; if (ByteBuf.class.isAssignableFrom(msg.getClass())) { ByteBuf byteBuf = (ByteBuf) msg; if (byteBuf.isReadable()) { int protocolVersion = byteBuf.readByte(); if (protocolVersion != PROTOCOL_VERSION) { throw new RuntimeException("Unsupported protocol version: " + protocolVersion); } int observableNameLength = byteBuf.readByte(); String observableName = null; if (observableNameLength > 0) { // read name observableName = new String(byteBuf.readBytes(observableNameLength).array()); } int operation = byteBuf.readByte(); RemoteRxEvent.Type type = null; Map<String, String> subscribeParams = null; byte[] valueData = null; if (operation == 1) { logger.debug("READ request for RemoteRxEvent: next"); type = RemoteRxEvent.Type.next; valueData = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(valueData); } else if (operation == 2) { logger.debug("READ request for RemoteRxEvent: error"); type = RemoteRxEvent.Type.error; valueData = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(valueData); } else if (operation == 3) { logger.debug("READ request for RemoteRxEvent: completed"); type = RemoteRxEvent.Type.completed; } else if (operation == 4) { logger.debug("READ request for RemoteRxEvent: subscribed"); type = RemoteRxEvent.Type.subscribed; // read subscribe parameters int subscribeParamsLength = byteBuf.readInt(); if (subscribeParamsLength > 0) { // read byte into map byte[] subscribeParamsBytes = new byte[subscribeParamsLength]; byteBuf.readBytes(subscribeParamsBytes); subscribeParams = fromBytesToMap(subscribeParamsBytes); } } else if (operation == 5) { logger.debug("READ request for RemoteRxEvent: unsubscribed"); type = RemoteRxEvent.Type.unsubscribed; } else { throw new RuntimeException("operation: " + operation + " not support."); } handled = true; byteBuf.release(); ctx.fireChannelRead(new RemoteRxEvent(observableName, type, valueData, subscribeParams)); } } if (!handled) { super.channelRead(ctx, msg); } } @Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { if (msg instanceof RemoteRxEvent) { ByteBuf buf = ctx.alloc().buffer(); buf.writeByte(PROTOCOL_VERSION); RemoteRxEvent event = (RemoteRxEvent) msg; String observableName = event.getName(); if (observableName != null && !observableName.isEmpty()) { // write length int nameLength = observableName.length(); if (nameLength < 127) { buf.writeByte(nameLength); buf.writeBytes(observableName.getBytes()); } else { throw new RuntimeException( "observableName " + observableName + " exceeds max limit of 127 characters"); } } else { // no name provided, write 0 bytes for name length buf.writeByte(0); } if (event.getType() == RemoteRxEvent.Type.next) { logger.debug("WRITE request for RemoteRxEvent: next"); buf.writeByte(1); buf.writeBytes(event.getData()); super.write(ctx, buf, promise); } else if (event.getType() == RemoteRxEvent.Type.error) { logger.debug("WRITE request for RemoteRxEvent: error"); buf.writeByte(2); buf.writeBytes(event.getData()); super.write(ctx, buf, promise); } else if (event.getType() == RemoteRxEvent.Type.completed) { logger.debug("WRITE request for RemoteRxEvent: completed"); buf.writeByte(3); super.write(ctx, buf, promise); super.flush(ctx); // TODO why do I need to explicitly call flush for this to work??? empty data?? } else if (event.getType() == RemoteRxEvent.Type.subscribed) { logger.debug("WRITE request for RemoteRxEvent: subscribed"); buf.writeByte(4); Map<String, String> subscribeParameters = event.getSubscribeParameters(); if (subscribeParameters != null && !subscribeParameters.isEmpty()) { byte[] subscribeBytes = fromMapToBytes(subscribeParameters); buf.writeInt(subscribeBytes.length); // write int for length buf.writeBytes(subscribeBytes); // write data } else { buf.writeInt(0); // no data } super.write(ctx, buf, promise); super.flush(ctx); } else if (event.getType() == RemoteRxEvent.Type.unsubscribed) { logger.debug("WRITE request for RemoteRxEvent: unsubscribed"); buf.writeByte(5); super.write(ctx, buf, promise); super.flush(ctx); // TODO why do I need to explicitly call flush for this to work??? empty data?? } } else { super.write(ctx, msg, promise); } } }); }
From source file:io.scalecube.socketio.serialization.PacketFramer.java
License:Apache License
public static List<Packet> decodePacketsFrame(final ByteBuf buffer) throws IOException { List<Packet> packets = new LinkedList<Packet>(); int sequenceNumber = 0; while (buffer.isReadable()) { Packet packet = PacketFramer.decodeNextPacket(buffer); packet.setSequenceNumber(sequenceNumber); sequenceNumber++;/*from ww w .j av a 2 s.com*/ packets.add(packet); } return packets; }
From source file:io.vertx.core.dns.impl.decoder.RecordDecoder.java
License:Open Source License
/** * Retrieves a domain name given a buffer containing a DNS packet. If the * name contains a pointer, the position of the buffer will be set to * directly after the pointer's index after the name has been read. * * @param buf the byte buffer containing the DNS packet * @return the domain name for an entry//www .j a va 2 s.c o m */ static String readName(ByteBuf buf) { int position = -1; StringBuilder name = new StringBuilder(); for (int len = buf.readUnsignedByte(); buf.isReadable() && len != 0; len = buf.readUnsignedByte()) { boolean pointer = (len & 0xc0) == 0xc0; if (pointer) { if (position == -1) { position = buf.readerIndex() + 1; } buf.readerIndex((len & 0x3f) << 8 | buf.readUnsignedByte()); } else { name.append(buf.toString(buf.readerIndex(), len, CharsetUtil.UTF_8)).append("."); buf.skipBytes(len); } } if (position != -1) { buf.readerIndex(position); } if (name.length() == 0) { return null; } return name.substring(0, name.length() - 1); }
From source file:io.vertx.core.dns.impl.fix.DnsNameResolverContext.java
License:Apache License
/** * Retrieves a domain name given a buffer containing a DNS packet. If the * name contains a pointer, the position of the buffer will be set to * directly after the pointer's index after the name has been read. * * @param in the byte buffer containing the DNS packet * @return the domain name for an entry/*from w w w.j a va2s .c o m*/ */ public static String decodeName(ByteBuf in) { int position = -1; int checked = 0; final int end = in.writerIndex(); final int readable = in.readableBytes(); // Looking at the spec we should always have at least enough readable bytes to read a byte here but it seems // some servers do not respect this for empty names. So just workaround this and return an empty name in this // case. // // See: // - https://github.com/netty/netty/issues/5014 // - https://www.ietf.org/rfc/rfc1035.txt , Section 3.1 if (readable == 0) { return "."; } final StringBuilder name = new StringBuilder(readable << 1); while (in.isReadable()) { final int len = in.readUnsignedByte(); final boolean pointer = (len & 0xc0) == 0xc0; if (pointer) { if (position == -1) { position = in.readerIndex() + 1; } if (!in.isReadable()) { throw new CorruptedFrameException("truncated pointer in a name"); } final int next = (len & 0x3f) << 8 | in.readUnsignedByte(); if (next >= end) { throw new CorruptedFrameException("name has an out-of-range pointer"); } in.readerIndex(next); // check for loops checked += 2; if (checked >= end) { throw new CorruptedFrameException("name contains a loop."); } } else if (len != 0) { if (!in.isReadable(len)) { throw new CorruptedFrameException("truncated label in a name"); } name.append(in.toString(in.readerIndex(), len, CharsetUtil.UTF_8)).append('.'); in.skipBytes(len); } else { // len == 0 break; } } if (position != -1) { in.readerIndex(position); } if (name.length() == 0) { return "."; } if (name.charAt(name.length() - 1) != '.') { name.append('.'); } return name.toString(); }
From source file:io.vertx.core.http.impl.ClientConnection.java
License:Open Source License
@Override public void writeBuffer(ByteBuf buff, boolean end) { if (end) {/* ww w . j a va 2 s.c om*/ if (buff != null && buff.isReadable()) { writeToChannel(new DefaultLastHttpContent(buff, false)); } else { writeToChannel(LastHttpContent.EMPTY_LAST_CONTENT); } } else if (buff != null) { writeToChannel(new DefaultHttpContent(buff)); } }