/**
* Copyright (c) 2012-2016 André Bargull
* Alle Rechte vorbehalten / All Rights Reserved. Use is subject to license terms.
*
* <https://github.com/anba/es6draft>
*/
package com.github.anba.es6draft.regexp;
/**
* UTF-32 encoding with modified case-folding
*/
final class UTF32Encoding extends UEncoding {
public static final UTF32Encoding INSTANCE = new UTF32Encoding();
protected UTF32Encoding() {
super("UTF-32", 4, 4);
}
@Override
public byte[] toBytes(CharSequence cs) {
return toBytes(cs.toString());
}
@Override
public byte[] toBytes(String s) {
int length = 0;
for (int cp, i = 0, len = s.length(); i < len; i += Character.charCount(cp)) {
cp = s.codePointAt(i);
length += 1;
}
byte[] bytes = new byte[length * 4 + 4]; // null-terminated c-string
for (int cp, i = 0, j = 0, len = s.length(); i < len; i += Character.charCount(cp)) {
cp = s.codePointAt(i);
bytes[j++] = (byte) ((cp >>> 24) & 0xff);
bytes[j++] = (byte) ((cp >>> 16) & 0xff);
bytes[j++] = (byte) ((cp >>> 8) & 0xff);
bytes[j++] = (byte) ((cp >>> 0) & 0xff);
}
return bytes;
}
@Override
public int strLength(CharSequence cs, int start, int count) {
int index = start;
for (int j = 0; j < count; j += 4) {
index += Character.charCount(Character.codePointAt(cs, index));
}
return index - start;
}
@Override
public int length(CharSequence cs) {
return Character.codePointCount(cs, 0, cs.length()) * 4;
}
@Override
public int length(CharSequence cs, int start, int end) {
assert 0 <= start && start <= end && end <= cs.length();
return Character.codePointCount(cs, start, end) * 4;
}
@Override
public int length(CharSequence cs, int byteIndex) {
return 4;
}
@Override
public int length(byte c) {
return 4;
}
@Override
public int length(byte[] bytes, int p, int end) {
return p + 3 < end ? 4 : missing(p + 2 < end ? 1 : p + 1 < end ? 2 : 3);
}
@Override
public int mbcToCode(byte[] bytes, int p, int end) {
return ((bytes[p + 0] & 0xff) << 24) | ((bytes[p + 1] & 0xff) << 16) | ((bytes[p + 2] & 0xff) << 8)
| (bytes[p + 3] & 0xff);
}
@Override
public int codeToMbcLength(int code) {
return 4;
}
@Override
public int codeToMbc(int code, byte[] bytes, int p) {
bytes[p + 0] = (byte) ((code >>> 24) & 0xff);
bytes[p + 1] = (byte) ((code >>> 16) & 0xff);
bytes[p + 2] = (byte) ((code >>> 8) & 0xff);
bytes[p + 3] = (byte) ((code >>> 0) & 0xff);
return 4;
}
@Override
public int leftAdjustCharHead(byte[] bytes, int p, int s, int end) {
return s > p ? s - ((s - p) & 3) : s;
}
@Override
public int strLength(byte[] bytes, int p, int end) {
return p <= end ? (end - p) >>> 2 : 0;
}
@Override
public int strCodeAt(byte[] bytes, int p, int end, int index) {
int q = p + (index << 2);
return q + 3 < end ? mbcToCode(bytes, q, end) : -1;
}
}