/** * Puts {@code numBits} into the buffer with the value {@code value}. * * @param numBits The number of bits to put into the buffer. * @param value The value. * @throws IllegalStateException if the builder is not in bit access mode. * @throws IllegalArgumentException if the number of bits is not between 1 and 31 inclusive. */ public void putBits(int numBits, int value) { if (numBits <= 0 || numBits > 32) { throw new IllegalArgumentException("Number of bits must be between 1 and 31 inclusive"); } checkBitAccess(); int bytePos = bitIndex >> 3; int bitOffset = 8 - (bitIndex & 7); bitIndex += numBits; int requiredSpace = bytePos - buffer.writerIndex() + 1; requiredSpace += (numBits + 7) / 8; buffer.ensureWritable(requiredSpace); for (; numBits > bitOffset; bitOffset = 8) { int tmp = buffer.getByte(bytePos); tmp &= ~BITMASKS[bitOffset]; tmp |= (value >> (numBits - bitOffset)) & BITMASKS[bitOffset]; buffer.setByte(bytePos++, tmp); numBits -= bitOffset; } if (numBits == bitOffset) { int tmp = buffer.getByte(bytePos); tmp &= ~BITMASKS[bitOffset]; tmp |= value & BITMASKS[bitOffset]; buffer.setByte(bytePos, tmp); } else { int tmp = buffer.getByte(bytePos); tmp &= ~(BITMASKS[numBits] << (bitOffset - numBits)); tmp |= (value & BITMASKS[numBits]) << (bitOffset - numBits); buffer.setByte(bytePos, tmp); } }
private static boolean isValueFound(ByteBuf buffer, int index, ByteBuf search) { for (int i = 0; i < search.readableBytes(); i++) { if (buffer.getByte(index + i) != search.getByte(i)) { return false; } } return true; }
public static int stringLeftMatchUTF8( ByteBuf str, int strStart, int strEnd, ByteBuf substr, int subStart, int subEnd) { for (int i = strStart; i <= strEnd - (subEnd - subStart); i++) { int j = subStart; for (; j < subEnd; j++) { if (str.getByte(i + j - subStart) != substr.getByte(j)) break; } if (j == subEnd && j != subStart) { // found a matched substr (non-empty) in str. return i; // found a match. } } return -1; }
public boolean hasError() { if (response == null) return false; if (response.getByte(0) == Coder.ERROR_ID) return true; return false; }
private void checkPrintableAscii(final ByteBuf buffer) { final ByteBuf tmpBuffer = buffer.slice(); final int lowerBound = tmpBuffer.readerIndex(); final int upperBound = tmpBuffer.writerIndex(); for (int idx = lowerBound; idx < upperBound; ++idx) { checkPrintableAscii(tmpBuffer.getByte(idx)); } }
/** * In-place parsing of a hex encoded binary string. * * <p>This function does not modify the {@code readerIndex} and {@code writerIndex} of the byte * buffer. * * @return Index in the byte buffer just after the last written byte. */ public static int parseBinaryString(ByteBuf str, int strStart, int strEnd) { int length = (strEnd - strStart); int dstEnd = strStart; for (int i = strStart; i < length; i++) { byte b = str.getByte(i); if (b == '\\' && length > i + 3 && (str.getByte(i + 1) == 'x' || str.getByte(i + 1) == 'X')) { // ok, take next 2 hex digits. byte hd1 = str.getByte(i + 2); byte hd2 = str.getByte(i + 3); if (isHexDigit(hd1) && isHexDigit(hd2)) { // [a-fA-F0-9] // turn hex ASCII digit -> number b = (byte) ((toBinaryFromHex(hd1) << 4) + toBinaryFromHex(hd2)); i += 3; // skip 3 } } str.setByte(dstEnd++, b); } return dstEnd; }
private SpdyHeadersFrame readHeaderBlockFrame(ByteBuf buffer) { int streamId; switch (type) { case SPDY_SYN_STREAM_FRAME: if (buffer.readableBytes() < 10) { return null; } int offset = buffer.readerIndex(); streamId = getUnsignedInt(buffer, offset); int associatedToStreamId = getUnsignedInt(buffer, offset + 4); byte priority = (byte) (buffer.getByte(offset + 8) >> 5 & 0x07); buffer.skipBytes(10); length -= 10; SpdySynStreamFrame spdySynStreamFrame = new DefaultSpdySynStreamFrame(streamId, associatedToStreamId, priority); spdySynStreamFrame.setLast((flags & SPDY_FLAG_FIN) != 0); spdySynStreamFrame.setUnidirectional((flags & SPDY_FLAG_UNIDIRECTIONAL) != 0); return spdySynStreamFrame; case SPDY_SYN_REPLY_FRAME: if (buffer.readableBytes() < 4) { return null; } streamId = getUnsignedInt(buffer, buffer.readerIndex()); buffer.skipBytes(4); length -= 4; SpdySynReplyFrame spdySynReplyFrame = new DefaultSpdySynReplyFrame(streamId); spdySynReplyFrame.setLast((flags & SPDY_FLAG_FIN) != 0); return spdySynReplyFrame; case SPDY_HEADERS_FRAME: if (buffer.readableBytes() < 4) { return null; } streamId = getUnsignedInt(buffer, buffer.readerIndex()); buffer.skipBytes(4); length -= 4; SpdyHeadersFrame spdyHeadersFrame = new DefaultSpdyHeadersFrame(streamId); spdyHeadersFrame.setLast((flags & SPDY_FLAG_FIN) != 0); return spdyHeadersFrame; default: throw new Error("Shouldn't reach here."); } }
@Override protected void encode(ChannelHandlerContext ctx, MessageBuilder msg, ByteBuf out) throws Exception { // Generate a new encryption key using ISAAC, encode the message and // write it to the client. ByteBuf internal = msg.buffer(); int value = internal.getByte(0) + encryptor.getKey(); internal.setByte(0, value); out.writeBytes(internal); }
@Override protected Object decodeLast(ChannelHandlerContext ctx, ByteBuf buffer) throws Exception { switch (buffer.readableBytes()) { case 0: return null; case 1: // Ignore the last TC_RESET if (buffer.getByte(buffer.readerIndex()) == ObjectStreamConstants.TC_RESET) { buffer.skipBytes(1); return null; } } return decode(ctx, buffer); }
/** * Return a printable representation of a byte buffer, escaping the non-printable bytes as '\\xNN' * where NN is the hexadecimal representation of such bytes. * * <p>This function does not modify the {@code readerIndex} and {@code writerIndex} of the byte * buffer. */ public static String toBinaryString(ByteBuf buf, int strStart, int strEnd) { StringBuilder result = new StringBuilder(); for (int i = strStart; i < strEnd; ++i) { int ch = buf.getByte(i) & 0xFF; if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || " `~!@#$%^&*()-_=+[]{}|;:'\",.<>/?".indexOf(ch) >= 0) { result.append((char) ch); } else { result.append(String.format("\\x%02X", ch)); } } return result.toString(); }
/** * Peeks at that the next frame in the buffer and verifies that it is a {@code SETTINGS} frame. * * @param in the inbound buffer. * @return {@code} true if the next frame is a {@code SETTINGS} frame, {@code false} if more * data is required before we can determine the next frame type. * @throws Http2Exception thrown if the next frame is NOT a {@code SETTINGS} frame. */ private boolean verifyFirstFrameIsSettings(ByteBuf in) throws Http2Exception { if (in.readableBytes() < 4) { // Need more data before we can see the frame type for the first frame. return false; } byte frameType = in.getByte(in.readerIndex() + 3); if (frameType != SETTINGS) { throw connectionError( PROTOCOL_ERROR, "First received frame was not SETTINGS. " + "Hex dump for first 4 bytes: %s", hexDump(in, in.readerIndex(), 4)); } return true; }
@Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // byte[] byte_buf = new byte[1024]; // ((ByteBuf)msg).getBytes(0, byte_buf); // for(int i = 0; i < byte_buf.length; i++) // System.out.printf("%X ", byte_buf[i]); // System.out.println(); // ctx.write(msg); ByteBuf byteBuf = (ByteBuf) msg; for (int i = 0; i < byteBuf.readableBytes(); i++) { System.out.printf("%X ", byteBuf.getByte(i)); } System.out.println(); }
private static int utf8CharLen(ByteBuf buffer, int idx) { byte firstByte = buffer.getByte(idx); if (firstByte >= 0) { // 1-byte char. First byte is 0xxxxxxx. return 1; } else if ((firstByte & 0xE0) == 0xC0) { // 2-byte char. First byte is 110xxxxx return 2; } else if ((firstByte & 0xF0) == 0xE0) { // 3-byte char. First byte is 1110xxxx return 3; } else if ((firstByte & 0xF8) == 0xF0) { // 4-byte char. First byte is 11110xxx return 4; } throw new DrillRuntimeException( "Unexpected byte 0x" + Integer.toString((int) firstByte & 0xff, 16) + " at position " + idx + " encountered while decoding UTF8 string."); }
@Override public byte getByte(int var1) { return a.getByte(var1); }
private void unmask(ByteBuf frame) { for (int i = frame.readerIndex(); i < frame.writerIndex(); i++) { frame.setByte(i, frame.getByte(i) ^ maskingKey.getByte(i % 4)); } }
private State readCommonHeader(ByteBuf buffer) { // Wait until entire header is readable if (buffer.readableBytes() < SPDY_HEADER_SIZE) { return State.READ_COMMON_HEADER; } int frameOffset = buffer.readerIndex(); int flagsOffset = frameOffset + SPDY_HEADER_FLAGS_OFFSET; int lengthOffset = frameOffset + SPDY_HEADER_LENGTH_OFFSET; buffer.skipBytes(SPDY_HEADER_SIZE); // Read common header fields boolean control = (buffer.getByte(frameOffset) & 0x80) != 0; flags = buffer.getByte(flagsOffset); length = getUnsignedMedium(buffer, lengthOffset); if (control) { // Decode control frame common header version = getUnsignedShort(buffer, frameOffset) & 0x7FFF; int typeOffset = frameOffset + SPDY_HEADER_TYPE_OFFSET; type = getUnsignedShort(buffer, typeOffset); streamId = 0; } else { // Decode data frame common header version = spdyVersion; // Default to expected version type = SPDY_DATA_FRAME; streamId = getUnsignedInt(buffer, frameOffset); } // Check version first then validity if (version != spdyVersion || !isValidFrameHeader()) { return State.FRAME_ERROR; } // Make sure decoder will produce a frame or consume input State nextState; if (willGenerateFrame()) { switch (type) { case SPDY_DATA_FRAME: nextState = State.READ_DATA_FRAME; break; case SPDY_SYN_STREAM_FRAME: case SPDY_SYN_REPLY_FRAME: case SPDY_HEADERS_FRAME: nextState = State.READ_HEADER_BLOCK_FRAME; break; case SPDY_SETTINGS_FRAME: nextState = State.READ_SETTINGS_FRAME; break; default: nextState = State.READ_CONTROL_FRAME; } } else if (length != 0) { nextState = State.DISCARD_FRAME; } else { nextState = State.READ_COMMON_HEADER; } return nextState; }
@Override protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception { switch (state) { case READ_COMMON_HEADER: state = readCommonHeader(buffer); if (state == State.FRAME_ERROR) { if (version != spdyVersion) { fireProtocolException(ctx, "Unsupported version: " + version); } else { fireInvalidFrameException(ctx); } } // FrameDecoders must consume data when producing frames // All length 0 frames must be generated now if (length == 0) { if (state == State.READ_DATA_FRAME) { SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(streamId); spdyDataFrame.setLast((flags & SPDY_DATA_FLAG_FIN) != 0); state = State.READ_COMMON_HEADER; out.add(spdyDataFrame); return; } // There are no length 0 control frames state = State.READ_COMMON_HEADER; } return; case READ_CONTROL_FRAME: try { Object frame = readControlFrame(buffer); if (frame != null) { state = State.READ_COMMON_HEADER; out.add(frame); } return; } catch (IllegalArgumentException e) { state = State.FRAME_ERROR; fireInvalidFrameException(ctx); } return; case READ_SETTINGS_FRAME: if (spdySettingsFrame == null) { // Validate frame length against number of entries if (buffer.readableBytes() < 4) { return; } int numEntries = getUnsignedInt(buffer, buffer.readerIndex()); buffer.skipBytes(4); length -= 4; // Each ID/Value entry is 8 bytes if ((length & 0x07) != 0 || length >> 3 != numEntries) { state = State.FRAME_ERROR; fireInvalidFrameException(ctx); return; } spdySettingsFrame = new DefaultSpdySettingsFrame(); boolean clear = (flags & SPDY_SETTINGS_CLEAR) != 0; spdySettingsFrame.setClearPreviouslyPersistedSettings(clear); } int readableEntries = Math.min(buffer.readableBytes() >> 3, length >> 3); for (int i = 0; i < readableEntries; i++) { byte ID_flags = buffer.getByte(buffer.readerIndex()); int ID = getUnsignedMedium(buffer, buffer.readerIndex() + 1); int value = getSignedInt(buffer, buffer.readerIndex() + 4); buffer.skipBytes(8); if (!spdySettingsFrame.isSet(ID)) { boolean persistVal = (ID_flags & SPDY_SETTINGS_PERSIST_VALUE) != 0; boolean persisted = (ID_flags & SPDY_SETTINGS_PERSISTED) != 0; spdySettingsFrame.setValue(ID, value, persistVal, persisted); } } length -= 8 * readableEntries; if (length == 0) { state = State.READ_COMMON_HEADER; Object frame = spdySettingsFrame; spdySettingsFrame = null; out.add(frame); return; } return; case READ_HEADER_BLOCK_FRAME: try { spdyHeadersFrame = readHeaderBlockFrame(buffer); if (spdyHeadersFrame != null) { if (length == 0) { state = State.READ_COMMON_HEADER; Object frame = spdyHeadersFrame; spdyHeadersFrame = null; out.add(frame); return; } state = State.READ_HEADER_BLOCK; } return; } catch (IllegalArgumentException e) { state = State.FRAME_ERROR; fireInvalidFrameException(ctx); return; } case READ_HEADER_BLOCK: int compressedBytes = Math.min(buffer.readableBytes(), length); ByteBuf compressed = buffer.slice(buffer.readerIndex(), compressedBytes); try { headerBlockDecoder.decode(compressed, spdyHeadersFrame); } catch (Exception e) { state = State.FRAME_ERROR; spdyHeadersFrame = null; ctx.fireExceptionCaught(e); return; } int readBytes = compressedBytes - compressed.readableBytes(); buffer.skipBytes(readBytes); length -= readBytes; if (spdyHeadersFrame != null && (spdyHeadersFrame.isInvalid() || spdyHeadersFrame.isTruncated())) { Object frame = spdyHeadersFrame; spdyHeadersFrame = null; if (length == 0) { headerBlockDecoder.reset(); state = State.READ_COMMON_HEADER; } out.add(frame); return; } if (length == 0) { Object frame = spdyHeadersFrame; spdyHeadersFrame = null; headerBlockDecoder.reset(); state = State.READ_COMMON_HEADER; if (frame != null) { out.add(frame); } } return; case READ_DATA_FRAME: if (streamId == 0) { state = State.FRAME_ERROR; fireProtocolException(ctx, "Received invalid data frame"); return; } // Generate data frames that do not exceed maxChunkSize int dataLength = Math.min(maxChunkSize, length); // Wait until entire frame is readable if (buffer.readableBytes() < dataLength) { return; } ByteBuf data = ctx.alloc().buffer(dataLength); data.writeBytes(buffer, dataLength); SpdyDataFrame spdyDataFrame = new DefaultSpdyDataFrame(streamId, data); length -= dataLength; if (length == 0) { spdyDataFrame.setLast((flags & SPDY_DATA_FLAG_FIN) != 0); state = State.READ_COMMON_HEADER; } out.add(spdyDataFrame); return; case DISCARD_FRAME: int numBytes = Math.min(buffer.readableBytes(), length); buffer.skipBytes(numBytes); length -= numBytes; if (length == 0) { state = State.READ_COMMON_HEADER; } return; case FRAME_ERROR: buffer.skipBytes(buffer.readableBytes()); return; default: throw new Error("Shouldn't reach here."); } }
/** * Returns the {@code byte} at position {@code pos} in the Buffer. * * @throws IndexOutOfBoundsException if the specified {@code pos} is less than {@code 0} or {@code * pos + 1} is greater than the length of the Buffer. */ public byte getByte(int pos) { return buffer.getByte(pos); }
@Override public byte getByte(int index) { return buf.getByte(index); }
/** * Reads a big-endian short integer from the buffer. Please note that we do not use {@link * ByteBuf#getShort(int)} because it might be a little-endian buffer. */ private static short getShort(ByteBuf buf, int offset) { return (short) (buf.getByte(offset) << 8 | buf.getByte(offset + 1) & 0xFF); }