aboutsummaryrefslogtreecommitdiffstats
path: root/AndroidAsync/src
diff options
context:
space:
mode:
authorKoushik Dutta <koush@koushikdutta.com>2014-03-26 11:12:11 -0700
committerKoushik Dutta <koush@koushikdutta.com>2014-03-26 11:12:11 -0700
commit8992ab64d98dedbcdb746ccf7d8d9dd49c5c6acb (patch)
tree1ffdb9d612b2bec0a6cac3603daf25e69f9521a6 /AndroidAsync/src
parenta3b221d35817952e9eccd2a6e3535d1f3f480aff (diff)
parentece384dfd650834fdf7c821aaedec30edf450136 (diff)
downloadAndroidAsync-8992ab64d98dedbcdb746ccf7d8d9dd49c5c6acb.tar.gz
AndroidAsync-8992ab64d98dedbcdb746ccf7d8d9dd49c5c6acb.tar.bz2
AndroidAsync-8992ab64d98dedbcdb746ccf7d8d9dd49c5c6acb.zip
Merge pull request #126 from paulpdaniels/optimize-framing
Optimize framing
Diffstat (limited to 'AndroidAsync/src')
-rw-r--r--AndroidAsync/src/com/koushikdutta/async/http/HybiParser.java85
-rw-r--r--AndroidAsync/src/com/koushikdutta/async/http/WebSocket.java1
-rw-r--r--AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java5
3 files changed, 67 insertions, 24 deletions
diff --git a/AndroidAsync/src/com/koushikdutta/async/http/HybiParser.java b/AndroidAsync/src/com/koushikdutta/async/http/HybiParser.java
index 05b70d4..dd8e82c 100644
--- a/AndroidAsync/src/com/koushikdutta/async/http/HybiParser.java
+++ b/AndroidAsync/src/com/koushikdutta/async/http/HybiParser.java
@@ -226,6 +226,22 @@ abstract class HybiParser {
}
private DataEmitterReader mReader = new DataEmitterReader();
+
+ private static final long BASE = 2;
+
+ private static final long _2_TO_8_ = BASE << 7;
+
+ private static final long _2_TO_16_ = BASE << 15;
+
+ private static final long _2_TO_24 = BASE << 23;
+
+ private static final long _2_TO_32_ = BASE << 31;
+
+ private static final long _2_TO_40_ = BASE << 39;
+
+ private static final long _2_TO_48_ = BASE << 47;
+
+ private static final long _2_TO_56_ = BASE << 55;
public HybiParser(DataEmitter socket) {
socket.setDataCallback(mReader);
parse();
@@ -275,29 +291,48 @@ abstract class HybiParser {
}
public byte[] frame(String data) {
- return frame(data, OP_TEXT, -1);
+ return frame(OP_TEXT, data, -1);
}
public byte[] frame(byte[] data) {
- return frame(data, OP_BINARY, -1);
+ return frame(OP_BINARY, data, -1);
}
-
- private byte[] frame(byte[] data, int opcode, int errorCode) {
- return frame((Object)data, opcode, errorCode);
+
+ public byte[] frame(byte[] data, int offset, int length) {
+ return frame(OP_BINARY, data, -1, offset, length);
}
- private byte[] frame(String data, int opcode, int errorCode) {
- return frame((Object)data, opcode, errorCode);
+ /**
+ * Flip the opcode so to avoid the name collision with the public method
+ *
+ * @param opcode
+ * @param data
+ * @param errorCode
+ * @return
+ */
+ private byte[] frame(int opcode, byte[] data, int errorCode) {
+ return frame(opcode, data, errorCode, 0, data.length);
}
- private byte[] frame(Object data, int opcode, int errorCode) {
+ /**
+ * Don't actually need the flipped method signature, trying to keep it in line with the byte[] version
+ *
+ * @param opcode
+ * @param data
+ * @param errorCode
+ * @return
+ */
+ private byte[] frame(int opcode, String data, int errorCode) {
+ return frame(opcode, decode(data), errorCode);
+ }
+
+ private byte[] frame(int opcode, byte [] data, int errorCode, int dataOffset, int dataLength) {
if (mClosed) return null;
// Log.d(TAG, "Creating frame for: " + data + " op: " + opcode + " err: " + errorCode);
-
- byte[] buffer = (data instanceof String) ? decode((String) data) : (byte[]) data;
+ byte[] buffer = data;
int insert = (errorCode > 0) ? 2 : 0;
- int length = buffer.length + insert;
+ int length = dataLength + insert - dataOffset;
int header = (length <= 125) ? 2 : (length <= 65535 ? 4 : 10);
int offset = header + (mMasking ? 4 : 0);
int masked = mMasking ? MASK : 0;
@@ -309,25 +344,27 @@ abstract class HybiParser {
frame[1] = (byte) (masked | length);
} else if (length <= 65535) {
frame[1] = (byte) (masked | 126);
- frame[2] = (byte) Math.floor(length / 256);
+ frame[2] = (byte) (length / 256);
frame[3] = (byte) (length & BYTE);
} else {
- frame[1] = (byte) (masked | 127);
- frame[2] = (byte) (((int) Math.floor(length / Math.pow(2, 56))) & BYTE);
- frame[3] = (byte) (((int) Math.floor(length / Math.pow(2, 48))) & BYTE);
- frame[4] = (byte) (((int) Math.floor(length / Math.pow(2, 40))) & BYTE);
- frame[5] = (byte) (((int) Math.floor(length / Math.pow(2, 32))) & BYTE);
- frame[6] = (byte) (((int) Math.floor(length / Math.pow(2, 24))) & BYTE);
- frame[7] = (byte) (((int) Math.floor(length / Math.pow(2, 16))) & BYTE);
- frame[8] = (byte) (((int) Math.floor(length / Math.pow(2, 8))) & BYTE);
+
+ frame[1] = (byte) (masked | 127);
+ frame[2] = (byte) (( length / _2_TO_56_) & BYTE);
+ frame[3] = (byte) (( length / _2_TO_48_) & BYTE);
+ frame[4] = (byte) (( length / _2_TO_40_) & BYTE);
+ frame[5] = (byte) (( length / _2_TO_32_) & BYTE);
+ frame[6] = (byte) (( length / _2_TO_24) & BYTE);
+ frame[7] = (byte) (( length / _2_TO_16_) & BYTE);
+ frame[8] = (byte) (( length / _2_TO_8_) & BYTE);
frame[9] = (byte) (length & BYTE);
}
if (errorCode > 0) {
- frame[offset] = (byte) (((int) Math.floor(errorCode / 256)) & BYTE);
+ frame[offset] = (byte) ((errorCode / 256) & BYTE);
frame[offset+1] = (byte) (errorCode & BYTE);
}
- System.arraycopy(buffer, 0, frame, offset + insert, buffer.length);
+
+ System.arraycopy(buffer, dataOffset, frame, offset + insert, dataLength - dataOffset);
if (mMasking) {
byte[] mask = {
@@ -347,7 +384,7 @@ abstract class HybiParser {
public void close(int code, String reason) {
if (mClosed) return;
- sendFrame(frame(reason, OP_CLOSE, code));
+ sendFrame(frame(OP_CLOSE, reason, code));
mClosed = true;
}
@@ -403,7 +440,7 @@ abstract class HybiParser {
} else if (opcode == OP_PING) {
if (payload.length > 125) { throw new ProtocolError("Ping payload too large"); }
// Log.d(TAG, "Sending pong!!");
- sendFrame(frame(payload, OP_PONG, -1));
+ sendFrame(frame(OP_PONG, payload, -1));
} else if (opcode == OP_PONG) {
String message = encode(payload);
diff --git a/AndroidAsync/src/com/koushikdutta/async/http/WebSocket.java b/AndroidAsync/src/com/koushikdutta/async/http/WebSocket.java
index 71dce06..8242381 100644
--- a/AndroidAsync/src/com/koushikdutta/async/http/WebSocket.java
+++ b/AndroidAsync/src/com/koushikdutta/async/http/WebSocket.java
@@ -10,6 +10,7 @@ public interface WebSocket extends AsyncSocket {
public void send(byte[] bytes);
public void send(String string);
+ public void send(byte [] bytes, int offset, int len);
public void setStringCallback(StringCallback callback);
public StringCallback getStringCallback();
diff --git a/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java b/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java
index 71c8632..3f343f0 100644
--- a/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java
+++ b/AndroidAsync/src/com/koushikdutta/async/http/WebSocketImpl.java
@@ -216,6 +216,11 @@ public class WebSocketImpl implements WebSocket {
public void send(byte[] bytes) {
mSink.write(ByteBuffer.wrap(mParser.frame(bytes)));
}
+
+ @Override
+ public void send(byte[] bytes, int offset, int len) {
+ mSink.write(ByteBuffer.wrap(mParser.frame(bytes, offset, len)));
+ }
@Override
public void send(String string) {