/** * Parses custom packet serialized by hessian marshaller. * * @param ses Session. * @param buf Buffer containing not parsed bytes. * @param state Parser state. * @return Parsed message. * @throws IOException If packet parsing or deserialization failed. */ @Nullable private GridClientMessage parseCustomPacket(GridNioSession ses, ByteBuffer buf, ParserState state) throws IOException { assert state.packetType() == PacketType.GRIDGAIN; assert state.packet() == null; ByteArrayOutputStream tmp = state.buffer(); int len = state.index(); while (buf.remaining() > 0) { byte b = buf.get(); if (len == 0) { tmp.write(b); if (tmp.size() == 4) { len = U.bytesToInt(tmp.toByteArray(), 0); tmp.reset(); if (len == 0) return PING_MESSAGE; else if (len < 0) throw new IOException( "Failed to parse incoming packet (invalid packet length) [ses=" + ses + ", len=" + len + ']'); state.index(len); } } else { tmp.write(b); if (tmp.size() == len) return marshaller.unmarshal(tmp.toByteArray()); } } return null; }
/** {@inheritDoc} */ @Override public ByteBuffer encode(GridNioSession ses, GridClientMessage msg) throws IOException, GridException { assert msg != null; if (msg instanceof GridTcpRestPacket) return encodeMemcache((GridTcpRestPacket) msg); else if (msg == PING_MESSAGE) return ByteBuffer.wrap(PING_PACKET); else { byte[] data = marshaller.marshal(msg); assert data.length > 0; ByteBuffer res = ByteBuffer.allocate(data.length + 5); res.put(GRIDGAIN_REQ_FLAG); res.put(U.intToBytes(data.length)); res.put(data); res.flip(); return res; } }
/** {@inheritDoc} */ public String toString() { return S.toString( GridTcpRestParser.class, this, "clientMarshaller", marshaller.getClass().getSimpleName()); }