Merge pull request #120 from niqo01/nm/optimizeParser

Enhance Parser decode
This commit is contained in:
Naoyuki Kanezawa
2015-03-29 01:16:36 +09:00
3 changed files with 62 additions and 29 deletions

View File

@@ -57,10 +57,10 @@ public class Parser {
"CONNECT", "CONNECT",
"DISCONNECT", "DISCONNECT",
"EVENT", "EVENT",
"BINARY_EVENT",
"ACK", "ACK",
"BINARY_ACK",
"ERROR", "ERROR",
"BINARY_EVENT",
"BINARY_ACK"
}; };
@@ -172,11 +172,13 @@ public class Parser {
private static Packet decodeString(String str) { private static Packet decodeString(String str) {
Packet p = new Packet(); Packet p = new Packet();
int i = 0; int i = 0;
int length = str.length();
p.type = Character.getNumericValue(str.charAt(0)); p.type = Character.getNumericValue(str.charAt(0));
if (p.type < 0 || p.type > types.length - 1) return error(); if (p.type < 0 || p.type > types.length - 1) return error();
if (BINARY_EVENT == p.type || BINARY_ACK == p.type) { if (BINARY_EVENT == p.type || BINARY_ACK == p.type) {
if (!str.contains("-") || length <= i + 1) return error();
StringBuilder attachments = new StringBuilder(); StringBuilder attachments = new StringBuilder();
while (str.charAt(++i) != '-') { while (str.charAt(++i) != '-') {
attachments.append(str.charAt(i)); attachments.append(str.charAt(i));
@@ -184,48 +186,49 @@ public class Parser {
p.attachments = Integer.parseInt(attachments.toString()); p.attachments = Integer.parseInt(attachments.toString());
} }
if (str.length() > i + 1 && '/' == str.charAt(i + 1)) { if (length > i + 1 && '/' == str.charAt(i + 1)) {
StringBuilder nsp = new StringBuilder(); StringBuilder nsp = new StringBuilder();
while (true) { while (true) {
++i; ++i;
char c = str.charAt(i); char c = str.charAt(i);
if (',' == c) break; if (',' == c) break;
nsp.append(c); nsp.append(c);
if (i + 1 == str.length()) break; if (i + 1 == length) break;
} }
p.nsp = nsp.toString(); p.nsp = nsp.toString();
} else { } else {
p.nsp = "/"; p.nsp = "/";
} }
Character next; if (length > i + 1){
try { Character next = str.charAt(i + 1);
next = str.charAt(i + 1); if (Character.getNumericValue(next) > -1) {
} catch (IndexOutOfBoundsException e) { StringBuilder id = new StringBuilder();
next = Character.UNASSIGNED; while (true) {
} ++i;
if (Character.UNASSIGNED != next && Character.getNumericValue(next) > -1) { char c = str.charAt(i);
StringBuilder id = new StringBuilder(); if (Character.getNumericValue(c) < 0) {
while (true) { --i;
++i; break;
char c = str.charAt(i); }
if (Character.getNumericValue(c) < 0) { id.append(c);
--i; if (i + 1 == length) break;
break; }
try {
p.id = Integer.parseInt(id.toString());
} catch (NumberFormatException e){
return error();
} }
id.append(c);
if (i + 1 == str.length()) break;
} }
p.id = Integer.parseInt(id.toString());
} }
try { if (length > i + 1){
str.charAt(++i); try {
p.data = new JSONTokener(str.substring(i)).nextValue(); str.charAt(++i);
} catch (IndexOutOfBoundsException e) { p.data = new JSONTokener(str.substring(i)).nextValue();
// do nothing } catch (JSONException e) {
} catch (JSONException e) { return error();
return error(); }
} }
logger.fine(String.format("decoded %s as %s", str, p)); logger.fine(String.format("decoded %s as %s", str, p));

View File

@@ -15,6 +15,7 @@ import static org.junit.Assert.assertThat;
public class Helpers { public class Helpers {
private static Parser.Encoder encoder = new Parser.Encoder(); private static Parser.Encoder encoder = new Parser.Encoder();
private static Packet<String> errorPacket = new Packet<String>(Parser.ERROR, "parser error");
public static void test(final Packet obj) { public static void test(final Packet obj) {
encoder.encode(obj, new Parser.Encoder.Callback() { encoder.encode(obj, new Parser.Encoder.Callback() {
@@ -33,6 +34,18 @@ public class Helpers {
}); });
} }
public static void testDecodeError(final String errorMessage) {
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(errorPacket, packet);
}
});
decoder.add(errorMessage);
}
public static void testBin(final Packet obj) { public static void testBin(final Packet obj) {
final Object originalData = obj.data; final Object originalData = obj.data;
encoder.encode(obj, new Parser.Encoder.Callback() { encoder.encode(obj, new Parser.Encoder.Callback() {

View File

@@ -11,7 +11,6 @@ public class ParserTest {
private static Parser.Encoder encoder = new Parser.Encoder(); private static Parser.Encoder encoder = new Parser.Encoder();
@Test @Test
public void encodeConnection() { public void encodeConnection() {
Packet packet = new Packet(Parser.CONNECT); Packet packet = new Packet(Parser.CONNECT);
@@ -47,4 +46,22 @@ public class ParserTest {
packet.nsp = "/"; packet.nsp = "/";
Helpers.test(packet); Helpers.test(packet);
} }
@Test
public void decodeInError() throws JSONException {
// Random string
Helpers.testDecodeError("asdf");
// Unknown type
Helpers.testDecodeError(Parser.types.length + "asdf");
// Binary event with no `-`
Helpers.testDecodeError(Parser.BINARY_EVENT + "asdf");
// Binary ack with no `-`
Helpers.testDecodeError(Parser.BINARY_ACK + "asdf");
// Binary event with no attachment
Helpers.testDecodeError(String.valueOf(Parser.BINARY_EVENT));
// event non numeric id
Helpers.testDecodeError(Parser.EVENT + "2sd");
// event with invalid json data
Helpers.testDecodeError(Parser.EVENT + "2[\"a\",1,{asdf}]");
}
} }