Esempio n. 1
0
 /// <summary>
 /// Constructs a run iterator over the given text from start
 /// (inclusive) to limit (exclusive).
 /// </summary>
 /// <param name="text"></param>
 /// <param name="start"></param>
 /// <param name="limit"></param>
 public ScriptRunIterator(IReplaceable text, int start, int limit)
 {
     this.text      = text;
     this.textStart = start;
     this.textLimit = limit;
     this.Limit     = start;
 }
Esempio n. 2
0
 /// <summary>
 /// Reset this iterator to point to a new string.  This public
 /// method is used by classes that want to avoid allocating
 /// new <see cref="ReplaceableCharacterIterator"/> objects every
 /// time their <see cref="SetText(IReplaceable)"/> method
 /// is called.
 /// </summary>
 /// <param name="text">The <see cref="string"/> to be iterated over.</param>
 public void SetText(IReplaceable text)
 {
     this.text  = text ?? throw new ArgumentNullException(nameof(text));
     this.begin = 0;
     this.end   = text.Length;
     this.pos   = 0;
 }
Esempio n. 3
0
        /// <summary>
        /// Default implementation of <see cref="IUnicodeMatcher.Matches(IReplaceable, int[], int, bool)"/> for Unicode
        /// filters.  Matches a single 16-bit code unit at offset.
        /// </summary>
        /// <stable>ICU 2.0</stable>
        public virtual MatchDegree Matches(IReplaceable text,
                                           int[] offset,
                                           int limit,
                                           bool incremental)
        {
            int c;

            if (offset[0] < limit &&
                Contains(c = text.Char32At(offset[0])))
            {
                offset[0] += UTF16.GetCharCount(c);
                return(MatchDegree.Match);
            }
            if (offset[0] > limit && Contains(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] -= UTF16.GetCharCount(text.Char32At(offset[0])) - 1;
                }
                return(MatchDegree.Match);
            }
            if (incremental && offset[0] == limit)
            {
                return(MatchDegree.PartialMatch);
            }
            return(MatchDegree.Mismatch);
        }
Esempio n. 4
0
        /// <summary>
        /// <see cref="IUnicodeReplacer"/> API
        /// </summary>
        public virtual int Replace(IReplaceable 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);
        }
Esempio n. 5
0
        public HtmlTemplate ReplaceTagsInTemplate(MerchantTribeApplication app, IReplaceable item, List <IReplaceable> repeatingItems)
        {
            List <IReplaceable> items = new List <IReplaceable>();

            items.Add(item);
            return(ReplaceTagsInTemplate(app, items, repeatingItems));
        }
Esempio n. 6
0
        private string GetDescription(IReplaceable instance)
        {
            if (instance == null)
            {
                return(string.Empty);
            }
            var result = ((ObjectInstance)instance).ToShortString();

            if (instance is MoveableInstance)
            {
                result += " (" + instance.SecondaryAttribDesc + ": " + ((MoveableInstance)instance).Ocb + ")";
            }
            else if (instance is StaticInstance && _editor.Level.Settings.GameVersion == TRVersion.Game.TRNG)
            {
                result += " (" + instance.SecondaryAttribDesc + ": " + ((StaticInstance)instance).Ocb + ")";
            }
            else if (instance is SinkInstance)
            {
                result += " (" + instance.PrimaryAttribDesc + ": " + ((SinkInstance)instance).Strength + ")";
            }
            else if (instance is ImportedGeometryInstance)
            {
                result += " (" + instance.SecondaryAttribDesc + ": " + ((ImportedGeometryInstance)instance).Scale.ToString(".0#") + ")";
            }
            else if (instance is SoundSourceInstance)
            {
                result += " (" + instance.PrimaryAttribDesc + ": " + ((SoundSourceInstance)instance).SoundId + ")";
            }

            return(result);
        }
Esempio n. 7
0
        public HtmlTemplate ReplaceTagsInTemplate(HccRequestContext context, IReplaceable item)
        {
            var items = new List <IReplaceable>();

            items.Add(item);
            return(ReplaceTagsInTemplate(context, items));
        }
Esempio n. 8
0
        public bool ReplaceableEquals(IReplaceable other, bool withProperties = false)
        {
            var otherInstance = other as ItemInstance;

            return(otherInstance?.ItemType.IsStatic == ItemType.IsStatic &&
                   otherInstance.ItemType == ItemType &&
                   (withProperties ? otherInstance?.Ocb == Ocb : true));
        }
 /// <summary>
 /// Set the text for iteration.
 /// </summary>
 /// <param name="rep"><see cref="IReplaceable"/> to iterate over.</param>
 public virtual void SetText(IReplaceable rep)
 {
     this.rep     = rep;
     limit        = contextLimit = rep.Length;
     cpStart      = cpLimit = index = contextStart = 0;
     dir          = 0;
     reachedLimit = false;
 }
Esempio n. 10
0
 /// <summary>
 /// Set the text for iteration.
 /// </summary>
 /// <param name="rep"><see cref="IReplaceable"/> to iterate over.</param>
 public virtual void SetText(IReplaceable rep)
 {
     this.rep     = rep;
     limit        = contextLimit = rep.Length;
     cpStart      = cpLimit = index = contextStart = 0;
     forward      = true;
     reachedLimit = false;
     Current      = -1;
 }
Esempio n. 11
0
        // public constructor ------------------------------------------------------

        /// <summary>
        /// Public constructor.
        /// </summary>
        /// <param name="replaceable">Text which the iterator will be based on.</param>
        public ReplaceableUCharacterIterator(IReplaceable replaceable)
        {
            if (replaceable == null)
            {
                throw new ArgumentException();
            }
            this.replaceable  = replaceable;
            this.currentIndex = 0;
        }
Esempio n. 12
0
        /// <summary>
        /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, TransliterationPosition, bool)"/>.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="index"></param>
        /// <param name="incremental"></param>
        protected override void HandleTransliterate(IReplaceable text,
                                                    TransliterationPosition 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;
        }
Esempio n. 13
0
        /// <summary>
        /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, Position, bool)"/>.
        /// </summary>
        protected override void HandleTransliterate(IReplaceable text,
                                                    Position pos, bool isIncremental)
        {
            int allStart = pos.Start;
            int allLimit = pos.Limit;

            ScriptRunIterator it =
                new 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;
        }
Esempio n. 14
0
        /// <summary>
        /// Retrieves the message of the given Message code and replaces all ReplacementCodes with the proper value
        /// </summary>
        /// <param name="text">The text to parse</param>
        /// <param name="replaceable">Any objects that are available should be passed on as they may be used as part of the parsing process.</param>
        /// <returns>The text element parsed</returns>
        public string ParseMessage(string text, IReplaceable <TKey> replaceable)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return(string.Empty);
            }

            StringBuilder message = new StringBuilder();
            List <IReplaceableCode <TKey> > codes          = replaceable.GetReplaceableCodes();
            Dictionary <TKey, object>       objectsToParse = replaceable.GetReplaceables();

            return(this.ParseText(text, codes, objectsToParse));
        }
Esempio n. 15
0
        public bool Replace(IReplaceable other, bool withProperties)
        {
            var thatSink = (SinkInstance)other;

            if (!ReplaceableEquals(other) && Strength != thatSink?.Strength)
            {
                Strength = thatSink.Strength;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 16
0
        public bool Replace(IReplaceable other, bool withProperties)
        {
            var thatSound = (SoundSourceInstance)other;

            if (!ReplaceableEquals(other) && thatSound.SoundId != SoundId)
            {
                SoundId = ((SoundSourceInstance)other).SoundId;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 17
0
        public bool Replace(IReplaceable other, bool withProperties)
        {
            var thatColor = (LightInstance)other;

            if (!ReplaceableEquals(other) && Color != thatColor?.Color)
            {
                Color = thatColor.Color;
                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 18
0
        /// <summary>
        /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, Position, bool)"/>.
        /// </summary>
        protected override void HandleTransliterate(IReplaceable text,
                                                    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 ? text.Char32At(start) : text[start];
                int charLen = grokSupplementals ? UTF16.GetCharCount(c) : 1;

                if ((c & 0xFFFF0000) != 0 && supplementalHandler != null)
                {
                    buf.Length = 0;
                    buf.Append(supplementalHandler.prefix);
                    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;
                    }
                    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;
        }
Esempio n. 19
0
        /// <summary>
        /// <see cref="IUnicodeReplacer"/> API
        /// </summary>
        public virtual int Replace(IReplaceable 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);
        }
Esempio n. 20
0
        /// <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, and return 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 virtual bool Transliterate(IReplaceable text,
                                          TransliterationPosition pos,
                                          bool incremental)
        {
            int indexByte = text.Char32At(pos.Start) & 0xFF;

            for (int i = index[indexByte]; i < index[indexByte + 1]; ++i)
            {
                MatchDegree m = rules[i].MatchAndReplace(text, pos, incremental);
                switch (m)
                {
                case MatchDegree.Match:
                    if (Transliterator.DEBUG)
                    {
                        Console.Out.WriteLine((incremental ? "Rule.i: match " : "Rule: match ") +
                                              rules[i].ToRule(true) + " => " +
                                              UtilityExtensions.FormatInput(text, pos));
                    }
                    return(true);

                case MatchDegree.PartialMatch:
                    if (Transliterator.DEBUG)
                    {
                        Console.Out.WriteLine((incremental ? "Rule.i: partial match " : "Rule: partial match ") +
                                              rules[i].ToRule(true) + " => " +
                                              UtilityExtensions.FormatInput(text, pos));
                    }
                    return(false);

                default:
                    if (Transliterator.DEBUG)
                    {
                        Console.Out.WriteLine("Rule: no match " + rules[i]);
                    }
                    break;
                }
            }
            // No match or partial match from any rule
            pos.Start += UTF16.GetCharCount(text.Char32At(pos.Start));
            if (Transliterator.DEBUG)
            {
                Console.Out.WriteLine((incremental ? "Rule.i: no match => " : "Rule: no match => ") +
                                      UtilityExtensions.FormatInput(text, pos));
            }
            return(true);
        }
Esempio n. 21
0
#pragma warning disable 809
        protected override void HandleTransliterate(IReplaceable text,
                                                    TransliterationPosition index, bool incremental)
#pragma warning disable 809
        {
            /* 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.
             */
            lock (data)
            {
                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;
                }
            }
        }
Esempio n. 22
0
            ///// <summary>
            ///// Constructs an iterator with an initial index of 0.
            ///// </summary>
            ///// <param name="text">The <see cref="string"/> to be iterated over.</param>
            //public ReplaceableCharacterIterator(IReplaceable text)
            //    : this(text, 0)
            //{
            //}

            ///// <summary>
            ///// Constructs an iterator with the specified initial index.
            ///// </summary>
            ///// <param name="text">The <see cref="string"/> to be iterated over.</param>
            ///// <param name="pos">Initial iterator position.</param>
            //public ReplaceableCharacterIterator(IReplaceable 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">The <see cref="string"/> to be iterated over.</param>
            /// <param name="begin">Index of the first character.</param>
            /// <param name="end">Index of the character following the last character.</param>
            /// <param name="pos">Initial iterator position.</param>
            public ReplaceableCharacterIterator(IReplaceable text, int begin, int end, int pos)
            {
                this.text = text ?? throw new ArgumentNullException(nameof(text));

                if (begin < 0 || begin > end || end > text.Length)
                {
                    throw new ArgumentException("Invalid substring range");
                }

                if (pos < begin || pos > end)
                {
                    throw new ArgumentException("Invalid position");
                }

                this.begin = begin;
                this.end   = end;
                this.pos   = pos;
            }
Esempio n. 23
0
        /// <summary>
        /// Implement <see cref="IUnicodeMatcher"/> API.
        /// </summary>
        public virtual MatchDegree Matches(IReplaceable text,
                                           int[] offset,
                                           int limit,
                                           bool incremental)
        {
            int start = offset[0];
            int count = 0;

            while (count < maxCount)
            {
                int         pos = offset[0];
                MatchDegree m   = matcher.Matches(text, offset, limit, incremental);
                if (m == MatchDegree.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 == MatchDegree.PartialMatch)
                {
                    return(MatchDegree.PartialMatch);
                }
                else
                {
                    break;
                }
            }
            if (incremental && offset[0] == limit)
            {
                return(MatchDegree.PartialMatch);
            }
            if (count >= minCount)
            {
                return(MatchDegree.Match);
            }
            offset[0] = start;
            return(MatchDegree.Mismatch);
        }
Esempio n. 24
0
        public bool Replace(IReplaceable other, bool withProperties)
        {
            var result = false;

            if (!ReplaceableEquals(other))
            {
                if (ItemType.IsStatic)
                {
                    var thisObj = (StaticInstance)this;
                    var thatObj = (StaticInstance)other;
                    if (thisObj.WadObjectId != thatObj.WadObjectId)
                    {
                        thisObj.WadObjectId = thatObj.WadObjectId;
                        result = true;
                    }
                    if (withProperties && thisObj.Ocb != thatObj.Ocb)
                    {
                        thisObj.Ocb = thatObj.Ocb;
                        result      = true;
                    }
                }
                else
                {
                    var thisObj = (MoveableInstance)this;
                    var thatObj = (MoveableInstance)other;
                    if (thisObj.WadObjectId != thatObj.WadObjectId)
                    {
                        thisObj.WadObjectId = thatObj.WadObjectId;
                        result = true;
                    }
                    if (withProperties && thisObj.Ocb != thatObj.Ocb)
                    {
                        thisObj.Ocb = thatObj.Ocb;
                        result      = true;
                    }
                }
            }

            return(result);
        }
Esempio n. 25
0
        public bool Replace(IReplaceable other, bool withProperties)
        {
            var result = false;

            if (!ReplaceableEquals(other))
            {
                var thatObj = (ImportedGeometryInstance)other;

                if (Model != thatObj.Model)
                {
                    Model  = thatObj.Model;
                    result = true;
                }
                if (withProperties && Scale != thatObj.Scale)
                {
                    Scale  = thatObj.Scale;
                    result = true;
                }
            }

            return(result);
        }
Esempio n. 26
0
        /// <summary>
        /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, Position, bool)"/>.
        /// </summary>
        protected override void HandleTransliterate(IReplaceable text,
                                                    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 = UCharacter.GetExtendedName(c)) != null)
                {
                    str.Length = OPEN_DELIM_LEN;
                    str.Append(name).Append(CLOSE_DELIM);

                    int clen = 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;
        }
Esempio n. 27
0
        /// <summary>
        /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, TransliterationPosition, bool)"/>.
        /// </summary>
        protected override void HandleTransliterate(IReplaceable text,
                                                    TransliterationPosition offsets, bool isIncremental)
        {
            // start and limit of the input range
            int start = offsets.Start;
            int limit = offsets.Limit;

            if (start >= limit)
            {
                return;
            }

            /*
             * Normalize as short chunks at a time as possible even in
             * bulk mode, so that styled text is minimally disrupted.
             * In incremental mode, a chunk that ends with offsets.limit
             * must not be normalized.
             *
             * If it was known that the input text is not styled, then
             * a bulk mode normalization could be used.
             * (For details, see the comment in the C++ version.)
             */
            StringBuilder segment    = new StringBuilder();
            StringBuilder normalized = new StringBuilder();
            int           c          = text.Char32At(start);

            do
            {
                int prev = start;
                // Skip at least one character so we make progress.
                // c holds the character at start.
                segment.Length = 0;
                do
                {
                    segment.AppendCodePoint(c);
                    start += Character.CharCount(c);
                } while (start < limit && !norm2.HasBoundaryBefore(c = text.Char32At(start)));
                if (start == limit && isIncremental && !norm2.HasBoundaryAfter(c))
                {
                    // stop in incremental mode when we reach the input limit
                    // in case there are additional characters that could change the
                    // normalization result
                    start = prev;
                    break;
                }
                norm2.Normalize(segment, normalized);
                if (!UTF16Plus.Equal(segment, normalized))
                {
                    // replace the input chunk with its normalized form
                    text.Replace(prev, start - prev, normalized.ToString()); // ICU4N: Corrected 2nd parameter

                    // update all necessary indexes accordingly
                    int delta = normalized.Length - (start - prev);
                    start += delta;
                    limit += delta;
                }
            } while (start < limit);

            offsets.Start         = start;
            offsets.ContextLimit += limit - offsets.Limit;
            offsets.Limit         = limit;
        }
Esempio n. 28
0
        //=    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>
        /// <see cref="IUnicodeReplacer"/> API
        /// </summary>
        public virtual int Replace(IReplaceable 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.
                 */
                StringBuffer buf = new StringBuffer();
                int          oOutput; // offset into 'output'
                isComplex = false;

                // The temporary buffer starts at tempStart, and extends
                // 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 = 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 = 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 + UTF16.GetCharCount(c);
                    if (nextIndex == output.Length)
                    {
                        tempExtra = UTF16.GetCharCount(text.Char32At(limit));
                        text.Copy(limit, limit + tempExtra, destLimit);
                    }

                    IUnicodeReplacer r = data.LookupReplacer(c);
                    if (r == null)
                    {
                        // Accumulate straight (non-segment) 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 = r.Replace(text, destLimit, destLimit, cursor);
                        destLimit += len;
                    }
                    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 -= UTF16.GetCharCount(text.Char32At(newStart - 1));
                        ++n;
                    }
                    newStart += n;
                }
                else if (cursorPos > output.Length)
                {
                    newStart = start + outLen;
                    int n = cursorPos - output.Length;
                    // Outside the output string, cursorPos counts code points
                    while (n > 0 && newStart < text.Length)
                    {
                        newStart += UTF16.GetCharCount(text.Char32At(newStart));
                        --n;
                    }
                    newStart += n;
                }
                else
                {
                    // Cursor is within output string.  It has been set up above
                    // to be relative to start.
                    newStart += start;
                }

                cursor[0] = newStart;
            }

            return(outLen);
        }
Esempio n. 29
0
        /// <summary>
        /// Implements <see cref="Transliterator.HandleTransliterate(IReplaceable, TransliterationPosition, bool)"/>
        /// </summary>
        protected override void HandleTransliterate(IReplaceable text,
                                                    TransliterationPosition offsets, bool isIncremental)
        {
            lock (syncLock)
            {
                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.ToFullFolding(c, result, 0); // toFullFolding(int c, StringBuffer out, int options)

                    if (iter.DidReachLimit && isIncremental)
                    {
                        // the case mapping function tried to look beyond the context limit
                        // wait for more input
                        offsets.Start = iter.CaseMapCPStart;
                        return;
                    }

                    /* decode the result */
                    if (c < 0)
                    {
                        /* c mapped to itself, no change */
                        continue;
                    }
                    else if (c <= UCaseProperties.MaxStringLength)
                    {
                        /* replace by the mapping string */
                        delta         = iter.Replace(result.ToString());
                        result.Length = 0;
                    }
                    else
                    {
                        /* replace by single-code point mapping */
                        delta = iter.Replace(UTF16.ValueOf(c));
                    }

                    if (delta != 0)
                    {
                        offsets.Limit        += delta;
                        offsets.ContextLimit += delta;
                    }
                }
                offsets.Start = offsets.Limit;
            }
        }
Esempio n. 30
0
        /// <summary>
        /// Implement <see cref="IUnicodeMatcher"/>
        /// </summary>
        public virtual MatchDegree Matches(IReplaceable text,
                                           int[] offset,
                                           int limit,
                                           bool incremental)
        {
            // Note (1): We process text in 16-bit code units, rather than
            // 32-bit code points.  This works because stand-ins are
            // always in the BMP and because we are doing a literal match
            // operation, which can be done 16-bits at a time.
            int i;

            int[] cursor = new int[] { offset[0] };
            if (limit < cursor[0])
            {
                // Match in the reverse direction
                for (i = pattern.Length - 1; i >= 0; --i)
                {
                    char            keyChar = pattern[i]; // OK; see note (1) above
                    IUnicodeMatcher subm    = data.LookupMatcher(keyChar);
                    if (subm == null)
                    {
                        if (cursor[0] > limit &&
                            keyChar == text[cursor[0]])
                        { // OK; see note (1) above
                            --cursor[0];
                        }
                        else
                        {
                            return(MatchDegree.Mismatch);
                        }
                    }
                    else
                    {
                        MatchDegree m =
                            subm.Matches(text, cursor, limit, incremental);
                        if (m != MatchDegree.Match)
                        {
                            return(m);
                        }
                    }
                }
                // Record the match position, but adjust for a normal
                // forward start, limit, and only if a prior match does not
                // exist -- we want the rightmost match.
                if (matchStart < 0)
                {
                    matchStart = cursor[0] + 1;
                    matchLimit = offset[0] + 1;
                }
            }
            else
            {
                for (i = 0; i < pattern.Length; ++i)
                {
                    if (incremental && cursor[0] == limit)
                    {
                        // We've reached the context limit without a mismatch and
                        // without completing our match.
                        return(MatchDegree.PartialMatch);
                    }
                    char            keyChar = pattern[i]; // OK; see note (1) above
                    IUnicodeMatcher subm    = data.LookupMatcher(keyChar);
                    if (subm == null)
                    {
                        // Don't need the cursor < limit check if
                        // incremental is true (because it's done above); do need
                        // it otherwise.
                        if (cursor[0] < limit &&
                            keyChar == text[cursor[0]])
                        { // OK; see note (1) above
                            ++cursor[0];
                        }
                        else
                        {
                            return(MatchDegree.Mismatch);
                        }
                    }
                    else
                    {
                        MatchDegree m =
                            subm.Matches(text, cursor, limit, incremental);
                        if (m != MatchDegree.Match)
                        {
                            return(m);
                        }
                    }
                }
                // Record the match position
                matchStart = offset[0];
                matchLimit = cursor[0];
            }

            offset[0] = cursor[0];
            return(MatchDegree.Match);
        }
Esempio n. 31
0
 public HtmlTemplate ReplaceTagsInTemplate(MerchantTribeApplication app, IReplaceable item, List<IReplaceable> repeatingItems)
 {
     List<IReplaceable> items = new List<IReplaceable>();
     items.Add(item);
     return ReplaceTagsInTemplate(app, items, repeatingItems);
 }