compatible with engine.io-parser 1.0.6
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
package com.github.nkzawa.engineio.parser;
|
||||
|
||||
|
||||
import com.github.nkzawa.utf8.UTF8;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -47,7 +48,7 @@ public class Parser {
|
||||
String encoded = String.valueOf(packets.get(packet.type));
|
||||
|
||||
if (null != packet.data) {
|
||||
encoded += packet.data;
|
||||
encoded += UTF8.encode(String.valueOf(packet.data));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -70,6 +71,7 @@ public class Parser {
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
type = -1;
|
||||
}
|
||||
data = UTF8.decode(data);
|
||||
|
||||
if (type < 0 || type >= packetslist.size()) {
|
||||
return err;
|
||||
@@ -102,7 +104,7 @@ public class Parser {
|
||||
@Override
|
||||
public void call(Object packet) {
|
||||
if (packet instanceof String) {
|
||||
String encodingLength = String.valueOf(((String)packet).getBytes(Charset.forName("UTF-8")).length);
|
||||
String encodingLength = String.valueOf(((String) packet).length());
|
||||
byte[] sizeBuffer = new byte[encodingLength.length() + 2];
|
||||
|
||||
sizeBuffer[0] = (byte)0; // is a string
|
||||
@@ -110,7 +112,7 @@ public class Parser {
|
||||
sizeBuffer[i + 1] = (byte)Character.getNumericValue(encodingLength.charAt(i));
|
||||
}
|
||||
sizeBuffer[sizeBuffer.length - 1] = (byte)255;
|
||||
results.add(Buffer.concat(new byte[][] {sizeBuffer, ((String)packet).getBytes(Charset.forName("UTF-8"))}));
|
||||
results.add(Buffer.concat(new byte[][] {sizeBuffer, stringToByteArray((String)packet)}));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,7 +204,7 @@ public class Parser {
|
||||
byte[] msg = new byte[bufferTail.remaining()];
|
||||
bufferTail.get(msg);
|
||||
if (isString) {
|
||||
buffers.add(new String(msg, Charset.forName("UTF-8")));
|
||||
buffers.add(byteArrayToString(msg));
|
||||
} else {
|
||||
buffers.add(msg);
|
||||
}
|
||||
@@ -226,6 +228,22 @@ public class Parser {
|
||||
}
|
||||
}
|
||||
|
||||
public static String byteArrayToString(byte[] bytes) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (byte b : bytes) {
|
||||
builder.appendCodePoint(b & 0xFF);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static byte[] stringToByteArray(String string) {
|
||||
int len = string.length();
|
||||
byte[] bytes = new byte[len];
|
||||
for (int i = 0; i < len; i++) {
|
||||
bytes[i] = (byte)Character.codePointAt(string, i);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static interface EncodeCallback<T> {
|
||||
|
||||
|
||||
164
src/main/java/com/github/nkzawa/utf8/UTF8.java
Normal file
164
src/main/java/com/github/nkzawa/utf8/UTF8.java
Normal file
@@ -0,0 +1,164 @@
|
||||
package com.github.nkzawa.utf8;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* UTF-8 encoder/decoder ported from utf8.js.
|
||||
*
|
||||
* @see <a href="https://github.com/mathiasbynens/utf8.js">https://github.com/mathiasbynens/utf8.js</a>
|
||||
*/
|
||||
public class UTF8 {
|
||||
|
||||
private static int[] byteArray;
|
||||
private static int byteCount;
|
||||
private static int byteIndex;
|
||||
|
||||
public static String encode(String string) {
|
||||
int[] codePoints = uc2decode(string);
|
||||
int length = codePoints.length;
|
||||
int index = -1;
|
||||
int codePoint;
|
||||
StringBuilder byteString = new StringBuilder();
|
||||
while (++index < length) {
|
||||
codePoint = codePoints[index];
|
||||
byteString.append(encodeCodePoint(codePoint));
|
||||
}
|
||||
return byteString.toString();
|
||||
}
|
||||
|
||||
public static String decode(String byteString) {
|
||||
byteArray = uc2decode(byteString);
|
||||
byteCount = byteArray.length;
|
||||
byteIndex = 0;
|
||||
List<Integer> codePoints = new ArrayList<Integer>();
|
||||
int tmp;
|
||||
while ((tmp = decodeSymbol()) != -1) {
|
||||
codePoints.add(tmp);
|
||||
}
|
||||
return ucs2encode(listToArray(codePoints));
|
||||
}
|
||||
|
||||
private static int[] uc2decode(String string) {
|
||||
int length = string.length();
|
||||
int[] output = new int[string.codePointCount(0, length)];
|
||||
int counter = 0;
|
||||
int value;
|
||||
for (int i = 0; i < length; i += Character.charCount(value)) {
|
||||
value = string.codePointAt(i);
|
||||
output[counter++] = value;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static String encodeCodePoint(int codePoint) {
|
||||
StringBuilder symbol = new StringBuilder();
|
||||
if ((codePoint & 0xFFFFFF80) == 0) {
|
||||
return symbol.append(Character.toChars(codePoint)).toString();
|
||||
}
|
||||
if ((codePoint & 0xFFFFF800) == 0) {
|
||||
symbol.append(Character.toChars(((codePoint >> 6) & 0x1F) | 0xC0));
|
||||
} else if ((codePoint & 0xFFFF0000) == 0) {
|
||||
symbol.append(Character.toChars(((codePoint >> 12) & 0x0F) | 0xE0));
|
||||
symbol.append(createByte(codePoint, 6));
|
||||
} else if ((codePoint & 0xFFE00000) == 0) {
|
||||
symbol.append(Character.toChars(((codePoint >> 18) & 0x07) | 0xF0));
|
||||
symbol.append(createByte(codePoint, 12));
|
||||
symbol.append(createByte(codePoint, 6));
|
||||
}
|
||||
symbol.append(Character.toChars((codePoint & 0x3F) | 0x80));
|
||||
return symbol.toString();
|
||||
}
|
||||
|
||||
private static char[] createByte(int codePoint, int shift) {
|
||||
return Character.toChars(((codePoint >> shift) & 0x3F) | 0x80);
|
||||
}
|
||||
|
||||
private static int decodeSymbol() {
|
||||
int byte1;
|
||||
int byte2;
|
||||
int byte3;
|
||||
int byte4;
|
||||
int codePoint;
|
||||
|
||||
if (byteIndex > byteCount) {
|
||||
throw new RuntimeException("Invalid byte index");
|
||||
}
|
||||
|
||||
if (byteIndex == byteCount) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
byte1 = byteArray[byteIndex] & 0xFF;
|
||||
byteIndex++;
|
||||
|
||||
if ((byte1 & 0x80) == 0) {
|
||||
return byte1;
|
||||
}
|
||||
|
||||
if ((byte1 & 0xE0) == 0xC0) {
|
||||
byte2 = readContinuationByte();
|
||||
codePoint = ((byte1 & 0x1F) << 6) | byte2;
|
||||
if (codePoint >= 0x80) {
|
||||
return codePoint;
|
||||
} else {
|
||||
throw new RuntimeException("Invalid continuation byte");
|
||||
}
|
||||
}
|
||||
|
||||
if ((byte1 & 0xF0) == 0xE0) {
|
||||
byte2 = readContinuationByte();
|
||||
byte3 = readContinuationByte();
|
||||
codePoint = ((byte1 & 0x0F) << 12) | (byte2 << 6) | byte3;
|
||||
if (codePoint >= 0x0800) {
|
||||
return codePoint;
|
||||
} else {
|
||||
throw new RuntimeException("Invalid continuation byte");
|
||||
}
|
||||
}
|
||||
|
||||
if ((byte1 & 0xF8) == 0xF0) {
|
||||
byte2 = readContinuationByte();
|
||||
byte3 = readContinuationByte();
|
||||
byte4 = readContinuationByte();
|
||||
codePoint = ((byte1 & 0x0F) << 0x12) | (byte2 << 0x0C) | (byte3 << 0x06) | byte4;
|
||||
if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {
|
||||
return codePoint;
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Invalid continuation byte");
|
||||
}
|
||||
|
||||
private static int readContinuationByte() {
|
||||
if (byteIndex >= byteCount) {
|
||||
throw new RuntimeException("Invalid byte index");
|
||||
}
|
||||
|
||||
int continuationByte = byteArray[byteIndex] & 0xFF;
|
||||
byteIndex++;
|
||||
|
||||
if ((continuationByte & 0xC0) == 0x80) {
|
||||
return continuationByte & 0x3F;
|
||||
}
|
||||
|
||||
throw new RuntimeException("Invalid continuation byte");
|
||||
}
|
||||
|
||||
private static String ucs2encode(int[] array) {
|
||||
StringBuilder output = new StringBuilder();
|
||||
for (int value : array) {
|
||||
output.appendCodePoint(value);
|
||||
}
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private static int[] listToArray(List<Integer> list) {
|
||||
int size = list.size();
|
||||
int[] array = new int[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
array[i] = list.get(i);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user