@Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { buffer.markReaderIndex(); final byte[] buf = new byte[5]; for (int i = 0; i < buf.length; i++) { if (!buffer.readable()) { buffer.resetReaderIndex(); return null; } buf[i] = buffer.readByte(); if (buf[i] >= 0) { int length = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32(); if (length < 0) { throw new CorruptedFrameException("negative length: " + length); } if (buffer.readableBytes() < length) { buffer.resetReaderIndex(); return null; } else { return buffer.readBytes(length); } } } // Couldn't find the byte whose MSB is off. throw new CorruptedFrameException("length wider than 32-bit"); }
/** * Parse TE List from the channel buffer. * * @param cb of type channel buffer * @throws PcepParseException if mandatory fields are missing */ public void parseTEList(ChannelBuffer cb) throws PcepParseException { byte yObjClass; byte yObjType; llTEObjList = new LinkedList<PcepTEObject>(); // caller should verify for TE object if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { log.debug("Unable to find TE Object"); return; } cb.markReaderIndex(); PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); cb.resetReaderIndex(); yObjClass = tempObjHeader.getObjClass(); yObjType = tempObjHeader.getObjType(); PcepTEObject teObj; while ((yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) && ((yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_NODE_VALUE) || (yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_LINK_VALUE))) { teObj = PcepTEObjectVer1.read(cb); llTEObjList.add(teObj); if (cb.readableBytes() > OBJECT_HEADER_LENGTH) { cb.markReaderIndex(); tempObjHeader = PcepObjectHeader.read(cb); cb.resetReaderIndex(); yObjClass = tempObjHeader.getObjClass(); yObjType = tempObjHeader.getObjType(); } else { break; } } }
/* * Each ControlMessage is encoded as: * code (<0) ... short(2) * Each TaskMessage is encoded as: * task (>=0) ... short(2) * len ... int(4) * payload ... byte[] * */ protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { // Make sure that we have received at least a short if (buf.readableBytes() < 2) { // need more data return null; } // Mark the current buffer position before reading task/len field // because the whole frame might not be in the buffer yet. // We will reset the buffer position to the marked position if // there's not enough bytes in the buffer. buf.markReaderIndex(); // read the short field short code = buf.readShort(); // case 1: Control message ControlMessage ctrl_msg = ControlMessage.mkMessage(code); if (ctrl_msg != null) return ctrl_msg; // case 2: task Message short task = code; // Make sure that we have received at least an integer (length) if (buf.readableBytes() < 4) { // need more data buf.resetReaderIndex(); return null; } // Read the length field. int length = buf.readInt(); if (length <= 0) { return new TaskMessage(task, null); } // Make sure if there's enough bytes in the buffer. if (buf.readableBytes() < length) { // The whole bytes were not received yet - return null. buf.resetReaderIndex(); return null; } // There's enough bytes in the buffer. Read it. ChannelBuffer payload = buf.readBytes(length); // Successfully decoded a frame. // Return a TaskMessage object return new TaskMessage(task, payload.array()); }
private static boolean maybeSsl(final ChannelBuffer buffer) { buffer.markReaderIndex(); final StringBuffer sb = new StringBuffer(); for (int lineLength = 0; lineLength++ < 3; sb.append((char) buffer.readByte())) ; buffer.resetReaderIndex(); return !httpVerbPrefix.contains(sb.toString()); }
@Test public void iternext() { Iternext dut = new Iternext(transcoder, transcoder); ChannelBuffer request = ChannelBuffers.buffer(2); request.writeBytes(new byte[] {(byte) 0xC8, (byte) 0x51}); ChannelBuffer actual = ChannelBuffers.buffer(request.capacity()); dut.encode(actual); assertEquals(request, actual); ChannelBuffer response = ChannelBuffers.buffer(1 + 4 + value.length); assertFalse(dut.decode(response)); response.writeByte(BinaryCommand.ESUCCESS); assertFalse(dut.decode(response)); response.resetReaderIndex(); response.writeInt(value.length); response.writeBytes(value); assertTrue(dut.decode(response)); assertArrayEquals(value, (byte[]) dut.getReturnValue()); // error response.clear(); response.writeByte(BinaryCommand.EUNKNOWN); assertTrue(dut.decode(response)); assertNull(dut.getReturnValue()); }
/** * Reads the byte stream of PcepError from channel buffer. * * @param cb of type channel buffer * @return PcepError error part of PCEP-ERROR * @throws PcepParseException if mandatory fields are missing */ public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException { if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { throw new PcepParseException("Unknown Object"); } PcepErrorVer1 pcepError = new PcepErrorVer1(); // check whether any PCEP Error Info is present cb.markReaderIndex(); PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); cb.resetReaderIndex(); byte yObjClass = tempObjHeader.getObjClass(); // If RPlist present then store it.RPList and TEList are optional if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) { log.debug("RP_LIST"); pcepError.parseRPList(cb); yObjClass = checkNextObject(cb); } else if (yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) { log.debug("TE_LIST"); pcepError.parseTEList(cb); yObjClass = checkNextObject(cb); } if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) { log.debug("PCEP-ERROR obj list"); pcepError.parseErrObjList(cb); yObjClass = checkNextObject(cb); } return pcepError; }
/** * Handles a received {@link MBeanServerConnection} invocation * * @param channel The channel the request was received on * @param remoteAddress The remote address of the caller * @param buffer THe buffer received */ public static void handleJMXRequest( Channel channel, SocketAddress remoteAddress, ChannelBuffer buffer) { buffer.resetReaderIndex(); /* The request write */ // cb.writeByte(OpCode.JMX_REQUEST.op()); // 1 // cb.writeBytes(domainInfoData); // domain data // cb.writeInt(reqId); // 4 // cb.writeByte(methodToKey.get(method)); // 1 // cb.writeInt(sargs.length); // 4 // cb.writeBytes(sargs); // sargs.length Object result = null; MBeanServerConnection server = null; buffer.skipBytes(1); byte domainIndicator = buffer.readByte(); if (domainIndicator == 0) { server = JMXHelper.getHeliosMBeanServer(); } else { byte[] domainBytes = new byte[domainIndicator]; buffer.readBytes(domainBytes); String domain = new String(domainBytes); server = JMXHelper.getLocalMBeanServer(true, domain); if (server == null) { result = new SmallException("Failed to locate MBeanServer for domain [" + domain + "]"); } } int reqId = buffer.readInt(); byte methodId = buffer.readByte(); if (result == null) { int payloadSize = buffer.readInt(); byte[] payload = new byte[payloadSize]; buffer.readBytes(payload); Object[] params = getInput(payload); Method targetMethod = null; try { targetMethod = keyToMethod.get(methodId); if (targetMethod == null) { result = new SmallException( "Failed to handle MBeanServerConnection invocation because method Op Code [" + methodId + "] was not recognized"); } else { if ("addNotificationListener".equals(targetMethod.getName()) && !targetMethod.getParameterTypes()[1].equals(ObjectName.class)) { } else if ("removeNotificationListener".equals(targetMethod.getName()) && !targetMethod.getParameterTypes()[1].equals(ObjectName.class)) { } else { result = targetMethod.invoke(server, params); } } } catch (Throwable t) { SimpleLogger.warn("Failed to invoke [", targetMethod, "]", t); result = new SmallException(t.toString()); } } writeJMXResponse(reqId, methodId, channel, remoteAddress, result); }
/** * Checks Next Object. * * @param cb of type channel buffer. * @return object type class. */ private static byte checkNextObject(ChannelBuffer cb) { if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { return 0; } cb.markReaderIndex(); PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); cb.resetReaderIndex(); return tempObjHeader.getObjClass(); }
/** * Overriden super class method. Uses the {@link CommandInterpreter#readCommand(MessageEvent)} to * interpret the Command and thereby check if all bytes have been received, returns a null * otherwise. * * @see * org.jboss.netty.handler.codec.frame.FrameDecoder#decode(org.jboss.netty.channel.ChannelHandlerContext, * org.jboss.netty.channel.Channel, org.jboss.netty.buffer.ChannelBuffer) */ protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { int beginIndex = buffer.readerIndex(); buffer.markReaderIndex(); CommandInterpreter.ProxyCommand proxyCommand = new CommandInterpreter().interpretCommand(buffer); if (proxyCommand.getReadFailure() != null && proxyCommand.getReadFailure() == ReadFailure.INSUFFICIENT_DATA) { LOGGER.debug( "Frame decode failed due to insufficient data. Message is : " + proxyCommand.getReadFailureDescription()); buffer.resetReaderIndex(); return null; // we return null here and Netty will call this decoder again when more data is // available } int endIndex = buffer.readerIndex(); buffer.resetReaderIndex(); return buffer.readSlice(endIndex - beginIndex); }
/** * Examines the channel buffer and attempts to match the protocol of the request and invoke the * matching {@link ProtocolInitiator}. * * @param ctx The channel handler context * @param channel The channel * @param bufferx The message buffer * @param e The channel event * @return The channel buffer to send upstream, or null if we need more bytes */ protected ChannelBuffer protocolSwitch( ChannelHandlerContext ctx, Channel channel, ChannelBuffer bufferx, ChannelEvent e) { ChannelBuffer cb = preSwitchedBuffer.get(channel); if (cb != null) { cb.writeBytes(bufferx); cb.resetReaderIndex(); } else { cb = bufferx; } // this guy will be set with a matching initiator ProtocolInitiator selectedInitiator = null; // this guy will be set to false if at least 1 initiator had insufficient bytes to match boolean sufficientBytes = true; // ths guy has the total bytes available in the buffer final int bytesAvailable = cb.readableBytes(); for (ProtocolInitiator pi : initiators.values()) { if (pi.requiredBytes() > bytesAvailable) { sufficientBytes = false; } else { if (pi.match(cb)) { selectedInitiator = pi; break; } } } if (selectedInitiator == null) { // we did not get a match if (!sufficientBytes) { // ok, we did not have enough bytes DynamicChannelBuffer dcb = preSwitchedBuffer.get(channel); if (dcb == null) { dcb = new DynamicChannelBuffer(cb.order(), 1024, chanelBufferFactory); preSwitchedBuffer.set(channel, dcb); } dcb.writeBytes(cb); dcb.resetReaderIndex(); return null; } // darn, we have enough bytes for any of the inits, // but none matched throw new RuntimeException("Failed to match any protocol initiator"); } preSwitchedBuffer.remove(channel); // we matched on an initiator, so have it modify the pipeline selectedInitiator.modifyPipeline(ctx, channel, cb); return cb; // if we get here, it means we did not find a protocol match // so pass to the default protocol initiator. }
/** * parseErrObjList from the channel buffer. * * @param cb of type channel buffer * @throws PcepParseException if mandatory fields are missing */ public void parseErrObjList(ChannelBuffer cb) throws PcepParseException { byte yObjClass; byte yObjType; boolean bIsErrorObjFound = false; llErrObjList = new LinkedList<PcepErrorObject>(); // caller should verify for RP object if (cb.readableBytes() < OBJECT_HEADER_LENGTH) { throw new PcepParseException("Unable to find PCEP-ERROR Object"); } cb.markReaderIndex(); PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb); cb.resetReaderIndex(); yObjClass = tempObjHeader.getObjClass(); yObjType = tempObjHeader.getObjType(); PcepErrorObject errorObject; while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) { errorObject = PcepErrorObjectVer1.read(cb); llErrObjList.add(errorObject); bIsErrorObjFound = true; if (cb.readableBytes() > OBJECT_HEADER_LENGTH) { cb.markReaderIndex(); tempObjHeader = PcepObjectHeader.read(cb); cb.resetReaderIndex(); yObjClass = tempObjHeader.getObjClass(); yObjType = tempObjHeader.getObjType(); } else { break; } } if (!bIsErrorObjFound) { throw new PcepParseException("At least one PCEP-ERROR Object should be present."); } }
protected void applyDataMask(byte[] mask, ChannelBuffer data) { if (!shouldMask()) { return; } int dataLen = data.readableBytes(); data.markReaderIndex(); for (int i = 0; i < dataLen; ++i) { byte cur = data.getByte(i); cur = (byte) (cur ^ mask[i % 4]); data.setByte(i, cur); } data.resetReaderIndex(); }
@Override protected Object decode( ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer, State state) throws Exception { if (buffer.readableBytes() < 4) { return null; } buffer.markReaderIndex(); int length = buffer.readInt(); if (buffer.readableBytes() < length) { buffer.resetReaderIndex(); return null; } return parseMessage(buffer, length); }
@Test public void protocol() { double num = 4; Adddouble dut = new Adddouble(transcoder, transcoder, key, num); ChannelBuffer request = ChannelBuffers.buffer(2 + 4 + 8 + 8 + key.length); request.writeBytes(new byte[] {(byte) 0xC8, (byte) 0x61}); request.writeInt(key.length); request.writeLong(dut._integ(num)); request.writeLong(dut._fract(num)); request.writeBytes(key); ChannelBuffer actual = ChannelBuffers.buffer(request.capacity()); dut.encode(actual); assertEquals(request, actual); ChannelBuffer response = ChannelBuffers.buffer(1 + 8 + 8); assertFalse(dut.decode(response)); response.writeByte(Command.ESUCCESS); assertFalse(dut.decode(response)); response.resetReaderIndex(); response.writeLong(dut._integ(3.0 + num)); assertFalse(dut.decode(response)); response.resetReaderIndex(); response.writeLong(dut._fract(3.0 + num)); assertTrue(dut.decode(response)); assertEquals(3.0 + num, (double) dut.getReturnValue(), 0.0); // error response.clear(); response.writeByte(Command.EUNKNOWN); assertTrue(dut.decode(response)); assertEquals(Double.NaN, (double) dut.getReturnValue(), 0.0); }
@Override public boolean checkAccepts(final HttpRequest message) { if (message instanceof MappingHttpRequest) { final MappingHttpRequest httpRequest = (MappingHttpRequest) message; if (httpRequest.getMethod().equals(HttpMethod.POST)) { final Map<String, String> parameters = new HashMap<String, String>(httpRequest.getParameters()); final ChannelBuffer buffer = httpRequest.getContent(); buffer.markReaderIndex(); final byte[] read = new byte[buffer.readableBytes()]; buffer.readBytes(read); final String query = new String(read); buffer.resetReaderIndex(); for (final String p : query.split("&")) { final String[] splitParam = p.split("="); String lhs = splitParam[0]; String rhs = splitParam.length == 2 ? splitParam[1] : null; try { if (lhs != null) lhs = new URLCodec().decode(lhs); } catch (final DecoderException e) { } try { if (rhs != null) rhs = new URLCodec().decode(rhs); } catch (final DecoderException e) { } parameters.put(lhs, rhs); } for (final RequiredQueryParams p : RequiredQueryParams.values()) { if (!parameters.containsKey(p.toString())) { return false; } } httpRequest.getParameters().putAll(parameters); } else { for (final RequiredQueryParams p : RequiredQueryParams.values()) { if (!httpRequest.getParameters().containsKey(p.toString())) { return false; } } } return (message.getUri().startsWith(this.servicePath) || message.getUri().startsWith(this.internalServicePath)); } return false; }
@Override protected Object decode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { if (msg instanceof ChannelBuffer) { ChannelBuffer buffer = (ChannelBuffer) msg; buffer.markReaderIndex(); byte clientId = buffer.readByte(); byte opcode = buffer.readByte(); if (Opcode.fromByte(opcode) == Opcode.CHAT_MESSAGE) { int messageSize = buffer.readInt(); byte userId = buffer.readByte(); String message = readString(buffer); ChatMessage chatMessage = new ChatMessage(userId, message); chatMessage.setClientId((byte) clientId); return chatMessage; } buffer.resetReaderIndex(); } return msg; }
/** 解析数据包,主要负责解析数据包前8个字节统一格式的头部信息,生成Packet对象, 剩余的数据部分的解析在后面具体的action处理 */ @Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { if (buffer.readableBytes() < SysConstants.PROTOCOL_HEADER_LENGTH) { return null; } buffer.markReaderIndex(); // 标记一下 int length = buffer.readInt(); // 消息长度 char serviceId = buffer.readChar(); // 服务号, 后端这边固定1000 char commandId = buffer.readChar(); // 命令号 char version = buffer.readChar(); // 消息version, 1个字节 char reserved = buffer.readChar(); // 保留,可用户如序列号等 int contentLength = length - SysConstants.PROTOCOL_HEADER_LENGTH; // 计算数据包中业务数据部分的长度(去除头部长度16) if (buffer.readableBytes() < contentLength) { logger.info("数据长度:" + contentLength); buffer.resetReaderIndex(); // 返回到上面标记的位置 return null; } ChannelBuffer cBuffer = ChannelBuffers.buffer(contentLength); buffer.readBytes(cBuffer, contentLength); // 转移所有业务部分的数据到新的byte Packet packet = new Packet(); packet.setLength(contentLength); packet.setServiceId(serviceId); packet.setCommandId(commandId); packet.setVersion(version); packet.setReserved(reserved); DataBuffer dataBuffer = new DataBuffer(cBuffer); // 数据部分 packet.setContentBuffer(dataBuffer); // logger.info("decode packet serviceId : " + packet.getServiceId() // + " commandId: " + packet.getCommandId()); return packet; }
@Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { buffer.markReaderIndex(); byte[] buf = new byte[5]; for (int i = 0; i < 5; i++) { if (!buffer.readable()) { break; } buf[i] = buffer.readByte(); if (buf[i] >= 0) { int messageSize = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32(); if (buffer.readableBytes() < messageSize) { break; } return buffer.readBytes(messageSize); } } buffer.resetReaderIndex(); return null; }
@Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { MemcachedRestRequest request = this.request; if (request == null) { buffer.markReaderIndex(); if (buffer.readableBytes() < 1) { return null; } short magic = buffer.readUnsignedByte(); if (magic == 0x80) { if (buffer.readableBytes() < 23) return null; short opcode = buffer.readUnsignedByte(); short keyLength = buffer.readShort(); short extraLength = buffer.readUnsignedByte(); short dataType = buffer.readUnsignedByte(); // unused short reserved = buffer.readShort(); // unused int totalBodyLength = buffer.readInt(); int opaque = buffer.readInt(); long cas = buffer.readLong(); // we want the whole of totalBodyLength; otherwise, keep waiting. if (buffer.readableBytes() < totalBodyLength) { buffer.resetReaderIndex(); return null; } buffer.skipBytes(extraLength); // get extras, can be empty if (keyLength != 0) { byte[] key = new byte[keyLength]; buffer.readBytes(key); String uri = Unicode.fromBytes(key); if (opcode == 0x00) { // GET request = new MemcachedRestRequest(RestRequest.Method.GET, uri, key, -1, true); request.setOpaque(opaque); return request; } else if (opcode == 0x04) { // DELETE request = new MemcachedRestRequest(RestRequest.Method.DELETE, uri, key, -1, true); request.setOpaque(opaque); return request; } else if (opcode == 0x01) { // SET // the remainder of the message -- that is, totalLength - (keyLength + extraLength) // should be the payload int size = totalBodyLength - keyLength - extraLength; request = new MemcachedRestRequest(RestRequest.Method.POST, uri, key, size, true); request.setOpaque(opaque); byte[] data = new byte[size]; buffer.readBytes(data, 0, size); request.setData(data); return request; } } else if (opcode == 0x07) { // QUIT channel.disconnect(); } } else { buffer.resetReaderIndex(); // reset to get to the first byte // need to read a header boolean done = false; StringBuffer sb = this.sb; int readableBytes = buffer.readableBytes(); for (int i = 0; i < readableBytes; i++) { byte next = buffer.readByte(); if (next == CR) { next = buffer.readByte(); if (next == LF) { done = true; break; } } else if (next == LF) { done = true; break; } else { sb.append((char) next); } } if (!done) { buffer.resetReaderIndex(); return null; } String[] args = lineSplit.split(sb); // we read the text, clear it sb.setLength(0); String cmd = args[0]; String uri = args[1]; if ("get".equals(cmd)) { request = new MemcachedRestRequest(RestRequest.Method.GET, uri, null, -1, false); if (args.length > 3) { request.setData(Unicode.fromStringAsBytes(args[2])); } return request; } else if ("delete".equals(cmd)) { request = new MemcachedRestRequest(RestRequest.Method.DELETE, uri, null, -1, false); // if (args.length > 3) { // request.setData(Unicode.fromStringAsBytes(args[2])); // } return request; } else if ("set".equals(cmd)) { this.request = new MemcachedRestRequest( RestRequest.Method.POST, uri, null, Integer.parseInt(args[4]), false); buffer.markReaderIndex(); } else if ("quit".equals(cmd)) { channel.disconnect(); } } } else { if (buffer.readableBytes() < (request.getDataSize() + 2)) { return null; } byte[] data = new byte[request.getDataSize()]; buffer.readBytes(data, 0, data.length); byte next = buffer.readByte(); if (next == CR) { next = buffer.readByte(); if (next == LF) { request.setData(data); // reset this.request = null; return request; } else { this.request = null; throw new StreamCorruptedException("Expecting \r\n after data block"); } } else { this.request = null; throw new StreamCorruptedException("Expecting \r\n after data block"); } } return null; }
/* * Each ControlMessage is encoded as: code (<0) ... short(2) Each * TaskMessage is encoded as: task (>=0) ... short(2) len ... int(4) payload * ... byte[] * */ protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { // Make sure that we have received at least a short long available = buf.readableBytes(); // Length of control message is 10. // Minimum length of a task message is 6(short taskId, int length). if (available < 10) { // need more data return null; } Long startTime = null; if (isServer) { startTime = System.nanoTime(); } try { // Mark the current buffer position before reading task/len field // because the whole frame might not be in the buffer yet. // We will reset the buffer position to the marked position if // there's not enough bytes in the buffer. buf.markReaderIndex(); // read the short field short code = buf.readShort(); available -= 2; // case 1: Control message ControlMessage ctrl_msg = ControlMessage.mkMessage(code); if (ctrl_msg != null) { if (available < 12) { // The time stamp bytes were not received yet - return null. buf.resetReaderIndex(); return null; } long timeStamp = buf.readLong(); int clientPort = buf.readInt(); available -= 12; if (ctrl_msg == ControlMessage.EOB_MESSAGE) { long interval = System.currentTimeMillis() - timeStamp; if (interval > 0) { Histogram netTransTime = getTransmitHistogram(channel, clientPort); if (netTransTime != null) { netTransTime.update(interval); } } recvSpeed.update(Double.valueOf(ControlMessage.encodeLength())); } return ctrl_msg; } // case 2: task Message short task = code; // Make sure that we have received at least an integer (length) if (available < 8) { // need more data buf.resetReaderIndex(); return null; } // Read the length field. int length = buf.readInt(); if (length <= 0) { LOG.info("Receive one message whose TaskMessage's message length is {}", length); return new TaskMessage(task, null); } int headerLength = buf.readInt(); if (headerLength <= 0) { LOG.info("Receive one message whose TaskMessage's message header length is {}", length); } // Make sure if there's enough bytes in the buffer. available -= 8; if (available < length + headerLength) { // The whole bytes were not received yet - return null. buf.resetReaderIndex(); return null; } String component = null; String stream = null; if (headerLength > 0) { ChannelBuffer header = buf.readBytes(headerLength); String headerValue = new String(header.array()); String splits[] = headerValue.split(" "); stream = splits[0]; component = splits[1]; } // There's enough bytes in the buffer. Read it. ChannelBuffer payload = buf.readBytes(length); // Successfully decoded a frame. // Return a TaskMessage object byte[] rawBytes = payload.array(); // @@@ TESTING CODE // LOG.info("Receive task:{}, length: {}, data:{}", // task, length, JStormUtils.toPrintableString(rawBytes)); TaskMessage ret = new TaskMessage(task, rawBytes, component, stream); recvSpeed.update(Double.valueOf(rawBytes.length + 6)); return ret; } finally { if (isServer) { Long endTime = System.nanoTime(); timer.update((endTime - startTime) / 1000000.0d); } } }
/** * Ensures that at least a {@code nbytes} are readable from the given buffer. If there aren't * enough bytes in the buffer this will raise an exception and cause the {@link ReplayingDecoder} * to undo whatever we did thus far so we can wait until we read more from the socket. * * @param buf Buffer to check. * @param nbytes Number of bytes desired. */ static void ensureReadable(final ChannelBuffer buf, final int nbytes) { buf.markReaderIndex(); buf.skipBytes(nbytes); // can puke with Throwable buf.resetReaderIndex(); }