summaryrefslogtreecommitdiff
path: root/src/moe/anita/mai/buffer/MemBuf.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/moe/anita/mai/buffer/MemBuf.java')
-rw-r--r--src/moe/anita/mai/buffer/MemBuf.java57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/moe/anita/mai/buffer/MemBuf.java b/src/moe/anita/mai/buffer/MemBuf.java
index a2bc477..922e624 100644
--- a/src/moe/anita/mai/buffer/MemBuf.java
+++ b/src/moe/anita/mai/buffer/MemBuf.java
@@ -1,29 +1,72 @@
package moe.anita.mai.buffer;
+import java.nio.charset.StandardCharsets;
import java.util.Objects;
/**
- * Buffer backed entirely by an in-memory string.
+ * An in-memory UTF-8 source buffer.
+ *
+ * Offsets and lengths are measured in UTF-8 bytes.
*/
public final class MemBuf implements Buffer {
- private final String data;
+ private final byte[] data;
- public MemBuf(String data) { this.data = Objects.requireNonNull(data);
+ public MemBuf(String source) {
+ Objects.requireNonNull(source);
+ data = source.getBytes(StandardCharsets.UTF_8);
}
@Override
public int length() {
- return data.length();
+ return data.length;
}
@Override
- public char get(int index) {
- return data.charAt(index);
+ public int get(int offset) {
+ int first = Byte.toUnsignedInt(data[offset]);
+
+ if ((first & 0x80) == 0) {
+ return first;
+ }
+
+ if ((first & 0xE0) == 0xC0) {
+ return ((first & 0x1F) << 6) | (Byte.toUnsignedInt(data[offset + 1]) & 0x3F);
+ }
+
+ if ((first & 0xF0) == 0xE0) {
+ return ((first & 0x0F) << 12)
+ | ((Byte.toUnsignedInt(data[offset + 1]) & 0x3F) << 6)
+ | (Byte.toUnsignedInt(data[offset + 2]) & 0x3F);
+ }
+
+ return ((first & 0x07) << 18)
+ | ((Byte.toUnsignedInt(data[offset + 1]) & 0x3F) << 12)
+ | ((Byte.toUnsignedInt(data[offset + 2]) & 0x3F) << 6)
+ | (Byte.toUnsignedInt(data[offset + 3]) & 0x3F);
+ }
+
+ @Override
+ public int width(int offset) {
+ int first = Byte.toUnsignedInt(data[offset]);
+
+ if ((first & 0x80) == 0) {
+ return 1;
+ }
+
+ if ((first & 0xE0) == 0xC0) {
+ return 2;
+ }
+
+ if ((first & 0xF0) == 0xE0) {
+ return 3;
+ }
+
+ return 4;
}
@Override
public CharSequence slice(int start, int end) {
- return data.subSequence(start, end);
+ return new String(data, start, end - start, StandardCharsets.UTF_8);
}
}