ICU-4700 updates for UnicodeSet
X-SVN-Rev: 18796
This commit is contained in:
parent
b881df5948
commit
5994c85fac
393
icu4j/src/com/ibm/icu/impl/CollectionUtilities.java
Normal file
393
icu4j/src/com/ibm/icu/impl/CollectionUtilities.java
Normal file
@ -0,0 +1,393 @@
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2005, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
import com.ibm.icu.text.UnicodeSetIterator;
|
||||
|
||||
/**
|
||||
* Utilities that ought to be on collections, but aren't
|
||||
*/
|
||||
public final class CollectionUtilities {
|
||||
/**
|
||||
* Utility like Arrays.asList()
|
||||
*/
|
||||
public static Map asMap(Object[][] source, Map target, boolean reverse) {
|
||||
int from = 0, to = 1;
|
||||
if (reverse) {
|
||||
from = 1; to = 0;
|
||||
}
|
||||
for (int i = 0; i < source.length; ++i) {
|
||||
target.put(source[i][from], source[i][to]);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
public static Collection addAll(Iterator source, Collection target) {
|
||||
while (source.hasNext()) {
|
||||
target.add(source.next());
|
||||
}
|
||||
return target; // for chaining
|
||||
}
|
||||
|
||||
public static int size(Iterator source) {
|
||||
int result = 0;
|
||||
while (source.hasNext()) {
|
||||
source.next();
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Map asMap(Object[][] source) {
|
||||
return asMap(source, new HashMap(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility that ought to be on Map
|
||||
*/
|
||||
public static Map removeAll(Map m, Collection itemsToRemove) {
|
||||
for (Iterator it = itemsToRemove.iterator(); it.hasNext();) {
|
||||
Object item = it.next();
|
||||
m.remove(item);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
public Object getFirst(Collection c) {
|
||||
Iterator it = c.iterator();
|
||||
if (!it.hasNext()) return null;
|
||||
return it.next();
|
||||
}
|
||||
|
||||
public static Object getBest(Collection c, Comparator comp, int direction) {
|
||||
Iterator it = c.iterator();
|
||||
if (!it.hasNext()) return null;
|
||||
Object bestSoFar = it.next();
|
||||
while (it.hasNext()) {
|
||||
Object item = it.next();
|
||||
if (comp.compare(item, bestSoFar) == direction) {
|
||||
bestSoFar = item;
|
||||
}
|
||||
}
|
||||
return bestSoFar;
|
||||
}
|
||||
|
||||
public interface Filter {
|
||||
boolean matches(Object o);
|
||||
}
|
||||
|
||||
public static Collection removeAll(Collection c, Filter f) {
|
||||
for (Iterator it = c.iterator(); it.hasNext();) {
|
||||
Object item = it.next();
|
||||
if (f.matches(item)) it.remove();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Collection retainAll(Collection c, Filter f) {
|
||||
for (Iterator it = c.iterator(); it.hasNext();) {
|
||||
Object item = it.next();
|
||||
if (!f.matches(item)) it.remove();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public static boolean containsSome(Collection a, Collection b) {
|
||||
// fast paths
|
||||
if (a.size() == 0 || b.size() == 0) return false;
|
||||
if (a == b) return true; // must test after size test.
|
||||
|
||||
if (a instanceof SortedSet && b instanceof SortedSet) {
|
||||
SortedSet aa = (SortedSet) a;
|
||||
SortedSet bb = (SortedSet) b;
|
||||
aa.containsAll(null);
|
||||
Comparator bbc = bb.comparator();
|
||||
Comparator aac = aa.comparator();
|
||||
if (bbc == null) {
|
||||
if (aac == null) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Comparable ao = (Comparable) ai.next(); // these are ok, since the sizes are != 0
|
||||
Comparable bo = (Comparable) bi.next();
|
||||
while (true) {
|
||||
int rel = ao.compareTo(bo);
|
||||
if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = (Comparable) ai.next();
|
||||
} else if (rel > 0) {
|
||||
if (!bi.hasNext()) return false;
|
||||
bo = (Comparable) bi.next();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bbc.equals(a)) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Object ao = ai.next(); // these are ok, since the sizes are != 0
|
||||
Object bo = bi.next();
|
||||
while (true) {
|
||||
int rel = aac.compare(ao, bo);
|
||||
if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = ai.next();
|
||||
} else if (rel > 0) {
|
||||
if (!bi.hasNext()) return false;
|
||||
bo = bi.next();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator it = a.iterator(); it.hasNext();) {
|
||||
if (b.contains(it.next())) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean containsAll(Collection a, Collection b) {
|
||||
// fast paths
|
||||
if (a == b) return true;
|
||||
if (b.size() == 0) return true;
|
||||
if (a.size() == 0) return false;
|
||||
|
||||
if (a instanceof SortedSet && b instanceof SortedSet) {
|
||||
SortedSet aa = (SortedSet) a;
|
||||
SortedSet bb = (SortedSet) b;
|
||||
Comparator bbc = bb.comparator();
|
||||
Comparator aac = aa.comparator();
|
||||
if (bbc == null) {
|
||||
if (aac == null) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Comparable ao = (Comparable) ai.next(); // these are ok, since the sizes are != 0
|
||||
Comparable bo = (Comparable) bi.next();
|
||||
while (true) {
|
||||
int rel = ao.compareTo(bo);
|
||||
if (rel == 0) {
|
||||
if (!bi.hasNext()) return true;
|
||||
if (!ai.hasNext()) return false;
|
||||
bo = (Comparable) bi.next();
|
||||
ao = (Comparable) ai.next();
|
||||
} else if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = (Comparable) ai.next();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (bbc.equals(a)) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Object ao = ai.next(); // these are ok, since the sizes are != 0
|
||||
Object bo = bi.next();
|
||||
while (true) {
|
||||
int rel = aac.compare(ao, bo);
|
||||
if (rel == 0) {
|
||||
if (!bi.hasNext()) return true;
|
||||
if (!ai.hasNext()) return false;
|
||||
bo = bi.next();
|
||||
ao = ai.next();
|
||||
} else if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = ai.next();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return a.containsAll(b);
|
||||
}
|
||||
|
||||
public static boolean containsNone(Collection a, Collection b) {
|
||||
return !containsSome(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for results of getContainmentRelation
|
||||
*/
|
||||
public static final int
|
||||
ALL_EMPTY = 0,
|
||||
NOT_A_SUPERSET_B = 1,
|
||||
NOT_A_DISJOINT_B = 2,
|
||||
NOT_A_SUBSET_B = 4,
|
||||
NOT_A_EQUALS_B = NOT_A_SUBSET_B | NOT_A_SUPERSET_B,
|
||||
A_PROPER_SUBSET_OF_B = NOT_A_DISJOINT_B | NOT_A_SUPERSET_B,
|
||||
A_PROPER_SUPERSET_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B,
|
||||
A_PROPER_OVERLAPS_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B | NOT_A_SUPERSET_B;
|
||||
|
||||
/**
|
||||
* Assesses all the possible containment relations between collections A and B with one call.<br>
|
||||
* Returns an int with bits set, according to a "Venn Diagram" view of A vs B.<br>
|
||||
* NOT_A_SUPERSET_B: a - b != {}<br>
|
||||
* NOT_A_DISJOINT_B: a * b != {} // * is intersects<br>
|
||||
* NOT_A_SUBSET_B: b - a != {}<br>
|
||||
* Thus the bits can be used to get the following relations:<br>
|
||||
* for A_SUPERSET_B, use (x & CollectionUtilities.NOT_A_SUPERSET_B) == 0<br>
|
||||
* for A_SUBSET_B, use (x & CollectionUtilities.NOT_A_SUBSET_B) == 0<br>
|
||||
* for A_EQUALS_B, use (x & CollectionUtilities.NOT_A_EQUALS_B) == 0<br>
|
||||
* for A_DISJOINT_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) == 0<br>
|
||||
* for A_OVERLAPS_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) != 0<br>
|
||||
*/
|
||||
public static int getContainmentRelation(Collection a, Collection b) {
|
||||
if (a.size() == 0) {
|
||||
return (b.size() == 0) ? ALL_EMPTY : NOT_A_SUPERSET_B;
|
||||
} else if (b.size() == 0) {
|
||||
return NOT_A_SUBSET_B;
|
||||
}
|
||||
int result = 0;
|
||||
// WARNING: one might think that the following can be short-circuited, by looking at
|
||||
// the sizes of a and b. However, this would fail in general, where a different comparator is being
|
||||
// used in the two collections. Unfortunately, there is no failsafe way to test for that.
|
||||
for (Iterator it = a.iterator(); result != 6 && it.hasNext();) {
|
||||
result |= (b.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUBSET_B;
|
||||
}
|
||||
for (Iterator it = b.iterator(); (result & 3) != 3 && it.hasNext();) {
|
||||
result |= (a.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUPERSET_B;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String remove(String source, UnicodeSet removals) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
int cp;
|
||||
for (int i = 0; i < source.length(); i += UTF16.getCharCount(cp)) {
|
||||
cp = UTF16.charAt(source, i);
|
||||
if (!removals.contains(cp)) UTF16.append(result, cp);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String prettyPrint(UnicodeSet uset, boolean compressRanges, UnicodeSet toQuote, Transliterator quoter,
|
||||
Comparator ordering, Comparator spaceComparator) {
|
||||
PrettyPrinter pp = new PrettyPrinter().setCompressRanges(compressRanges);
|
||||
if (toQuote != null) pp.setToQuote(toQuote);
|
||||
if (ordering != null) pp.setOrdering(ordering);
|
||||
if (spaceComparator != null) pp.setSpaceComparator(spaceComparator);
|
||||
return pp.toPattern(uset);
|
||||
}
|
||||
|
||||
static class MultiComparator implements Comparator {
|
||||
private Comparator[] comparators;
|
||||
|
||||
public MultiComparator (Comparator[] comparators) {
|
||||
this.comparators = comparators;
|
||||
}
|
||||
|
||||
/* Lexigraphic compare. Returns the first difference
|
||||
* @return zero if equal. Otherwise +/- (i+1)
|
||||
* where i is the index of the first comparator finding a difference
|
||||
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
|
||||
*/
|
||||
public int compare(Object arg0, Object arg1) {
|
||||
for (int i = 0; i < comparators.length; ++i) {
|
||||
int result = comparators[i].compare(arg0, arg1);
|
||||
if (result == 0) continue;
|
||||
if (result > 0) return i+1;
|
||||
return -(i+1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies Unicode set to flatten the strings. Eg [abc{da}] => [abcd]
|
||||
* Returns the set for chaining.
|
||||
* @param exemplar1
|
||||
* @return
|
||||
*/
|
||||
public static UnicodeSet flatten(UnicodeSet exemplar1) {
|
||||
UnicodeSet result = new UnicodeSet();
|
||||
boolean gotString = false;
|
||||
for (UnicodeSetIterator it = new UnicodeSetIterator(exemplar1); it.nextRange();) {
|
||||
if (it.codepoint == it.IS_STRING) {
|
||||
result.addAll(it.string);
|
||||
gotString = true;
|
||||
} else {
|
||||
result.add(it.codepoint, it.codepointEnd);
|
||||
}
|
||||
}
|
||||
if (gotString) exemplar1.set(result);
|
||||
return exemplar1;
|
||||
}
|
||||
|
||||
/**
|
||||
* For producing filtered iterators
|
||||
*/
|
||||
public static abstract class FilteredIterator implements Iterator {
|
||||
private Iterator baseIterator;
|
||||
private static final Object EMPTY = new Object();
|
||||
private static final Object DONE = new Object();
|
||||
private Object nextObject = EMPTY;
|
||||
public FilteredIterator set(Iterator baseIterator) {
|
||||
this.baseIterator = baseIterator;
|
||||
return this;
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Doesn't support removal");
|
||||
}
|
||||
public Object next() {
|
||||
Object result = nextObject;
|
||||
nextObject = EMPTY;
|
||||
return result;
|
||||
}
|
||||
public boolean hasNext() {
|
||||
if (nextObject == DONE) return false;
|
||||
if (nextObject != EMPTY) return true;
|
||||
while (baseIterator.hasNext()) {
|
||||
nextObject = baseIterator.next();
|
||||
if (isIncluded(nextObject)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
nextObject = DONE;
|
||||
return false;
|
||||
}
|
||||
abstract public boolean isIncluded(Object item);
|
||||
}
|
||||
|
||||
public static class PrefixIterator extends FilteredIterator {
|
||||
private String prefix;
|
||||
public PrefixIterator set(Iterator baseIterator, String prefix) {
|
||||
super.set(baseIterator);
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
public boolean isIncluded(Object item) {
|
||||
return ((String)item).startsWith(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegexIterator extends FilteredIterator {
|
||||
private Matcher matcher;
|
||||
public RegexIterator set(Iterator baseIterator, Matcher matcher) {
|
||||
super.set(baseIterator);
|
||||
this.matcher = matcher;
|
||||
return this;
|
||||
}
|
||||
public boolean isIncluded(Object item) {
|
||||
return matcher.reset((String)item).matches();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
231
icu4j/src/com/ibm/icu/impl/PrettyPrinter.java
Normal file
231
icu4j/src/com/ibm/icu/impl/PrettyPrinter.java
Normal file
@ -0,0 +1,231 @@
|
||||
/**
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2005, international Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import com.ibm.icu.impl.CollectionUtilities.MultiComparator;
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.text.Collator;
|
||||
import com.ibm.icu.text.RuleBasedCollator;
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
import com.ibm.icu.text.UTF16;
|
||||
import com.ibm.icu.text.UnicodeSet;
|
||||
import com.ibm.icu.text.UnicodeSetIterator;
|
||||
import com.ibm.icu.util.ULocale;
|
||||
|
||||
/** Provides more flexible formatting of UnicodeSet patterns.
|
||||
*/
|
||||
public class PrettyPrinter {
|
||||
private static UnicodeSet patternWhitespace = new UnicodeSet("[[:Cn:][:Default_Ignorable_Code_Point:][:patternwhitespace:]]");
|
||||
|
||||
private boolean first = true;
|
||||
private StringBuffer target = new StringBuffer();
|
||||
private int firstCodePoint = -2;
|
||||
private int lastCodePoint = -2;
|
||||
private boolean compressRanges = true;
|
||||
private String lastString = "";
|
||||
private UnicodeSet toQuote = new UnicodeSet(patternWhitespace);
|
||||
private Transliterator quoter = null;
|
||||
|
||||
private Comparator ordering;
|
||||
private Comparator spaceComp = Collator.getInstance(ULocale.ROOT);
|
||||
{
|
||||
setOrdering(Collator.getInstance(ULocale.ROOT));
|
||||
((RuleBasedCollator)spaceComp).setStrength(RuleBasedCollator.PRIMARY);
|
||||
}
|
||||
|
||||
public Transliterator getQuoter() {
|
||||
return quoter;
|
||||
}
|
||||
|
||||
public PrettyPrinter setQuoter(Transliterator quoter) {
|
||||
this.quoter = quoter;
|
||||
return this; // for chaining
|
||||
}
|
||||
|
||||
public boolean isCompressRanges() {
|
||||
return compressRanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param compressRanges if you want abcde instead of a-e, make this false
|
||||
* @return
|
||||
*/
|
||||
public PrettyPrinter setCompressRanges(boolean compressRanges) {
|
||||
this.compressRanges = compressRanges;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Comparator getOrdering() {
|
||||
return ordering;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ordering the resulting ordering of the list of characters in the pattern
|
||||
* @return
|
||||
*/
|
||||
public PrettyPrinter setOrdering(Comparator ordering) {
|
||||
this.ordering = new MultiComparator(new Comparator[] {ordering, new UTF16.StringComparator(true,false,0)});
|
||||
return this;
|
||||
}
|
||||
|
||||
public Comparator getSpaceComparator() {
|
||||
return spaceComp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param spaceComp if the comparison returns non-zero, then a space will be inserted between characters
|
||||
* @return this, for chaining
|
||||
*/
|
||||
public PrettyPrinter setSpaceComparator(Comparator spaceComp) {
|
||||
this.spaceComp = spaceComp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public UnicodeSet getToQuote() {
|
||||
return toQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* a UnicodeSet of extra characters to quote with \\uXXXX-style escaping (will automatically quote pattern whitespace)
|
||||
* @param toQuote
|
||||
*/
|
||||
public void setToQuote(UnicodeSet toQuote) {
|
||||
toQuote = (UnicodeSet)toQuote.clone();
|
||||
toQuote.addAll(patternWhitespace);
|
||||
this.toQuote = toQuote;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pattern for a particular set.
|
||||
* @param uset
|
||||
* @return formatted UnicodeSet
|
||||
*/
|
||||
public String toPattern(UnicodeSet uset) {
|
||||
// make sure that comparison separates all strings, even canonically equivalent ones
|
||||
Set orderedStrings = new TreeSet(ordering);
|
||||
for (UnicodeSetIterator it = new UnicodeSetIterator(uset); it.next();) {
|
||||
orderedStrings.add(it.getString());
|
||||
}
|
||||
target.setLength(0);
|
||||
target.append("[");
|
||||
for (Iterator it = orderedStrings.iterator(); it.hasNext();) {
|
||||
appendUnicodeSetItem((String) it.next());
|
||||
}
|
||||
flushLast();
|
||||
target.append("]");
|
||||
String sresult = target.toString();
|
||||
UnicodeSet doubleCheck = new UnicodeSet(sresult);
|
||||
if (!uset.equals(doubleCheck)) {
|
||||
throw new InternalError("Failure to round-trip in pretty-print");
|
||||
}
|
||||
return sresult;
|
||||
}
|
||||
|
||||
PrettyPrinter appendUnicodeSetItem(String s) {
|
||||
int cp;
|
||||
if (UTF16.hasMoreCodePointsThan(s, 1)) {
|
||||
flushLast();
|
||||
addSpace(s);
|
||||
target.append("{");
|
||||
for (int i = 0; i < s.length(); i += UTF16.getCharCount(cp)) {
|
||||
appendQuoted(cp = UTF16.charAt(s, i));
|
||||
}
|
||||
target.append("}");
|
||||
lastString = s;
|
||||
} else {
|
||||
if (!compressRanges)
|
||||
flushLast();
|
||||
cp = UTF16.charAt(s, 0);
|
||||
if (cp == lastCodePoint + 1) {
|
||||
lastCodePoint = cp; // continue range
|
||||
} else { // start range
|
||||
flushLast();
|
||||
firstCodePoint = lastCodePoint = cp;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void addSpace(String s) {
|
||||
if (first) {
|
||||
first = false;
|
||||
} else if (spaceComp.compare(s, lastString) != 0) {
|
||||
target.append(' ');
|
||||
} else {
|
||||
int type = UCharacter.getType(UTF16.charAt(s,0));
|
||||
if (type == UCharacter.NON_SPACING_MARK || type == UCharacter.ENCLOSING_MARK) {
|
||||
target.append(' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void flushLast() {
|
||||
if (lastCodePoint >= 0) {
|
||||
addSpace(UTF16.valueOf(firstCodePoint));
|
||||
if (firstCodePoint != lastCodePoint) {
|
||||
appendQuoted(firstCodePoint);
|
||||
target.append(firstCodePoint + 1 == lastCodePoint ? ' ' : '-');
|
||||
}
|
||||
appendQuoted(lastCodePoint);
|
||||
lastString = UTF16.valueOf(lastCodePoint);
|
||||
firstCodePoint = lastCodePoint = -2;
|
||||
}
|
||||
}
|
||||
PrettyPrinter appendQuoted(int codePoint) {
|
||||
if (toQuote.contains(codePoint)) {
|
||||
if (quoter != null) {
|
||||
target.append(quoter.transliterate(UTF16.valueOf(codePoint)));
|
||||
return this;
|
||||
}
|
||||
if (codePoint > 0xFFFF) {
|
||||
target.append("\\U");
|
||||
target.append(Utility.hex(codePoint,8));
|
||||
} else {
|
||||
target.append("\\u");
|
||||
target.append(Utility.hex(codePoint,4));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
switch (codePoint) {
|
||||
case '[': // SET_OPEN:
|
||||
case ']': // SET_CLOSE:
|
||||
case '-': // HYPHEN:
|
||||
case '^': // COMPLEMENT:
|
||||
case '&': // INTERSECTION:
|
||||
case '\\': //BACKSLASH:
|
||||
case '{':
|
||||
case '}':
|
||||
case '$':
|
||||
case ':':
|
||||
target.append('\\');
|
||||
break;
|
||||
default:
|
||||
// Escape whitespace
|
||||
if (patternWhitespace.contains(codePoint)) {
|
||||
target.append('\\');
|
||||
}
|
||||
break;
|
||||
}
|
||||
UTF16.append(target, codePoint);
|
||||
return this;
|
||||
}
|
||||
// Appender append(String s) {
|
||||
// target.append(s);
|
||||
// return this;
|
||||
// }
|
||||
// public String toString() {
|
||||
// return target.toString();
|
||||
// }
|
||||
}
|
Loading…
Reference in New Issue
Block a user