| 61 | // An implementation of MachineInput for UTF-8 byte arrays. |
| 62 | // |pos| and |width| are byte indices. |
| 63 | private static class UTF8Input extends MachineInput { |
| 64 | |
| 65 | final byte[] b; |
| 66 | final int start; |
| 67 | final int end; |
| 68 | |
| 69 | UTF8Input(byte[] b) { |
| 70 | this.b = b; |
| 71 | start = 0; |
| 72 | end = b.length; |
| 73 | } |
| 74 | |
| 75 | UTF8Input(byte[] b, int start, int end) { |
| 76 | if (end > b.length) { |
| 77 | throw new ArrayIndexOutOfBoundsException( |
| 78 | "end is greater than length: " + end + " > " + b.length); |
| 79 | } |
| 80 | this.b = b; |
| 81 | this.start = start; |
| 82 | this.end = end; |
| 83 | } |
| 84 | |
| 85 | @Override |
| 86 | int step(int i) { |
| 87 | i += start; |
| 88 | if (i >= end) { |
| 89 | return EOF; |
| 90 | } |
| 91 | |
| 92 | // UTF-8. RFC 3629 in five lines: |
| 93 | // |
| 94 | // Unicode code points UTF-8 encoding (binary) |
| 95 | // 00-7F (7 bits) 0tuvwxyz |
| 96 | // 0080-07FF (11 bits) 110pqrst 10uvwxyz |
| 97 | // 0800-FFFF (16 bits) 1110jklm 10npqrst 10uvwxyz |
| 98 | // 010000-10FFFF (21 bits) 11110efg 10hijklm 10npqrst 10uvwxyz |
| 99 | int x = b[i++] & 0xff; // zero extend |
| 100 | if ((x & 0x80) == 0) { |
| 101 | return x << 3 | 1; |
| 102 | } else if ((x & 0xE0) == 0xC0) { // 110xxxxx |
| 103 | x = x & 0x1F; |
| 104 | if (i >= end) { |
| 105 | return EOF; |
| 106 | } |
| 107 | x = x << 6 | (b[i++] & 0x3F); |
| 108 | return x << 3 | 2; |
| 109 | } else if ((x & 0xF0) == 0xE0) { // 1110xxxx |
| 110 | x = x & 0x0F; |
| 111 | if (i + 1 >= end) { |
| 112 | return EOF; |
| 113 | } |
| 114 | x = x << 6 | (b[i++] & 0x3F); |
| 115 | x = x << 6 | (b[i++] & 0x3F); |
| 116 | return x << 3 | 3; |
| 117 | } else { // 11110xxx |
| 118 | x = x & 0x07; |
| 119 | if (i + 2 >= end) { |
| 120 | return EOF; |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…