mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-14 09:21:03 +00:00
ICU-7273 compute FC_NFKC_Closure on the fly
X-SVN-Rev: 27528
This commit is contained in:
parent
7c628650b3
commit
47b794991d
3 changed files with 48 additions and 49 deletions
|
@ -360,41 +360,6 @@ public final class NormalizerImpl {
|
|||
|
||||
return false; /* not found */
|
||||
}
|
||||
|
||||
public static int getFC_NFKC_Closure(int c, char[] dest) {
|
||||
|
||||
int destCapacity;
|
||||
|
||||
if(dest==null ) {
|
||||
destCapacity=0;
|
||||
}else{
|
||||
destCapacity = dest.length;
|
||||
}
|
||||
|
||||
int aux =AuxTrieImpl.auxTrie.getCodePointValue(c);
|
||||
|
||||
aux&= AUX_FNC_MASK;
|
||||
if(aux!=0) {
|
||||
int s;
|
||||
int index=aux;
|
||||
int length;
|
||||
|
||||
s =extraData[index];
|
||||
if(s<0xff00) {
|
||||
/* s points to the single-unit string */
|
||||
length=1;
|
||||
} else {
|
||||
length=s&0xff;
|
||||
++index;
|
||||
}
|
||||
if(0<length && length<=destCapacity) {
|
||||
System.arraycopy(extraData,index,dest,0,length);
|
||||
}
|
||||
return length;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static UnicodeSet addPropertyStarts(UnicodeSet set) {
|
||||
int c;
|
||||
|
|
|
@ -1252,29 +1252,62 @@ public final class Normalizer implements Cloneable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Gets the FC_NFKC closure set from the normalization data
|
||||
* @param c The code point whose closure set is to be retrieved
|
||||
* @param dest The char array to receive the closure set
|
||||
* Gets the FC_NFKC closure value.
|
||||
* @param c The code point whose closure value is to be retrieved
|
||||
* @param dest The char array to receive the closure value
|
||||
* @return the length of the closure value; 0 if there is none
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public static int getFC_NFKC_Closure(int c,char[] dest) {
|
||||
return NormalizerImpl.getFC_NFKC_Closure(c,dest);
|
||||
String closure=getFC_NFKC_Closure(c);
|
||||
int length=closure.length();
|
||||
if(length!=0 && dest!=null && length<=dest.length) {
|
||||
closure.getChars(0, length, dest, 0);
|
||||
}
|
||||
return length;
|
||||
}
|
||||
/**
|
||||
* Gets the FC_NFKC closure set from the normalization data
|
||||
* @param c The the code point whose closure set is to be retrieved
|
||||
* @return String representation of the closure set
|
||||
* Gets the FC_NFKC closure value.
|
||||
* @param c The code point whose closure value is to be retrieved
|
||||
* @return String representation of the closure value; "" if there is none
|
||||
* @stable ICU 3.8
|
||||
*/
|
||||
public static String getFC_NFKC_Closure(int c) {
|
||||
char[] dest = new char[10];
|
||||
for(;;) {
|
||||
int length = getFC_NFKC_Closure(c,dest);
|
||||
if(length<=dest.length) {
|
||||
return new String(dest,0,length);
|
||||
} else {
|
||||
dest = new char[length];
|
||||
// Compute the FC_NFKC_Closure on the fly:
|
||||
// We have the API for complete coverage of Unicode properties, although
|
||||
// this value by itself is not useful via API.
|
||||
// (What could be useful is a custom normalization table that combines
|
||||
// case folding and NFKC.)
|
||||
// For the derivation, see Unicode's DerivedNormalizationProps.txt.
|
||||
Normalizer2Impl nfkcImpl=Norm2AllModes.getNFKCInstanceNoIOException().impl;
|
||||
UCaseProps csp;
|
||||
try {
|
||||
csp=UCaseProps.getSingleton();
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
// first: b = NFKC(Fold(a))
|
||||
StringBuffer folded=new StringBuffer();
|
||||
String kc1;
|
||||
int folded1Length=csp.toFullFolding(c, folded, 0);
|
||||
if(folded1Length<0) {
|
||||
kc1=nfkcImpl.getDecomposition(c);
|
||||
if(kc1==null) {
|
||||
return ""; // c does not change at all under CaseFolding+NFKC
|
||||
}
|
||||
} else {
|
||||
if(folded1Length>UCaseProps.MAX_STRING_LENGTH) {
|
||||
folded.appendCodePoint(folded1Length);
|
||||
}
|
||||
kc1=NFKC.normalizer2.normalize(folded);
|
||||
}
|
||||
// second: c = NFKC(Fold(b))
|
||||
String kc2=NFKC.normalizer2.normalize(UCharacter.foldCase(kc1, 0));
|
||||
// if (c != b) add the mapping from a to c
|
||||
if(kc1.equals(kc2)) {
|
||||
return "";
|
||||
} else {
|
||||
return kc2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2207,6 +2207,7 @@ public class BasicTest extends TestFmwk {
|
|||
}
|
||||
|
||||
TestStruct[] tests= new TestStruct[]{
|
||||
new TestStruct( 0x00C4, "" ),
|
||||
new TestStruct( 0x037A, "\u0020\u03B9" ),
|
||||
new TestStruct( 0x03D2, "\u03C5" ),
|
||||
new TestStruct( 0x20A8, "\u0072\u0073" ) ,
|
||||
|
|
Loading…
Add table
Reference in a new issue