Improved usability of PingFrame.

This commit is contained in:
Simone Bordet 2015-09-27 17:03:29 +02:00
parent 83c5105e71
commit 64ba5a6ef8
3 changed files with 97 additions and 3 deletions

View File

@ -18,15 +18,49 @@
package org.eclipse.jetty.http2.frames;
import java.util.Objects;
public class PingFrame extends Frame
{
public static final int PING_LENGTH = 8;
private static final byte[] EMPTY_PAYLOAD = new byte[8];
private final byte[] payload;
private final boolean reply;
/**
* Creates a PING frame with an empty payload.
*
* @param reply whether this PING frame is a reply
*/
public PingFrame(boolean reply)
{
this(EMPTY_PAYLOAD, reply);
}
/**
* Creates a PING frame with the given {@code long} {@code value} as payload.
*
* @param value the value to use as a payload for this PING frame
* @param reply whether this PING frame is a reply
*/
public PingFrame(long value, boolean reply)
{
this(toBytes(value), reply);
}
/**
* Creates a PING frame with the given {@code payload}.
*
* @param payload the payload for this PING frame
* @param reply whether this PING frame is a reply
*/
public PingFrame(byte[] payload, boolean reply)
{
super(FrameType.PING);
this.payload = payload;
this.payload = Objects.requireNonNull(payload);
if (payload.length != PING_LENGTH)
throw new IllegalArgumentException("PING payload must be 8 bytes");
this.reply = reply;
}
@ -35,8 +69,35 @@ public class PingFrame extends Frame
return payload;
}
public long getPayloadAsLong()
{
return toLong(payload);
}
public boolean isReply()
{
return reply;
}
private static byte[] toBytes(long value)
{
byte[] result = new byte[8];
for (int i = result.length - 1; i >= 0; --i)
{
result[i] = (byte)(value & 0xFF);
value >>= 8;
}
return result;
}
private static long toLong(byte[] payload)
{
long result = 0;
for (int i = 0; i < 8; ++i)
{
result <<= 8;
result |= (payload[i] & 0xFF);
}
return result;
}
}

View File

@ -43,10 +43,10 @@ public class PingGenerator extends FrameGenerator
public void generatePing(ByteBufferPool.Lease lease, byte[] payload, boolean reply)
{
if (payload.length != 8)
if (payload.length != PingFrame.PING_LENGTH)
throw new IllegalArgumentException("Invalid payload length: " + payload.length);
ByteBuffer header = generateHeader(lease, FrameType.PING, 8, reply ? Flags.ACK : Flags.NONE, 0);
ByteBuffer header = generateHeader(lease, FrameType.PING, PingFrame.PING_LENGTH, reply ? Flags.ACK : Flags.NONE, 0);
header.put(payload);

View File

@ -109,4 +109,37 @@ public class PingGenerateParseTest
Assert.assertArrayEquals(payload, frame.getPayload());
Assert.assertTrue(frame.isReply());
}
@Test
public void testPayloadAsLong() throws Exception
{
PingGenerator generator = new PingGenerator(new HeaderGenerator());
final List<PingFrame> frames = new ArrayList<>();
Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPing(PingFrame frame)
{
frames.add(frame);
}
}, 4096, 8192);
ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
PingFrame ping = new PingFrame(System.nanoTime(), true);
generator.generate(lease, ping);
for (ByteBuffer buffer : lease.getByteBuffers())
{
while (buffer.hasRemaining())
{
parser.parse(buffer);
}
}
Assert.assertEquals(1, frames.size());
PingFrame pong = frames.get(0);
Assert.assertEquals(ping.getPayloadAsLong(), pong.getPayloadAsLong());
Assert.assertTrue(pong.isReply());
}
}