/// <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; }
/// <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; }
/** * 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; }
// = 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); }
static internal int PosAfter(Replaceable str, int pos) { return((pos >= 0 && pos < str.Length()) ? pos + IBM.ICU.Text.UTF16.GetCharCount(str.Char32At(pos)) : pos + 1); }