forked from graphql-java/graphql-java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
UnicodeUtil.java
64 lines (56 loc) · 2.36 KB
/
UnicodeUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package graphql.parser;
import graphql.Assert;
import graphql.Internal;
import java.io.IOException;
import java.io.StringWriter;
/**
* Contains Unicode helpers for parsing StringValue types in the grammar
*/
@Internal
public class UnicodeUtil {
public static int MAX_UNICODE_CODE_POINT = 0x10FFFF;
public static int parseAndWriteUnicode(StringWriter writer, String string, int i) {
// Unicode characters can either be:
// - four hex characters in the form \\u597D, or
// - any number of hex characters surrounded by a brace in the form \\u{1F37A}
// Four hex character only case \\u597D, for code points in the Basic Multilingual Plane (BMP)
if (isNotBracedEscape(string, i)) {
String hexStr = string.substring(i + 1, i + 5);
int codepoint = Integer.parseInt(hexStr, 16);
writer.write(codepoint);
return i + 4;
// TODO error checking of invalid values
} else {
// Any number of hex characters e.g. \\u{1F37A}, which allows code points outside the Basic Multilingual Plane (BMP)
int startIx = i + 2;
int endIndexExclusive = startIx;
do {
if (endIndexExclusive + 1 >= string.length()) {
throw new RuntimeException("invalid unicode encoding");
}
} while (string.charAt(++endIndexExclusive) != '}');
String hexStr = string.substring(startIx, endIndexExclusive);
Integer hexValue = Integer.parseInt(hexStr, 16);
if (isValidUnicodeCodePoint(hexValue)) {
char[] chars = Character.toChars(hexValue);
try {
writer.write(chars);
} catch (IOException e) {
return Assert.assertShouldNeverHappen();
}
return endIndexExclusive;
} else {
throw new RuntimeException("invalid unicode code point");
}
}
// Assert.assertShouldNeverHappen();
// TODO error checking of invalid values
}
private static boolean isNotBracedEscape(String string, int i) {
return string.charAt(i + 1) != '{';
}
private static boolean isValidUnicodeCodePoint(Integer value) {
// TODO: Add bad surrogate checks
return value <= MAX_UNICODE_CODE_POINT;
}
}