1 /* GENERATED SOURCE. DO NOT MODIFY. */ 2 // 2016 and later: Unicode, Inc. and others. 3 // License & terms of use: http://www.unicode.org/copyright.html#License 4 /* 5 ******************************************************************************* 6 * Copyright (C) 1996-2011, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ******************************************************************************* 9 */ 10 package android.icu.text; 11 12 import android.icu.impl.UCaseProps; 13 import android.icu.lang.UCharacter; 14 import android.icu.util.ULocale; 15 16 /** 17 * A transliterator that performs locale-sensitive toUpper() 18 * case mapping. 19 */ 20 class UppercaseTransliterator extends Transliterator { 21 22 /** 23 * Package accessible ID. 24 */ 25 static final String _ID = "Any-Upper"; 26 // TODO: Add variants for tr/az, el, lt, default = default locale: ICU ticket #12720 27 28 /** 29 * System registration hook. 30 */ 31 static void register() { 32 Transliterator.registerFactory(_ID, new Transliterator.Factory() { 33 @Override 34 public Transliterator getInstance(String ID) { 35 return new UppercaseTransliterator(ULocale.US); 36 } 37 }); 38 } 39 40 private final ULocale locale; 41 42 private final UCaseProps csp; 43 private ReplaceableContextIterator iter; 44 private StringBuilder result; 45 private int caseLocale; 46 47 /** 48 * Constructs a transliterator. 49 */ 50 public UppercaseTransliterator(ULocale loc) { 51 super(_ID, null); 52 locale = loc; 53 csp=UCaseProps.INSTANCE; 54 iter=new ReplaceableContextIterator(); 55 result = new StringBuilder(); 56 caseLocale = UCaseProps.getCaseLocale(locale); 57 } 58 59 /** 60 * Implements {@link Transliterator#handleTransliterate}. 61 */ 62 @Override 63 protected synchronized void handleTransliterate(Replaceable text, 64 Position offsets, boolean isIncremental) { 65 if(csp==null) { 66 return; 67 } 68 69 if(offsets.start >= offsets.limit) { 70 return; 71 } 72 73 iter.setText(text); 74 result.setLength(0); 75 int c, delta; 76 77 // Walk through original string 78 // If there is a case change, modify corresponding position in replaceable 79 80 iter.setIndex(offsets.start); 81 iter.setLimit(offsets.limit); 82 iter.setContextLimits(offsets.contextStart, offsets.contextLimit); 83 while((c=iter.nextCaseMapCP())>=0) { 84 c=csp.toFullUpper(c, iter, result, caseLocale); 85 86 if(iter.didReachLimit() && isIncremental) { 87 // the case mapping function tried to look beyond the context limit 88 // wait for more input 89 offsets.start=iter.getCaseMapCPStart(); 90 return; 91 } 92 93 /* decode the result */ 94 if(c<0) { 95 /* c mapped to itself, no change */ 96 continue; 97 } else if(c<=UCaseProps.MAX_STRING_LENGTH) { 98 /* replace by the mapping string */ 99 delta=iter.replace(result.toString()); 100 result.setLength(0); 101 } else { 102 /* replace by single-code point mapping */ 103 delta=iter.replace(UTF16.valueOf(c)); 104 } 105 106 if(delta!=0) { 107 offsets.limit += delta; 108 offsets.contextLimit += delta; 109 } 110 } 111 offsets.start = offsets.limit; 112 } 113 114 // NOTE: normally this would be static, but because the results vary by locale.... 115 SourceTargetUtility sourceTargetUtility = null; 116 117 /* (non-Javadoc) 118 * @see android.icu.text.Transliterator#addSourceTargetSet(android.icu.text.UnicodeSet, android.icu.text.UnicodeSet, android.icu.text.UnicodeSet) 119 */ 120 @Override 121 public void addSourceTargetSet(UnicodeSet inputFilter, UnicodeSet sourceSet, UnicodeSet targetSet) { 122 synchronized (this) { 123 if (sourceTargetUtility == null) { 124 sourceTargetUtility = new SourceTargetUtility(new Transform<String,String>() { 125 @Override 126 public String transform(String source) { 127 return UCharacter.toUpperCase(locale, source); 128 } 129 }); 130 } 131 } 132 sourceTargetUtility.addSourceTargetSet(this, inputFilter, sourceSet, targetSet); 133 } 134 } 135