From ef3540707fa04b116df51dffa84106e7b09c2876 Mon Sep 17 00:00:00 2001 From: Naoyuki Kanezawa Date: Sun, 1 Jun 2014 22:25:31 +0900 Subject: [PATCH] compatible with socket.io-parser 2.2.0, and supports protocol v4 --- pom.xml | 2 +- .../github/nkzawa/socketio/parser/Binary.java | 16 +- .../github/nkzawa/socketio/parser/Parser.java | 16 +- .../nkzawa/socketio/parser/ByteArrayTest.java | 104 +++++++++++++ .../nkzawa/socketio/parser/Helpers.java | 76 ++++++++++ .../nkzawa/socketio/parser/ParserTest.java | 140 +----------------- src/test/resources/package.json | 2 +- 7 files changed, 207 insertions(+), 149 deletions(-) create mode 100644 src/test/java/com/github/nkzawa/socketio/parser/ByteArrayTest.java create mode 100644 src/test/java/com/github/nkzawa/socketio/parser/Helpers.java diff --git a/pom.xml b/pom.xml index a90dbdb..bacc4d6 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ com.github.nkzawa engine.io-client - 0.2.0 + 0.2.1-SNAPSHOT org.json diff --git a/src/main/java/com/github/nkzawa/socketio/parser/Binary.java b/src/main/java/com/github/nkzawa/socketio/parser/Binary.java index 3be23f7..c5c677a 100644 --- a/src/main/java/com/github/nkzawa/socketio/parser/Binary.java +++ b/src/main/java/com/github/nkzawa/socketio/parser/Binary.java @@ -17,7 +17,7 @@ public class Binary { public static DeconstructedPacket deconstructPacket(Packet packet) { List buffers = new ArrayList(); - packet.data = deconstructBinPackRecursive(packet.data, buffers); + packet.data = _deconstructPacket(packet.data, buffers); packet.attachments = buffers.size(); DeconstructedPacket result = new DeconstructedPacket(); @@ -26,7 +26,7 @@ public class Binary { return result; } - private static Object deconstructBinPackRecursive(Object data, List buffers) { + private static Object _deconstructPacket(Object data, List buffers) { if (data == null) return null; if (data instanceof byte[]) { @@ -40,7 +40,7 @@ public class Binary { JSONArray _data = (JSONArray)data; int len = _data.length(); for (int i = 0; i < len; i ++) { - newData.put(i, deconstructBinPackRecursive(_data.get(i), buffers)); + newData.put(i, _deconstructPacket(_data.get(i), buffers)); } return newData; } else if (data instanceof JSONObject) { @@ -49,7 +49,7 @@ public class Binary { Iterator iterator = _data.keys(); while (iterator.hasNext()) { String key = (String)iterator.next(); - newData.put(key, deconstructBinPackRecursive(_data.get(key), buffers)); + newData.put(key, _deconstructPacket(_data.get(key), buffers)); } return newData; } @@ -57,17 +57,17 @@ public class Binary { } public static Packet reconstructPacket(Packet packet, byte[][] buffers) { - packet.data = reconstructBinPackRecursive(packet.data, buffers); + packet.data = _reconstructPacket(packet.data, buffers); packet.attachments = -1; return packet; } - private static Object reconstructBinPackRecursive(Object data, byte[][] buffers) { + private static Object _reconstructPacket(Object data, byte[][] buffers) { if (data instanceof JSONArray) { JSONArray _data = (JSONArray)data; int len = _data.length(); for (int i = 0; i < len; i ++) { - _data.put(i, reconstructBinPackRecursive(_data.get(i), buffers)); + _data.put(i, _reconstructPacket(_data.get(i), buffers)); } return _data; } else if (data instanceof JSONObject) { @@ -79,7 +79,7 @@ public class Binary { Iterator iterator = _data.keys(); while (iterator.hasNext()) { String key = (String)iterator.next(); - _data.put(key, reconstructBinPackRecursive(_data.get(key), buffers)); + _data.put(key, _reconstructPacket(_data.get(key), buffers)); } return _data; } diff --git a/src/main/java/com/github/nkzawa/socketio/parser/Parser.java b/src/main/java/com/github/nkzawa/socketio/parser/Parser.java index 4a17ac0..1305dc9 100644 --- a/src/main/java/com/github/nkzawa/socketio/parser/Parser.java +++ b/src/main/java/com/github/nkzawa/socketio/parser/Parser.java @@ -43,7 +43,12 @@ public class Parser { */ public static final int BINARY_EVENT = 5; - public static int protocol = 3; + /** + * Packet type `binary ack`. + */ + public static final int BINARY_ACK = 6; + + public static int protocol = 4; /** * Packet types. @@ -54,6 +59,7 @@ public class Parser { "EVENT", "BINARY_EVENT", "ACK", + "BINARY_ACK", "ERROR", }; @@ -72,7 +78,7 @@ public class Parser { public void encode(Packet obj, Callback callback) { logger.fine(String.format("encoding packet %s", obj)); - if (BINARY_EVENT == obj.type || ACK == obj.type) { + if (BINARY_EVENT == obj.type || BINARY_ACK == obj.type) { encodeAsBinary(obj, callback); } else { String encoding = encodeAsString(obj); @@ -86,7 +92,7 @@ public class Parser { str.append(obj.type); - if (BINARY_EVENT == obj.type || ACK == obj.type) { + if (BINARY_EVENT == obj.type || BINARY_ACK == obj.type) { str.append(obj.attachments); str.append("-"); } @@ -140,7 +146,7 @@ public class Parser { public void add(String obj) { Packet packet = decodeString(obj); - if (BINARY_EVENT == packet.type || ACK == packet.type) { + if (BINARY_EVENT == packet.type || BINARY_ACK == packet.type) { this.reconstructor = new BinaryReconstructor(packet); if (this.reconstructor.reconPack.attachments == 0) { @@ -170,7 +176,7 @@ public class Parser { p.type = Character.getNumericValue(str.charAt(0)); if (p.type < 0 || p.type > types.length - 1) return error(); - if (BINARY_EVENT == p.type || ACK == p.type) { + if (BINARY_EVENT == p.type || BINARY_ACK == p.type) { StringBuilder attachments = new StringBuilder(); while (str.charAt(++i) != '-') { attachments.append(str.charAt(i)); diff --git a/src/test/java/com/github/nkzawa/socketio/parser/ByteArrayTest.java b/src/test/java/com/github/nkzawa/socketio/parser/ByteArrayTest.java new file mode 100644 index 0000000..b69f125 --- /dev/null +++ b/src/test/java/com/github/nkzawa/socketio/parser/ByteArrayTest.java @@ -0,0 +1,104 @@ +package com.github.nkzawa.socketio.parser; + +import com.github.nkzawa.emitter.Emitter; +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.nio.charset.Charset; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(JUnit4.class) +public class ByteArrayTest { + + private static Parser.Encoder encoder = new Parser.Encoder(); + + @Test + public void encodeByteArray() { + Packet packet = new Packet(Parser.BINARY_EVENT); + packet.data = "abc".getBytes(Charset.forName("UTF-8")); + packet.id = 23; + packet.nsp = "/cool"; + Helpers.testBin(packet); + } + + @Test + public void encodeByteArray2() { + Packet packet = new Packet(Parser.BINARY_EVENT); + packet.data = new byte[2]; + packet.id = 0; + packet.nsp = "/"; + Helpers.testBin(packet); + } + + @Test + public void encodeByteArrayDeepInJson() { + JSONObject data = new JSONObject("{a: \"hi\", b: {}, c: {a: \"bye\", b: {}}}"); + data.getJSONObject("b").put("why", new byte[3]); + data.getJSONObject("c").getJSONObject("b").put("a", new byte[6]); + + Packet packet = new Packet(Parser.BINARY_EVENT); + packet.data = data; + packet.id = 999; + packet.nsp = "/deep"; + Helpers.testBin(packet); + } + + @Test + public void encodeDeepBinaryJSONWithNullValue() { + JSONObject data = new JSONObject("{a: \"b\", c: 4, e: {g: null}, h: null}"); + data.put("h", new byte[9]); + + Packet packet = new Packet(Parser.BINARY_EVENT); + packet.data = data; + packet.nsp = "/"; + packet.id = 600; + Helpers.testBin(packet); + } + + @Test + public void encodeBinaryAckWithByteArray() { + JSONArray data = new JSONArray("[a, null, {}]"); + data.put(1, "xxx".getBytes(Charset.forName("UTF-8"))); + + Packet packet = new Packet(Parser.BINARY_ACK); + packet.data = data; + packet.id = 127; + packet.nsp = "/back"; + Helpers.testBin(packet); + } + + @Test + public void cleanItselfUpOnClose() { + JSONArray data = new JSONArray(); + data.put(new byte[2]); + data.put(new byte[3]); + + Packet packet = new Packet(Parser.BINARY_EVENT); + packet.data = data; + packet.id = 0; + packet.nsp = "/"; + + encoder.encode(packet, new Parser.Encoder.Callback() { + @Override + public void call(final Object[] encodedPackets) { + final Parser.Decoder decoder = new Parser.Decoder(); + decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() { + @Override + public void call(Object... args) { + throw new RuntimeException("received a packet when not all binary data was sent."); + } + }); + + decoder.add((String)encodedPackets[0]); + decoder.add((byte[]) encodedPackets[1]); + decoder.destroy(); + assertThat(decoder.reconstructor.buffers.size(), is(0)); + } + }); + } +} diff --git a/src/test/java/com/github/nkzawa/socketio/parser/Helpers.java b/src/test/java/com/github/nkzawa/socketio/parser/Helpers.java new file mode 100644 index 0000000..449d64d --- /dev/null +++ b/src/test/java/com/github/nkzawa/socketio/parser/Helpers.java @@ -0,0 +1,76 @@ +package com.github.nkzawa.socketio.parser; + +import com.github.nkzawa.emitter.Emitter; +import org.json.JSONArray; +import org.json.JSONObject; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.skyscreamer.jsonassert.JSONAssert; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(JUnit4.class) +public class Helpers { + + private static Parser.Encoder encoder = new Parser.Encoder(); + + public static void test(final Packet obj) { + encoder.encode(obj, new Parser.Encoder.Callback() { + @Override + public void call(Object[] encodedPackets) { + Parser.Decoder decoder = new Parser.Decoder(); + decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() { + @Override + public void call(Object... args) { + Packet packet = (Packet)args[0]; + assertPacket(packet, obj); + } + }); + decoder.add((String)encodedPackets[0]); + } + }); + } + + public static void testBin(final Packet obj) { + final Object originalData = obj.data; + encoder.encode(obj, new Parser.Encoder.Callback() { + @Override + public void call(Object[] encodedPackets) { + Parser.Decoder decoder = new Parser.Decoder(); + decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() { + @Override + public void call(Object... args) { + Packet packet = (Packet)args[0]; + obj.data = originalData; + obj.attachments = -1; + assertPacket(packet, obj); + } + }); + + for (Object packet : encodedPackets) { + if (packet instanceof String) { + decoder.add((String)packet); + } else if (packet instanceof byte[]) { + decoder.add((byte[])packet); + } + } + } + }); + } + + public static void assertPacket(Packet expected, Packet actual) { + assertThat(actual.type, is(expected.type)); + assertThat(actual.id, is(expected.id)); + assertThat(actual.nsp, is(expected.nsp)); + assertThat(actual.attachments, is(expected.attachments)); + + if (expected.data instanceof JSONArray) { + JSONAssert.assertEquals((JSONArray)expected.data, (JSONArray)actual.data, true); + } else if (expected.data instanceof JSONObject) { + JSONAssert.assertEquals((JSONObject)expected.data, (JSONObject)actual.data, true); + } else { + assertThat(actual.data, is(expected.data)); + } + } +} diff --git a/src/test/java/com/github/nkzawa/socketio/parser/ParserTest.java b/src/test/java/com/github/nkzawa/socketio/parser/ParserTest.java index a0edf9e..d102b64 100644 --- a/src/test/java/com/github/nkzawa/socketio/parser/ParserTest.java +++ b/src/test/java/com/github/nkzawa/socketio/parser/ParserTest.java @@ -1,17 +1,9 @@ package com.github.nkzawa.socketio.parser; -import com.github.nkzawa.emitter.Emitter; import org.json.JSONArray; -import org.json.JSONObject; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -import org.skyscreamer.jsonassert.JSONAssert; - -import java.nio.charset.Charset; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; @RunWith(JUnit4.class) public class ParserTest { @@ -23,14 +15,14 @@ public class ParserTest { public void encodeConnection() { Packet packet = new Packet(Parser.CONNECT); packet.nsp = "/woot"; - test(packet); + Helpers.test(packet); } @Test - public void encodeDisconnect() { + public void encodeDisconnection() { Packet packet = new Packet(Parser.DISCONNECT); packet.nsp = "/woot"; - test(packet); + Helpers.test(packet); } @Test @@ -38,12 +30,12 @@ public class ParserTest { Packet packet1 = new Packet(Parser.EVENT); packet1.data = new JSONArray("[\"a\", 1, {}]"); packet1.nsp = "/"; - test(packet1); + Helpers.test(packet1); Packet packet2 = new Packet(Parser.EVENT); packet2.data = new JSONArray("[\"a\", 1, {}]"); packet2.nsp = "/test"; - test(packet2); + Helpers.test(packet2); } @Test @@ -52,126 +44,6 @@ public class ParserTest { packet.data = new JSONArray("[\"a\", 1, {}]"); packet.id = 123; packet.nsp = "/"; - test(packet); - } - - @Test - public void encodeByteArray() { - Packet packet = new Packet(Parser.BINARY_EVENT); - packet.data = "abc".getBytes(Charset.forName("UTF-8")); - packet.id = 23; - packet.nsp = "/cool"; - testBin(packet); - } - - @Test - public void encodeByteArray2() { - Packet packet = new Packet(Parser.BINARY_EVENT); - packet.data = new byte[2]; - packet.id = 0; - packet.nsp = "/"; - testBin(packet); - } - - @Test - public void encodeByteArrayDeep() { - JSONObject data = new JSONObject("{a: \"hi\", b: {}, c: {a: \"bye\", b: {}}}"); - data.getJSONObject("b").put("why", new byte[3]); - data.getJSONObject("c").getJSONObject("b").put("a", new byte[6]); - - Packet packet = new Packet(Parser.BINARY_EVENT); - packet.data = data; - packet.id = 999; - packet.nsp = "/deep"; - testBin(packet); - } - - @Test - public void cleanItselfUpOnClose() { - JSONArray data = new JSONArray(); - data.put(new byte[2]); - data.put(new byte[3]); - - Packet packet = new Packet(Parser.BINARY_EVENT); - packet.data = data; - packet.id = 0; - packet.nsp = "/"; - - encoder.encode(packet, new Parser.Encoder.Callback() { - @Override - public void call(final Object[] encodedPackets) { - final Parser.Decoder decoder = new Parser.Decoder(); - decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() { - @Override - public void call(Object... args) { - throw new RuntimeException("received a packet when not all binary data was sent."); - } - }); - - decoder.add((String)encodedPackets[0]); - decoder.add((byte[]) encodedPackets[1]); - decoder.destroy(); - assertThat(decoder.reconstructor.buffers.size(), is(0)); - } - }); - } - - private void test(final Packet obj) { - encoder.encode(obj, new Parser.Encoder.Callback() { - @Override - public void call(Object[] encodedPackets) { - Parser.Decoder decoder = new Parser.Decoder(); - decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() { - @Override - public void call(Object... args) { - Packet packet = (Packet)args[0]; - assertPacket(packet, obj); - } - }); - decoder.add((String)encodedPackets[0]); - } - }); - } - - private void testBin(final Packet obj) { - final Object originalData = obj.data; - encoder.encode(obj, new Parser.Encoder.Callback() { - @Override - public void call(Object[] encodedPackets) { - Parser.Decoder decoder = new Parser.Decoder(); - decoder.on(Parser.Decoder.EVENT_DECODED, new Emitter.Listener() { - @Override - public void call(Object... args) { - Packet packet = (Packet)args[0]; - obj.data = originalData; - obj.attachments = -1; - assertPacket(packet, obj); - } - }); - - for (Object packet : encodedPackets) { - if (packet instanceof String) { - decoder.add((String)packet); - } else if (packet instanceof byte[]) { - decoder.add((byte[])packet); - } - } - } - }); - } - - private void assertPacket(Packet expected, Packet actual) { - assertThat(actual.type, is(expected.type)); - assertThat(actual.id, is(expected.id)); - assertThat(actual.nsp, is(expected.nsp)); - assertThat(actual.attachments, is(expected.attachments)); - - if (expected.data instanceof JSONArray) { - JSONAssert.assertEquals((JSONArray)expected.data, (JSONArray)actual.data, true); - } else if (expected.data instanceof JSONObject) { - JSONAssert.assertEquals((JSONObject)expected.data, (JSONObject)actual.data, true); - } else { - assertThat(actual.data, is(expected.data)); - } + Helpers.test(packet); } } diff --git a/src/test/resources/package.json b/src/test/resources/package.json index 7d34836..9bcea02 100644 --- a/src/test/resources/package.json +++ b/src/test/resources/package.json @@ -3,6 +3,6 @@ "version": "0.0.0", "private": true, "dependencies": { - "socket.io": "1.0.0-pre2" + "socket.io": "1.0.3" } }