New method IntegerList.toCharArray()

This commit is contained in:
Ben Hamilton 2017-01-24 11:28:49 -08:00
parent 449a32d4ae
commit bbf8476c8e
3 changed files with 101 additions and 6 deletions

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
package org.antlr.v4.test.runtime.java;
import static org.junit.Assert.assertArrayEquals;
import org.antlr.v4.runtime.misc.IntegerList;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class TestIntegerList {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void emptyListToEmptyCharArray() {
IntegerList l = new IntegerList();
assertArrayEquals(new char[0], l.toCharArray());
}
@Test
public void negativeIntegerToCharArrayThrows() {
IntegerList l = new IntegerList();
l.add(-42);
thrown.expect(IllegalArgumentException.class);
l.toCharArray();
}
@Test
public void surrogateRangeIntegerToCharArray() {
IntegerList l = new IntegerList();
// Java allows dangling surrogates, so (currently) we do
// as well. We could change this if desired.
l.add(0xDC00);
char expected[] = new char[] { 0xDC00 };
assertArrayEquals(expected, l.toCharArray());
}
@Test
public void tooLargeIntegerToCharArrayThrows() {
IntegerList l = new IntegerList();
l.add(0x110000);
thrown.expect(IllegalArgumentException.class);
l.toCharArray();
}
@Test
public void unicodeBMPIntegerListToCharArray() {
IntegerList l = new IntegerList();
l.add(0x35);
l.add(0x4E94);
l.add(0xFF15);
char expected[] = new char[] { 0x35, 0x4E94, 0xFF15 };
assertArrayEquals(expected, l.toCharArray());
}
@Test
public void unicodeSMPIntegerListToCharArray() {
IntegerList l = new IntegerList();
l.add(0x104A5);
l.add(0x116C5);
l.add(0x1D7FB);
char expected[] = new char[] { 0xD801, 0xDCA5, 0xD805, 0xDEC5, 0xD835, 0xDFFB };
assertArrayEquals(expected, l.toCharArray());
}
}

View File

@ -272,4 +272,34 @@ public class IntegerList {
_data = Arrays.copyOf(_data, newLength);
}
public final char[] toCharArray() {
// Optimize for the common case (all data values are
// < 0xFFFF) to avoid an extra scan
char[] resultArray = new char[_size];
int resultIdx = 0;
boolean calculatedPreciseResultSize = false;
for (int i = 0; i < _size; i++) {
int codePoint = _data[i];
// Calculate the precise result size if we encounter
// a code point > 0xFFFF
if (!calculatedPreciseResultSize &&
Character.isSupplementaryCodePoint(codePoint)) {
resultArray = Arrays.copyOf(resultArray, charArraySize());
calculatedPreciseResultSize = true;
}
// This will throw IllegalArgumentException if
// the code point is not a valid Unicode code point
int charsWritten = Character.toChars(codePoint, resultArray, resultIdx);
resultIdx += charsWritten;
}
return resultArray;
}
private int charArraySize() {
int result = 0;
for (int i = 0; i < _size; i++) {
result += Character.charCount(_data[i]);
}
return result;
}
}

View File

@ -136,12 +136,7 @@ public class Utils {
}
public static char[] toCharArray(IntegerList data) {
if ( data==null ) return null;
char[] cdata = new char[data.size()];
for (int i=0; i<data.size(); i++) {
cdata[i] = (char)data.get(i);
}
return cdata;
return data.toCharArray();
}
public static IntervalSet toSet(BitSet bits) {