private void PopulateTags(MerchantTribeApplication app) { List <IReplaceable> items = new List <IReplaceable>(); // Default Tags Replaceable defaultTags = new Replaceable(); defaultTags.Tags.AddRange(new HtmlTemplate().DefaultReplacementTags(app)); items.Add(defaultTags); // Objects with tags items.Add(new MailingListMember()); items.Add(new CustomerAccount()); items.Add(new VendorManufacturer()); items.Add(new Order()); items.Add(new LineItem()); items.Add(new OrderPackage()); items.Add(new Product()); // Get all tags from everything into one big list List <HtmlTemplateTag> t = new List <HtmlTemplateTag>(); foreach (IReplaceable r in items) { t.AddRange(r.GetReplaceableTags(app)); } this.Tags.DataSource = t; this.Tags.DataValueField = "Tag"; this.Tags.DataTextField = "Tag"; this.Tags.DataBind(); }
/// <summary> /// Constructs a run iterator over the given text from start (inclusive) /// to limit (exclusive). /// </summary> /// public ScriptRunIterator(Replaceable text_0, int start_1, int limit_2) { this.text = text_0; this.textStart = start_1; this.textLimit = limit_2; this.limit = start_1; }
/// <summary> /// Default implementation of UnicodeMatcher::matches() for Unicode filters. /// Matches a single 16-bit code unit at offset. /// </summary> /// /// @stable ICU 2.0 public virtual int Matches(Replaceable text, int[] offset, int limit, bool incremental) { int c; if (offset[0] < limit && Contains(c = text.Char32At(offset[0]))) { offset[0] += IBM.ICU.Text.UTF16.GetCharCount(c); return(IBM.ICU.Text.UnicodeMatcher_Constants.U_MATCH); } if (offset[0] > limit && Contains(c = text.Char32At(offset[0]))) { // Backup offset by 1, unless the preceding character is a // surrogate pair -- then backup by 2 (keep offset pointing at // the lead surrogate). --offset[0]; if (offset[0] >= 0) { offset[0] -= IBM.ICU.Text.UTF16.GetCharCount(text.Char32At(offset[0])) - 1; } return(IBM.ICU.Text.UnicodeMatcher_Constants.U_MATCH); } if (incremental && offset[0] == limit) { return(IBM.ICU.Text.UnicodeMatcher_Constants.U_PARTIAL_MATCH); } return(IBM.ICU.Text.UnicodeMatcher_Constants.U_MISMATCH); }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position offsets, bool isIncremental) { int start = offsets.start; int limit = offsets.limit; if (start >= limit) { return; } int overallDelta = 0; // Walk through the string looking for safe characters. // Whenever you hit one normalize from the start of the last // safe character up to just before the next safe character // Also, if you hit the end and we are not in incremental mode, // do to end. // TODO: fix for surrogates // TODO: add QuickCheck, so we rarely convert OK stuff int lastSafe = start; // go back to start in any event int cp; for (int i = start + 1; i < limit; i += IBM.ICU.Text.UTF16.GetCharCount(cp)) { cp = text.Char32At(i); if (IBM.ICU.Lang.UCharacter.GetCombiningClass(cp) == 0 && !unsafeStart.Contains(cp)) { int delta = Convert(text, lastSafe, i, null); i += delta; limit += delta; overallDelta += delta; lastSafe = i; } } if (!isIncremental) { int delta_0 = Convert(text, lastSafe, limit, null); overallDelta += delta_0; lastSafe = limit + delta_0; } else { // We are incremental, so accept the last characters IF they turn // into skippables int delta_1 = Convert(text, lastSafe, limit, skippable); if (delta_1 != Int32.MinValue) { overallDelta += delta_1; lastSafe = limit + delta_1; } } offsets.contextLimit += overallDelta; offsets.limit += overallDelta; offsets.start = lastSafe; }
/// <summary> /// Set the text for iteration. /// </summary> /// /// <param name="rep">Iteration text.</param> public void SetText(Replaceable rep) { this.rep = rep; limit = contextLimit = rep.Length(); cpStart = cpLimit = index = contextStart = 0; dir = 0; reachedLimit = false; }
// public constructor ------------------------------------------------------ /// <summary> /// Public constructor /// </summary> /// /// <param name="replaceable">text which the iterator will be based on</param> public ReplaceableUCharacterIterator(Replaceable replaceable) { if (replaceable == null) { throw new ArgumentException(); } this.replaceable = replaceable; this.currentIndex = 0; }
protected override Expression VisitInvocation(InvocationExpression expression) { if (expression.ToString() == Replaceable.ToString()) { return(Replacer); } return(base.VisitInvocation(expression)); }
/// <summary> /// Reset this iterator to point to a new string. This package-visible /// method is used by other java.text classes that want to avoid /// allocating new ReplaceableCharacterIterator objects every time their /// setText method is called. /// </summary> /// /// <param name="text_0">The String to be iterated over</param> public void SetText(Replaceable text_0) { if (text_0 == null) { throw new NullReferenceException(); } this.text = text_0; this.begin = 0; this.end = text_0.Length(); this.pos = 0; }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position index, bool incremental) { // Our caller (filteredTransliterate) has already narrowed us // to an unfiltered run. Delete it. text.Replace(index.start, index.limit, ""); int len = index.limit - index.start; index.contextLimit -= len; index.limit -= len; }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position pos, bool isIncremental) { int allStart = pos.start; int allLimit = pos.limit; AnyTransliterator.ScriptRunIterator it = new AnyTransliterator.ScriptRunIterator(text, pos.contextStart, pos.contextLimit); while (it.Next()) { // Ignore runs in the ante context if (it.limit <= allStart) { continue; } // Try to instantiate transliterator from it.scriptCode to // our target or target/variant Transliterator t = GetTransliterator(it.scriptCode); if (t == null) { // We have no transliterator. Do nothing, but keep // pos.start up to date. pos.start = it.limit; continue; } // If the run end is before the transliteration limit, do // a non-incremental transliteration. Otherwise do an // incremental one. bool incremental = isIncremental && (it.limit >= allLimit); pos.start = Math.Max(allStart, it.start); pos.limit = Math.Min(allLimit, it.limit); int limit = pos.limit; t.FilteredTransliterate(text, pos, incremental); int delta = pos.limit - limit; allLimit += delta; it.AdjustLimit(delta); // We're done if we enter the post context if (it.limit >= allLimit) { break; } } // Restore limit. pos.start is fine where the last transliterator // left it, or at the end of the last run. pos.limit = allLimit; }
/// <summary> /// UnicodeReplacer API /// </summary> /// public virtual int Replace(Replaceable text, int start, int limit, int[] cursor) { // First delegate to subordinate replacer int len = replacer.Replace(text, start, limit, cursor); limit = start + len; // Now transliterate limit = translit.Transliterate(text, start, limit); return(limit - start); }
public void SetParser_SingleOutput_Test() { var anyParser = Any(); var failParser = Fail <char>(); var target = new Replaceable <char, char> .SingleParser(failParser); target.SetParser(anyParser); var input = new StringCharacterSequence("abc"); var result = target.Parse(input); result.Value.Should().Be('a'); }
/// <summary> /// Transliterate the given text with the given UTransPosition indices. /// Return TRUE if the transliteration should continue or FALSE if it should /// halt (because of a U_PARTIAL_MATCH match). Note that FALSE is only ever /// returned if isIncremental is TRUE. /// </summary> /// /// <param name="text">the text to be transliterated</param> /// <param name="pos">the position indices, which will be updated</param> /// <param name="incremental">if TRUE, assume new text may be inserted at index.limit, andreturn FALSE if thre is a partial match.</param> /// <returns>TRUE unless a U_PARTIAL_MATCH has been obtained, indicating that /// transliteration should stop until more text arrives.</returns> public bool Transliterate(Replaceable text, Transliterator.Position pos, bool incremental) { int indexByte = text.Char32At(pos.start) & 0xFF; for (int i = index[indexByte]; i < index[indexByte + 1]; ++i) { int m = rules[i].MatchAndReplace(text, pos, incremental); switch (m) { case IBM.ICU.Text.UnicodeMatcher_Constants.U_MATCH: if (IBM.ICU.Text.Transliterator.DEBUG) { System.Console.Out.WriteLine(((incremental) ? "Rule.i: match " : "Rule: match ") + rules[i].ToRule(true) + " => " + IBM.ICU.Impl.UtilityExtensions.FormatInput(text, pos)); } return(true); case IBM.ICU.Text.UnicodeMatcher_Constants.U_PARTIAL_MATCH: if (IBM.ICU.Text.Transliterator.DEBUG) { System.Console.Out .WriteLine(((incremental) ? "Rule.i: partial match " : "Rule: partial match ") + rules[i].ToRule(true) + " => " + IBM.ICU.Impl.UtilityExtensions.FormatInput(text, pos)); } return(false); default: if (IBM.ICU.Text.Transliterator.DEBUG) { System.Console.Out.WriteLine("Rule: no match " + rules[i]); } break; } } // No match or partial match from any rule pos.start += IBM.ICU.Text.UTF16.GetCharCount(text.Char32At(pos.start)); if (IBM.ICU.Text.Transliterator.DEBUG) { System.Console.Out.WriteLine(((incremental) ? "Rule.i: no match => " : "Rule: no match => ") + IBM.ICU.Impl.UtilityExtensions.FormatInput(text, pos)); } return(true); }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position pos, bool incremental) { int start = pos.start; int limit = pos.limit; StringBuilder buf = new StringBuilder(prefix); int prefixLen = prefix.Length; bool redoPrefix = false; while (start < limit) { int c = (grokSupplementals) ? (int)(text.Char32At(start)) : (int)(text.CharAt(start)); int charLen = (grokSupplementals) ? IBM.ICU.Text.UTF16.GetCharCount(c) : 1; if ((c & -65536) != 0 && supplementalHandler != null) { buf.Length = 0; buf.Append(supplementalHandler.prefix); IBM.ICU.Impl.Utility.AppendNumber(buf, c, supplementalHandler.radix, supplementalHandler.minDigits); buf.Append(supplementalHandler.suffix); redoPrefix = true; } else { if (redoPrefix) { buf.Length = 0; buf.Append(prefix); redoPrefix = false; } else { buf.Length = prefixLen; } IBM.ICU.Impl.Utility.AppendNumber(buf, c, radix, minDigits); buf.Append(suffix); } text.Replace(start, start + charLen, buf.ToString()); start += buf.Length; limit += buf.Length - charLen; } pos.contextLimit += limit - pos.limit; pos.limit = limit; pos.start = start; }
public override int GetHashCode() { var hashCode = -81208087; hashCode = hashCode * -1521134295 + Color.GetHashCode(); hashCode = hashCode * -1521134295 + PushReaction.GetHashCode(); hashCode = hashCode * -1521134295 + BlocksMovement.GetHashCode(); hashCode = hashCode * -1521134295 + Flammable.GetHashCode(); hashCode = hashCode * -1521134295 + RequiresNoTool.GetHashCode(); hashCode = hashCode * -1521134295 + Liquid.GetHashCode(); hashCode = hashCode * -1521134295 + Opaque.GetHashCode(); hashCode = hashCode * -1521134295 + Replaceable.GetHashCode(); hashCode = hashCode * -1521134295 + Solid.GetHashCode(); return(hashCode); }
private void SendEmails(List <CustomerAccount> users, HccRequestContext hccContext) { HccRequestContext.Current = hccContext; var contentService = Factory.CreateService <ContentService>(hccContext); var template = contentService.GetHtmlTemplateOrDefault(HtmlTemplateType.ContactAbandonedCartUsers); var customMessage = txtCustomMessage.Text.Trim(); var customMessageTag = new Replaceable("[[CustomMessage]]", customMessage); template = template.ReplaceTagsInTemplate(hccContext, customMessageTag); foreach (var user in users) { if (user != null && !string.IsNullOrEmpty(user.Email)) { var mailMessage = template.ConvertToMailMessage(user.Email); MailServices.SendMail(mailMessage, hccContext.CurrentStore); } } }
public void SendNewRolesAssignment(CustomerAccount acc, string[] roles) { var roleTags = new Replaceable("[[User.NewRoles]]", string.Join(", ", roles)); var storeSettingsProvider = Factory.CreateStoreSettingsProvider(); var defaultCulture = storeSettingsProvider.GetDefaultLocale(); var hccRequestContext = HccRequestContextUtils.GetContextWithCulture(Context, defaultCulture); var contentService = Factory.CreateService <ContentService>(hccRequestContext); var template = contentService.GetHtmlTemplateOrDefault(HtmlTemplateType.NewRoleAssignment); template = template.ReplaceTagsInTemplate(hccRequestContext, new List <IReplaceable> { acc, roleTags }); var message = template.ConvertToMailMessage(acc.Email); MailServices.SendMail(message, hccRequestContext.CurrentStore); }
/// <summary> /// Converts the range from lastSafe to limit. /// </summary> /// /// <param name="verify">If non-null, check to see that all replacement characters arein it. If not, abort the conversion and returnInteger.MIN_VALUE.</param> /// <returns>return the delta in length (new - old), or Integer.MIN_VALUE if /// the verify aborted.</returns> internal int Convert(Replaceable text, int lastSafe, int limit, UnicodeSet verify) { // System.out.println("t: " + // com.ibm.icu.impl.Utility.hex(text.toString()) + ", s: " + lastSafe + // ", l: " + limit); int len = limit - lastSafe; String input = null; lock (buffer) { if (buffer.Length < len) { buffer = new char[len]; // rare, and we don't care if we grow // too large } text.GetChars(lastSafe, limit, buffer, 0); input = new String(buffer, 0, len); // TODO: fix normalizer to take // char[] } String output = IBM.ICU.Text.Normalizer.Normalize(input, mode, options); // verify OK, if specified if (verify != null) { bool skip = !skippable.ContainsAll(output); if (DEBUG) { System.Console.Out.WriteLine(((skip) ? " SKIP: " : "NOSKIP: ") + IBM.ICU.Impl.Utility.Escape(input) + " => " + IBM.ICU.Impl.Utility.Escape(output)); } if (skip) { return(Int32.MinValue); } } if (output.Equals(input)) { return(0); } text.Replace(lastSafe, limit, output); return(output.Length - len); }
/// <summary> /// Implement UnicodeMatcher API. /// </summary> /// public virtual int Matches(Replaceable text, int[] offset, int limit, bool incremental) { int start = offset[0]; int count = 0; while (count < maxCount) { int pos = offset[0]; int m = matcher.Matches(text, offset, limit, incremental); if (m == IBM.ICU.Text.UnicodeMatcher_Constants.U_MATCH) { ++count; if (pos == offset[0]) { // If offset has not moved we have a zero-width match. // Don't keep matching it infinitely. break; } } else if (incremental && m == IBM.ICU.Text.UnicodeMatcher_Constants.U_PARTIAL_MATCH) { return(IBM.ICU.Text.UnicodeMatcher_Constants.U_PARTIAL_MATCH); } else { break; } } if (incremental && offset[0] == limit) { return(IBM.ICU.Text.UnicodeMatcher_Constants.U_PARTIAL_MATCH); } if (count >= minCount) { return(IBM.ICU.Text.UnicodeMatcher_Constants.U_MATCH); } offset[0] = start; return(IBM.ICU.Text.UnicodeMatcher_Constants.U_MISMATCH); }
/// <summary> /// UnicodeReplacer API /// </summary> /// public virtual int Replace(Replaceable text, int start, int limit, int[] cursor) { int outLen = 0; // Copy segment with out-of-band data int dest = limit; // If there was no match, that means that a quantifier // matched zero-length. E.g., x (a)* y matched "xy". if (matchStart >= 0) { if (matchStart != matchLimit) { text.Copy(matchStart, matchLimit, dest); outLen = matchLimit - matchStart; } } text.Replace(start, limit, ""); // delete original text return(outLen); }
/** * Constructs an iterator with an initial index of 0. */ /* * public ReplaceableCharacterIterator(Replaceable text) { this(text, * 0); } */ /** * Constructs an iterator with the specified initial index. * * @param text * The String to be iterated over * @param pos * Initial iterator position */ /* * public ReplaceableCharacterIterator(Replaceable text, int pos) { * this(text, 0, text.length(), pos); } */ /// <summary> /// Constructs an iterator over the given range of the given string, with /// the index set at the specified position. /// </summary> /// /// <param name="text_0">The String to be iterated over</param> /// <param name="begin_1">Index of the first character</param> /// <param name="end_2">Index of the character following the last character</param> /// <param name="pos_3">Initial iterator position</param> public ReplaceableCharacterIterator(Replaceable text_0, int begin_1, int end_2, int pos_3) { if (text_0 == null) { throw new NullReferenceException(); } this.text = text_0; if (begin_1 < 0 || begin_1 > end_2 || end_2 > text_0.Length()) { throw new ArgumentException("Invalid substring range"); } if (pos_3 < begin_1 || pos_3 > end_2) { throw new ArgumentException("Invalid position"); } this.begin = begin_1; this.end = end_2; this.pos = pos_3; }
protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position index, bool incremental) { /* * We keep start and limit fixed the entire time, relative to the text * -- limit may move numerically if text is inserted or removed. The * cursor moves from start to limit, with replacements happening under * it. * * Example: rules 1. ab>x|y 2. yc>z * * |eabcd start - no match, advance cursor e|abcd match rule 1 - change * text & adjust cursor ex|ycd match rule 2 - change text & adjust * cursor exz|d no match, advance cursor exzd| done */ /* * A rule like a>b|a creates an infinite loop. To prevent that, we put * an arbitrary limit on the number of iterations that we take, one that * is high enough that any reasonable rules are ok, but low enough to * prevent a server from hanging. The limit is 16 times the number of * characters n, unless n is so large that 16n exceeds a uint32_t. */ int loopCount = 0; int loopLimit = (index.limit - index.start) << 4; if (loopLimit < 0) { loopLimit = 0x7FFFFFFF; } while (index.start < index.limit && loopCount <= loopLimit && data.ruleSet.Transliterate(text, index, incremental)) { ++loopCount; } }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position offsets, bool isIncremental) { int cursor = offsets.start; int limit = offsets.limit; StringBuilder str = new StringBuilder(); str.Append(OPEN_DELIM); int len; String name; while (cursor < limit) { int c = text.Char32At(cursor); if ((name = IBM.ICU.Lang.UCharacter.GetExtendedName(c)) != null) { str.Length = OPEN_DELIM_LEN; str.Append(name).Append(CLOSE_DELIM); int clen = IBM.ICU.Text.UTF16.GetCharCount(c); text.Replace(cursor, cursor + clen, str.ToString()); len = str.Length; cursor += len; // advance cursor by 1 and adjust for new text limit += len - clen; // change in length } else { ++cursor; } } offsets.contextLimit += limit - offsets.limit; offsets.limit = limit; offsets.start = cursor; }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position offsets, bool isIncremental) { int maxLen = IBM.ICU.Impl.UCharacterName.GetInstance().GetMaxCharNameLength() + 1; // allow // for // temporary // trailing // space StringBuilder name = new StringBuilder(maxLen); // Get the legal character set UnicodeSet legal = new UnicodeSet(); IBM.ICU.Impl.UCharacterName.GetInstance().GetCharNameCharacters(legal); int cursor = offsets.start; int limit = offsets.limit; // Modes: // 0 - looking for open delimiter // 1 - after open delimiter int mode = 0; int openPos = -1; // open delim candidate pos int c; while (cursor < limit) { c = text.Char32At(cursor); switch (mode) { case 0: // looking for open delimiter if (c == OPEN_DELIM) // quick check first { openPos = cursor; int i = IBM.ICU.Impl.Utility.ParsePattern(OPEN_PAT, text, cursor, limit); if (i >= 0 && i < limit) { mode = 1; name.Length = 0; cursor = i; continue; // *** reprocess char32At(cursor) } } break; case 1: // after open delimiter // Look for legal chars. If \s+ is found, convert it // to a single space. If closeDelimiter is found, exit // the loop. If any other character is found, exit the // loop. If the limit is reached, exit the loop. // Convert \s+ => SPACE. This assumes there are no // runs of >1 space characters in names. if (IBM.ICU.Impl.UCharacterProperty.IsRuleWhiteSpace(c)) { // Ignore leading whitespace if (name.Length > 0 && name[name.Length - 1] != SPACE) { name.Append(SPACE); // If we are too long then abort. maxLen includes // temporary trailing space, so use '>'. if (name.Length > maxLen) { mode = 0; } } break; } if (c == CLOSE_DELIM) { int len = name.Length; // Delete trailing space, if any if (len > 0 && name[len - 1] == SPACE) { name.Length = --len; } c = IBM.ICU.Lang.UCharacter.GetCharFromExtendedName(name.ToString()); if (c != -1) { // Lookup succeeded // assert(UTF16.getCharCount(CLOSE_DELIM) == 1); cursor++; // advance over CLOSE_DELIM String str = IBM.ICU.Text.UTF16.ValueOf(c); text.Replace(openPos, cursor, str); // Adjust indices for the change in the length of // the string. Do not assume that str.length() == // 1, in case of surrogates. int delta = cursor - openPos - str.Length; cursor -= delta; limit -= delta; // assert(cursor == openPos + str.length()); } // If the lookup failed, we leave things as-is and // still switch to mode 0 and continue. mode = 0; openPos = -1; // close off candidate continue; // *** reprocess char32At(cursor) } if (legal.Contains(c)) { IBM.ICU.Text.UTF16.Append(name, c); // If we go past the longest possible name then abort. // maxLen includes temporary trailing space, so use '>='. if (name.Length >= maxLen) { mode = 0; } } // Invalid character else { --cursor; // Backup and reprocess this character mode = 0; } break; } cursor += IBM.ICU.Text.UTF16.GetCharCount(c); } offsets.contextLimit += limit - offsets.limit; offsets.limit = limit; // In incremental mode, only advance the cursor up to the last // open delimiter candidate. offsets.start = (isIncremental && openPos >= 0) ? openPos : cursor; }
protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position pos, bool incremental) { boundaryCount = 0; int boundary = 0; GetBreakIterator(); // Lazy-create it if necessary bi.SetText(new BreakTransliterator.ReplaceableCharacterIterator(text, pos.start, pos.limit, pos.start)); // TODO: fix clumsy workaround used below. /* * char[] tempBuffer = new char[text.length()]; text.getChars(0, * text.length(), tempBuffer, 0); bi.setText(new * StringCharacterIterator(new String(tempBuffer), pos.start, pos.limit, * pos.start)); */ // end debugging // To make things much easier, we will stack the boundaries, and then // insert at the end. // generally, we won't need too many, since we will be filtered. for (boundary = bi.First(); boundary != IBM.ICU.Text.BreakIterator.DONE && boundary < pos.limit; boundary = bi.Next()) { if (boundary == 0) { continue; } // HACK: Check to see that preceeding item was a letter int cp = IBM.ICU.Text.UTF16.CharAt(text, boundary - 1); int type = IBM.ICU.Lang.UCharacter.GetType(cp); // System.out.println(Integer.toString(cp,16) + " (before): " + // type); if (((1 << type) & LETTER_OR_MARK_MASK) == 0) { continue; } cp = IBM.ICU.Text.UTF16.CharAt(text, boundary); type = IBM.ICU.Lang.UCharacter.GetType(cp); // System.out.println(Integer.toString(cp,16) + " (after): " + // type); if (((1 << type) & LETTER_OR_MARK_MASK) == 0) { continue; } if (boundaryCount >= boundaries.Length) // realloc if necessary { int[] temp = new int[boundaries.Length * 2]; System.Array.Copy((Array)(boundaries), 0, (Array)(temp), 0, boundaries.Length); boundaries = temp; } boundaries[boundaryCount++] = boundary; // System.out.println(boundary); } int delta = 0; int lastBoundary = 0; if (boundaryCount != 0) // if we found something, adjust { delta = boundaryCount * insertion.Length; lastBoundary = boundaries[boundaryCount - 1]; // we do this from the end backwards, so that we don't have to keep // updating. while (boundaryCount > 0) { boundary = boundaries[--boundaryCount]; text.Replace(boundary, boundary, insertion); } } // Now fix up the return values pos.contextLimit += delta; pos.limit += delta; pos.start = (incremental) ? lastBoundary + delta : pos.limit; }
/// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position offsets, bool isIncremental) { if (csp == null) { return; } if (offsets.start >= offsets.limit) { return; } iter.SetText(text); result.Length = 0; int c, delta; // Walk through original string // If there is a case change, modify corresponding position in // replaceable iter.SetIndex(offsets.start); iter.SetLimit(offsets.limit); iter.SetContextLimits(offsets.contextStart, offsets.contextLimit); while ((c = iter.NextCaseMapCP()) >= 0) { c = csp.ToFullUpper(c, iter, result, locale, locCache); if (iter.DidReachLimit() && isIncremental) { // the case mapping function tried to look beyond the context // limit // wait for more input offsets.start = iter.GetCaseMapCPStart(); return; } /* decode the result */ if (c < 0) { /* c mapped to itself, no change */ continue; } else if (c <= IBM.ICU.Impl.UCaseProps.MAX_STRING_LENGTH) { /* replace by the mapping string */ delta = iter.Replace(result.ToString()); result.Length = 0; } else { /* replace by single-code point mapping */ delta = iter.Replace(IBM.ICU.Text.UTF16.ValueOf(c)); } if (delta != 0) { offsets.limit += delta; offsets.contextLimit += delta; } } offsets.start = offsets.limit; }
// = public static UnicodeReplacer valueOf(String output, // = int cursorPos, // = RuleBasedTransliterator.Data data) { // = if (output.length() == 1) { // = char c = output.charAt(0); // = UnicodeReplacer r = data.lookupReplacer(c); // = if (r != null) { // = return r; // = } // = } // = return new StringReplacer(output, cursorPos, data); // = } /// <summary> /// UnicodeReplacer API /// </summary> /// public virtual int Replace(Replaceable text, int start, int limit, int[] cursor) { int outLen; int newStart = 0; // NOTE: It should be possible to _always_ run the complex // processing code; just slower. If not, then there is a bug // in the complex processing code. // Simple (no nested replacers) Processing Code : if (!isComplex) { text.Replace(start, limit, output); outLen = output.Length; // Setup default cursor position (for cursorPos within output) newStart = cursorPos; } // Complex (nested replacers) Processing Code : else { /* * When there are segments to be copied, use the Replaceable.copy() * API in order to retain out-of-band data. Copy everything to the * end of the string, then copy them back over the key. This * preserves the integrity of indices into the key and surrounding * context while generating the output text. */ StringBuilder buf = new StringBuilder(); int oOutput; // offset into 'output' isComplex = false; // The temporary buffer starts at tempStart, and : // to destLimit + tempExtra. The start of the buffer has a single // character from before the key. This provides style // data when addition characters are filled into the // temporary buffer. If there is nothing to the left, use // the non-character U+FFFF, which Replaceable subclasses // should treat specially as a "no-style character." // destStart points to the point after the style context // character, so it is tempStart+1 or tempStart+2. int tempStart = text.Length(); // start of temp buffer int destStart = tempStart; // copy new text to here if (start > 0) { int len = IBM.ICU.Text.UTF16.GetCharCount(text.Char32At(start - 1)); text.Copy(start - len, start, tempStart); destStart += len; } else { text.Replace(tempStart, tempStart, "\uFFFF"); destStart++; } int destLimit = destStart; int tempExtra = 0; // temp chars after destLimit for (oOutput = 0; oOutput < output.Length;) { if (oOutput == cursorPos) { // Record the position of the cursor newStart = buf.Length + destLimit - destStart; // relative // to start // the buf.length() was inserted for bug 5789 // the problem is that if we are accumulating into a buffer // (when r == null below) // then the actual length of the text at that point needs to // add the buf length. // there was an alternative suggested in #5789, but that // looks like it won't work // if we have accumulated some stuff in the dest part AND // have a non-zero buffer. } int c = IBM.ICU.Text.UTF16.CharAt(output, oOutput); // When we are at the last position copy the right style // context character into the temporary buffer. We don't // do this before because it will provide an incorrect // right context for previous replace() operations. int nextIndex = oOutput + IBM.ICU.Text.UTF16.GetCharCount(c); if (nextIndex == output.Length) { tempExtra = IBM.ICU.Text.UTF16.GetCharCount(text.Char32At(limit)); text.Copy(limit, limit + tempExtra, destLimit); } UnicodeReplacer r = data.LookupReplacer(c); if (r == null) { // Accumulate straight (non-segment) text. IBM.ICU.Text.UTF16.Append(buf, c); } else { isComplex = true; // Insert any accumulated straight text. if (buf.Length > 0) { text.Replace(destLimit, destLimit, buf.ToString()); destLimit += buf.Length; buf.Length = 0; } // Delegate output generation to replacer object int len_0 = r.Replace(text, destLimit, destLimit, cursor); destLimit += len_0; } oOutput = nextIndex; } // Insert any accumulated straight text. if (buf.Length > 0) { text.Replace(destLimit, destLimit, buf.ToString()); destLimit += buf.Length; } if (oOutput == cursorPos) { // Record the position of the cursor newStart = destLimit - destStart; // relative to start } outLen = destLimit - destStart; // Copy new text to start, and delete it text.Copy(destStart, destLimit, start); text.Replace(tempStart + outLen, destLimit + tempExtra + outLen, ""); // Delete the old text (the key) text.Replace(start + outLen, limit + outLen, ""); } if (hasCursor) { // Adjust the cursor for positions outside the key. These // refer to code points rather than code units. If cursorPos // is within the output string, then use newStart, which has // already been set above. if (cursorPos < 0) { newStart = start; int n = cursorPos; // Outside the output string, cursorPos counts code points while (n < 0 && newStart > 0) { newStart -= IBM.ICU.Text.UTF16.GetCharCount(text.Char32At(newStart - 1)); ++n; } newStart += n; } else if (cursorPos > output.Length) { newStart = start + outLen; int n_1 = cursorPos - output.Length; // Outside the output string, cursorPos counts code points while (n_1 > 0 && newStart < text.Length()) { newStart += IBM.ICU.Text.UTF16.GetCharCount(text.Char32At(newStart)); --n_1; } newStart += n_1; } else { // Cursor is within output string. It has been set up above // to be relative to start. newStart += start; } cursor[0] = newStart; } return(outLen); }
/// <exclude/> /// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position index, bool incremental) { /* * Call each transliterator with the same start value and initial cursor * index, but with the limit index as modified by preceding * transliterators. The cursor index must be reset for each * transliterator to give each a chance to transliterate the text. The * initial cursor index is known to still point to the same place after * each transliterator is called because each transliterator will not * change the text between start and the initial value of cursor. * * IMPORTANT: After the first transliterator, each subsequent * transliterator only gets to transliterate text committed by preceding * transliterators; that is, the cursor (output value) of transliterator * i becomes the limit (input value) of transliterator i+1. Finally, the * overall limit is fixed up before we return. * * Assumptions we make here: (1) contextStart <= start <= limit <= * contextLimit <= text.length() (2) start <= start' <= limit' ;cursor * doesn't move back (3) start <= limit' ;text before cursor unchanged - * start' is the value of start after calling handleKT - limit' is the * value of limit after calling handleKT */ /** * Example: 3 transliterators. This example illustrates the mechanics we * need to implement. C, S, and L are the contextStart, start, and * limit. gl is the globalLimit. contextLimit is equal to limit * throughout. * * 1. h-u, changes hex to Unicode * * 4 7 a d 0 4 7 a abc/u0061/u => abca/u C S L C S L gl=f->a * * 2. upup, changes "x" to "XX" * * 4 7 a 4 7 a abca/u => abcAA/u C SL C S L gl=a->b 3. u-h, changes * Unicode to hex * * 4 7 a 4 7 a d 0 3 abcAA/u => abc/u0041/u0041/u C S L C S L gl=b->15 * 4. return * * 4 7 a d 0 3 abc/u0041/u0041/u C S L */ if (trans.Length < 1) { index.start = index.limit; return; // Short circuit for empty compound transliterators } // compoundLimit is the limit value for the entire compound // operation. We overwrite index.limit with the previous // index.start. After each transliteration, we update // compoundLimit for insertions or deletions that have happened. int compoundLimit = index.limit; // compoundStart is the start for the entire compound // operation. int compoundStart = index.start; int delta = 0; // delta in length StringBuilder log = null; if (IBM.ICU.Text.Transliterator.DEBUG) { log = new StringBuilder("CompoundTransliterator{" + GetID() + ((incremental) ? "}i: IN=" : "}: IN=")); IBM.ICU.Impl.UtilityExtensions.FormatInput(log, text, index); System.Console.Out.WriteLine(IBM.ICU.Impl.Utility.Escape(log.ToString())); } // Give each transliterator a crack at the run of characters. // See comments at the top of the method for more detail. for (int i = 0; i < trans.Length; ++i) { index.start = compoundStart; // Reset start int limit = index.limit; if (index.start == index.limit) { // Short circuit for empty range if (IBM.ICU.Text.Transliterator.DEBUG) { System.Console.Out.WriteLine("CompoundTransliterator[" + i + ".." + (trans.Length - 1) + ((incremental) ? "]i: " : "]: ") + IBM.ICU.Impl.UtilityExtensions.FormatInput(text, index) + " (NOTHING TO DO)"); } break; } if (IBM.ICU.Text.Transliterator.DEBUG) { log.Length = 0; log.Append("CompoundTransliterator[" + i + "=" + trans[i].GetID() + ((incremental) ? "]i: " : "]: ")); IBM.ICU.Impl.UtilityExtensions.FormatInput(log, text, index); } trans[i].FilteredTransliterate(text, index, incremental); // In a properly written transliterator, start == limit after // handleTransliterate() returns when incremental is false. // Catch cases where the subclass doesn't do this, and throw // an exception. (Just pinning start to limit is a bad idea, // because what's probably happening is that the subclass // isn't transliterating all the way to the end, and it should // in non-incremental mode.) if (!incremental && index.start != index.limit) { throw new Exception( "ERROR: Incomplete non-incremental transliteration by " + trans[i].GetID()); } if (IBM.ICU.Text.Transliterator.DEBUG) { log.Append(" => "); IBM.ICU.Impl.UtilityExtensions.FormatInput(log, text, index); System.Console.Out.WriteLine(IBM.ICU.Impl.Utility.Escape(log.ToString())); } // Cumulative delta for insertions/deletions delta += index.limit - limit; if (incremental) { // In the incremental case, only allow subsequent // transliterators to modify what has already been // completely processed by prior transliterators. In the // non-incrmental case, allow each transliterator to // process the entire text. index.limit = index.start; } } compoundLimit += delta; // Start is good where it is -- where the last transliterator left // it. Limit needs to be put back where it was, modulo // adjustments for deletions/insertions. index.limit = compoundLimit; if (IBM.ICU.Text.Transliterator.DEBUG) { log.Length = 0; log.Append("CompoundTransliterator{" + GetID() + ((incremental) ? "}i: OUT=" : "}: OUT=")); IBM.ICU.Impl.UtilityExtensions.FormatInput(log, text, index); System.Console.Out.WriteLine(IBM.ICU.Impl.Utility.Escape(log.ToString())); } }
/// <exclude/> /// <summary> /// Implements <see cref="M:IBM.ICU.Text.Transliterator.HandleTransliterate(IBM.ICU.Text.Replaceable, null, System.Boolean)"/>. /// </summary> /// protected internal override void HandleTransliterate(Replaceable text, Transliterator.Position offsets, bool incremental) { offsets.start = offsets.limit; }
// static final methods ---------------------------------------------------- /// <summary> /// Returns a <c>UCharacterIterator</c> object given a /// <c>Replaceable</c> object. /// </summary> /// /// <param name="source">a valid source as a <c>Replaceable</c> object</param> /// <returns>UCharacterIterator object</returns> /// <exception cref="IllegalArgumentException">if the argument is null</exception> /// @stable ICU 2.4 public static UCharacterIterator GetInstance(Replaceable source) { return(new ReplaceableUCharacterIterator(source)); }