public static AddMsgLocation decode(final ByteBuffer buf) { if (!buf.hasRemaining()) { return null; } final long offset = buf.getLong(); final int length = buf.getInt(); final int checksum = buf.getInt(); final int descLen = buf.getInt(); final byte[] descBytes = new byte[descLen]; buf.get(descBytes); final String desc = ByteUtils.getString(descBytes); return new AddMsgLocation(offset, length, checksum, desc); }
/** * 消息位置序列化为: * * <ul> * <li>8个字节的offset * <li>4个字节的长度 * <li>4个字节checksum:这是指整个消息存储数据的checksum,跟message的checksum不同 * <li>4个字节长度,存储的分区名的长度 * <li>存储的分区名 * </ul> * * @return */ public ByteBuffer encode() { if (this.buf == null) { final byte[] storeDescBytes = ByteUtils.getBytes(this.storeDesc); final ByteBuffer buf = ByteBuffer.allocate(4 + 4 + 8 + 4 + this.storeDesc.length()); buf.putLong(this.getOffset()); buf.putInt(this.getLength()); buf.putInt(this.checksum); buf.putInt(storeDescBytes.length); buf.put(storeDescBytes); buf.flip(); this.buf = buf; } return this.buf; }
/** * 将消息属性和消息payload打包,结构如下:</br></br> 0或者1个定长attribute + payload * * @param message * @return */ public static final byte[] encodePayload(final Message message) { final byte[] payload = message.getData(); final String attribute = message.getAttribute(); byte[] attrData = null; if (attribute != null) { attrData = ByteUtils.getBytes(attribute); } else { return payload; } final int attrLen = attrData == null ? 0 : attrData.length; final ByteBuffer buffer = ByteBuffer.allocate(4 + attrLen + payload.length); if (attribute != null) { buffer.putInt(attrLen); if (attrData != null) { buffer.put(attrData); } } buffer.put(payload); return buffer.array(); }
/** * 从binary数据中解出消息 * * @param topic * @param data * @param offset * @return * @throws InvalidMessageException */ public static final DecodedMessage decodeMessage( final String topic, final byte[] data, final int offset) throws InvalidMessageException { final ByteBuffer buf = ByteBuffer.wrap(data, offset, HEADER_LEN); final int msgLen = buf.getInt(); final int checksum = buf.getInt(); vailidateMessage(offset + HEADER_LEN, msgLen, checksum, data); final long id = buf.getLong(); // 取flag final int flag = buf.getInt(); String attribute = null; int payLoadOffset = offset + HEADER_LEN; int payLoadLen = msgLen; if (payLoadLen > MAX_READ_BUFFER_SIZE) { throw new InvalidMessageException("Too much long payload length:" + payLoadLen); } // 如果有属性,需要解析属性 if (MessageFlagUtils.hasAttribute(flag)) { // 取4个字节的属性长度 final int attrLen = getInt(offset + HEADER_LEN, data); // 取消息属性 final byte[] attrData = new byte[attrLen]; System.arraycopy(data, offset + HEADER_LEN + 4, attrData, 0, attrLen); attribute = ByteUtils.getString(attrData); // 递增payloadOffset,加上4个字节的消息长度和消息长度本身 payLoadOffset = offset + HEADER_LEN + 4 + attrLen; // payload长度递减,减去4个字节的消息长度和消息长度本身 payLoadLen = msgLen - 4 - attrLen; } // 获取payload final byte[] payload = new byte[payLoadLen]; System.arraycopy(data, payLoadOffset, payload, 0, payLoadLen); final Message msg = new Message(topic, payload); MessageAccessor.setFlag(msg, flag); msg.setAttribute(attribute); MessageAccessor.setId(msg, id); return new DecodedMessage( payLoadOffset + payLoadLen, msg, ByteBuffer.wrap(data, offset, payLoadOffset + payLoadLen - offset)); }