//---------------------------------------------------------------------- // BEGIN Debugging support //----------------------------------------------------------------------
/** *@paramappendToresultisappendedtothisparam. *@paraminputthestringbeingtransliterated *@parampostheindexstruct
*/ static UnicodeString& _formatInput(UnicodeString &appendTo, const UnicodeString& input, const UTransPosition& pos) { // Output a string of the form aaa{bbb|ccc|ddd}eee, where // the {} indicate the context start and limit, and the || // indicate the start and limit. if (0 <= pos.contextStart &&
pos.contextStart <= pos.start &&
pos.start <= pos.limit &&
pos.limit <= pos.contextLimit &&
pos.contextLimit <= input.length()) {
//---------------------------------------------------------------------- // END Debugging support //----------------------------------------------------------------------
// Fill the precontext and postcontext with the patterns of the rules // that are masking one another. staticvoid maskingError(const icu::TransliterationRule& rule1, const icu::TransliterationRule& rule2,
UParseError& parseError) {
icu::UnicodeString r;
int32_t len;
parseError.line = parseError.offset = -1;
// for pre-context
rule1.toRule(r, false);
len = uprv_min(r.length(), U_PARSE_CONTEXT_LEN-1);
r.extract(0, len, parseError.preContext);
parseError.preContext[len] = 0;
/** *Checkthisformaskedrulesandindexittooptimizeperformance. *Thesequenceofoperationsis:(1)addrulestoasetusing *<code>addRule()</code>;(2)freezethesetusing *<code>freeze()</code>;(3)usetheruleset.If *<code>addRule()</code>iscalledaftercallingthismethod,it *invalidatesthisobject,andthismethodmustbecalledagain. *Thatis,<code>freeze()</code>maybecalledmultipletimes, *althoughforoptimalperformanceitshouldn'tbe.
*/ void TransliterationRuleSet::freeze(UParseError& parseError,UErrorCode& status) { /* Construct the rule array and index table. We reorder the *rulesbysortingtheminto256bins.Eachbincontainsall *rulesmatchingtheindexvalueforthatbin.Arule *matchesanindexvalueifstringwhosefirstkeycharacter *hasalowbyteequaltotheindexvaluecanmatchtherule. * *Eachbincontainszeroormorerules,inthesameorder *theywerefoundoriginally.However,thetotalrulesin *thebinsmayexceedthenumberintheoriginalvector, *sincerulesthathaveavariableastheirfirstkey *characterwillgenerallyfallintomorethanonebin. * *Thatis,eachbincontainsallrulesthateitherhavethat *firstindexvalueastheirfirstkeycharacter,orhave *asetcontainingtheindexvalueastheirfirstcharacter.
*/
int32_t n = ruleVector->size();
int32_t j;
int16_t x;
UVector v(2*n, status); // heuristic; adjust as needed
if (U_FAILURE(status)) { return;
}
/* Precompute the index values. This saves a LOT of time. *Becarefulnottocallmalloc(0).
*/
int16_t* indexValue = static_cast<int16_t*>(uprv_malloc(sizeof(int16_t) * (n > 0 ? n : 1))); /* test for nullptr */ if (indexValue == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR; return;
} for (j=0; j<n; ++j) {
TransliterationRule* r = static_cast<TransliterationRule*>(ruleVector->elementAt(j));
indexValue[j] = r->getIndexValue();
} for (x=0; x<256; ++x) {
index[x] = v.size(); for (j=0; j<n; ++j) { if (indexValue[j] >= 0) { if (indexValue[j] == x) {
v.addElement(ruleVector->elementAt(j), status);
}
} else { // If the indexValue is < 0, then the first key character is // a set, and we must use the more time-consuming // matchesIndexValue check. In practice this happens // rarely, so we seldom treat this code path.
TransliterationRule* r = static_cast<TransliterationRule*>(ruleVector->elementAt(j)); if (r->matchesIndexValue(static_cast<uint8_t>(x))) {
v.addElement(r, status);
}
}
}
}
uprv_free(indexValue);
index[256] = v.size(); if (U_FAILURE(status)) { return;
}
/* Freeze things into an array.
*/
uprv_free(rules); // Contains alias pointers
/* You can't do malloc(0)! */ if (v.size() == 0) {
rules = nullptr; return;
}
rules = static_cast<TransliterationRule**>(uprv_malloc(v.size() * sizeof(TransliterationRule*))); /* test for nullptr */ if (rules == nullptr) {
status = U_MEMORY_ALLOCATION_ERROR; return;
} for (j=0; j<v.size(); ++j) {
rules[j] = static_cast<TransliterationRule*>(v.elementAt(j));
}
// TODO Add error reporting that indicates the rules that // are being masked. //UnicodeString errors;
/* Check for masking. This is MUCH faster than our old check, *whichwaseachruleagainsteachfollowingrule,sincewe *onlyhavetocheckformaskingwithineachbinnow.It's *256*O(n2^2)insteadofO(n1^2),wheren1isthetotalrule *count,andn2istheper-binrulecount.Butn2<<n1,so *it'sabigwin.
*/ for (x=0; x<256; ++x) { for (j=index[x]; j<index[x+1]-1; ++j) {
TransliterationRule* r1 = rules[j]; for (int32_t k=j+1; k<index[x+1]; ++k) {
TransliterationRule* r2 = rules[k]; if (r1->masks(*r2)) { //| if (errors == null) { //| errors = new StringBuffer(); //| } else { //| errors.append("\n"); //| } //| errors.append("Rule " + r1 + " masks " + r2);
status = U_RULE_MASK_ERROR;
maskingError(*r1, *r2, parseError); return;
}
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.