@Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buf) throws Exception { char marker = (char) buf.getByte(buf.readerIndex()); while (marker != '*' && marker != '$' && buf.readableBytes() > 0) { buf.skipBytes(1); if (buf.readableBytes() > 0) { marker = (char) buf.getByte(buf.readerIndex()); } } if (marker == '*') { // Return text message int index = buf.indexOf(buf.readerIndex(), buf.writerIndex(), (byte) '#'); if (index != -1) { return buf.readBytes(index + 1 - buf.readerIndex()); } } else if (marker == '$' && buf.readableBytes() >= MESSAGE_LENGTH) { // Return binary message return buf.readBytes(MESSAGE_LENGTH); } return null; }
@Override public Bitmap call(sensor_msgs.Image message) { Preconditions.checkArgument(message.getEncoding().equals("rgb8")); Bitmap bitmap = Bitmap.createBitmap( (int) message.getWidth(), (int) message.getHeight(), Bitmap.Config.ARGB_8888); for (int x = 0; x < message.getWidth(); x++) { for (int y = 0; y < message.getHeight(); y++) { ChannelBuffer data = message.getData(); byte red = data.getByte((int) (y * message.getStep() + 3 * x)); byte green = data.getByte((int) (y * message.getStep() + 3 * x + 1)); byte blue = data.getByte((int) (y * message.getStep() + 3 * x + 2)); bitmap.setPixel(x, y, Color.argb(255, red & 0xFF, green & 0xFF, blue & 0xFF)); } } return bitmap; }
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(); }
public static String format(ChannelBuffer observed) { if (!observed.readable()) { return "[]"; } else { StringBuilder sb = new StringBuilder(); sb.append("["); for (int readerIndex = observed.readerIndex(); readerIndex < observed.writerIndex(); readerIndex++) { sb.append(String.format("0x%02x ", observed.getByte(readerIndex))); } sb.setCharAt(sb.length() - 1, ']'); return sb.toString(); } }
@Override protected Object decode(Channel channel, SocketAddress remoteAddress, Object msg) throws Exception { ChannelBuffer buf = (ChannelBuffer) msg; char first = (char) buf.getByte(0); if (first == '$') { return decodeNormalMessage(buf, channel, remoteAddress); } else if (first == '(') { return decodeAlertMessage(buf, channel, remoteAddress); } return null; }
@Override protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { if (!(msg instanceof ChannelBuffer)) return msg; if (!enabled) return msg; final ChannelBuffer buffer = (ChannelBuffer) msg; final int offset = buffer.readerIndex() + 2; // skip header final int size = buffer.readableBytes() - 2; int temp = 0, temp2 = 0; synchronized (key) { for (int i = 0; i < size; i++) { temp2 = buffer.getByte(offset + i) & 0xFF; temp = temp2 ^ key.get(i) ^ temp; buffer.setByte(offset + i, (byte) temp); } key.update(size); } return msg; }
private void sendReply(Channel channel, long deviceId, byte packetNumber) { ChannelBuffer reply = ChannelBuffers.directBuffer(ByteOrder.LITTLE_ENDIAN, 28); reply.writeByte('M'); reply.writeByte('C'); reply.writeByte('G'); reply.writeByte('P'); reply.writeByte(MSG_SERVER_ACKNOWLEDGE); reply.writeInt((int) deviceId); reply.writeByte(commandCount++); reply.writeInt(0); // authentication code reply.writeByte(0); reply.writeByte(packetNumber); reply.writeZero(11); byte checksum = 0; for (int i = 4; i < 27; i++) { checksum += reply.getByte(i); } reply.writeByte(checksum); if (channel != null) { channel.write(reply); } }
@Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { Object m = e.getMessage(); if (!(m instanceof ChannelBuffer)) { ctx.sendUpstream(e); return; } ChannelBuffer buffer = (ChannelBuffer) m; int size = buffer.getInt(buffer.readerIndex() - 4); transportServiceAdapter.received(size + 6); // we have additional bytes to read, outside of the header boolean hasMessageBytesToRead = (size - (NettyHeader.HEADER_SIZE - 6)) != 0; int markedReaderIndex = buffer.readerIndex(); int expectedIndexReader = markedReaderIndex + size; // netty always copies a buffer, either in NioWorker in its read handler, where it copies to a // fresh // buffer, or in the cumlation buffer, which is cleaned each time StreamInput streamIn = ChannelBufferStreamInputFactory.create(buffer, size); long requestId = buffer.readLong(); byte status = buffer.readByte(); Version version = Version.fromId(buffer.readInt()); StreamInput wrappedStream; if (TransportStatus.isCompress(status) && hasMessageBytesToRead && buffer.readable()) { Compressor compressor = CompressorFactory.compressor(buffer); if (compressor == null) { int maxToRead = Math.min(buffer.readableBytes(), 10); int offset = buffer.readerIndex(); StringBuilder sb = new StringBuilder("stream marked as compressed, but no compressor found, first [") .append(maxToRead) .append("] content bytes out of [") .append(buffer.readableBytes()) .append("] readable bytes with message size [") .append(size) .append("] ") .append("] are ["); for (int i = 0; i < maxToRead; i++) { sb.append(buffer.getByte(offset + i)).append(","); } sb.append("]"); throw new ElasticsearchIllegalStateException(sb.toString()); } wrappedStream = CachedStreamInput.cachedHandlesCompressed(compressor, streamIn); } else { wrappedStream = CachedStreamInput.cachedHandles(streamIn); } wrappedStream.setVersion(version); if (TransportStatus.isRequest(status)) { String action = handleRequest(ctx.getChannel(), wrappedStream, requestId, version); if (buffer.readerIndex() != expectedIndexReader) { if (buffer.readerIndex() < expectedIndexReader) { logger.warn( "Message not fully read (request) for [{}] and action [{}], resetting", requestId, action); } else { logger.warn( "Message read past expected size (request) for [{}] and action [{}], resetting", requestId, action); } buffer.readerIndex(expectedIndexReader); } } else { TransportResponseHandler handler = transportServiceAdapter.remove(requestId); // ignore if its null, the adapter logs it if (handler != null) { if (TransportStatus.isError(status)) { handlerResponseError(wrappedStream, handler); } else { handleResponse(ctx.getChannel(), wrappedStream, handler); } } else { // if its null, skip those bytes buffer.readerIndex(markedReaderIndex + size); } if (buffer.readerIndex() != expectedIndexReader) { if (buffer.readerIndex() < expectedIndexReader) { logger.warn( "Message not fully read (response) for [{}] handler {}, error [{}], resetting", requestId, handler, TransportStatus.isError(status)); } else { logger.warn( "Message read past expected size (response) for [{}] handler {}, error [{}], resetting", requestId, handler, TransportStatus.isError(status)); } buffer.readerIndex(expectedIndexReader); } } wrappedStream.close(); }
/** * Reads a big-endian short integer from the buffer. Please note that we do not use {@link * ChannelBuffer#getShort(int)} because it might be a little-endian buffer. */ private static short getShort(ChannelBuffer buf, int offset) { return (short) (buf.getByte(offset) << 8 | buf.getByte(offset + 1) & 0xFF); }