コード例 #1
0
ファイル: MutableStringOps.cs プロジェクト: tnachen/ironruby
        public static MutableString GetSubstring(ConversionStorage<int>/*!*/ fixnumCast, RubyContext/*!*/ context, MutableString/*!*/ self, 
            [NotNull]Range/*!*/ range) {
            int begin = Protocols.CastToFixnum(fixnumCast, context, range.Begin);
            int end = Protocols.CastToFixnum(fixnumCast, context, range.End);

            begin = NormalizeIndex(self, begin);
            if (begin < 0 || begin > self.Length) {
                return null;
            }

            end = NormalizeIndex(self, end);

            int count = range.ExcludeEnd ? end - begin : end - begin + 1;
            return (count < 0) ? self.CreateInstance().TaintBy(self) : GetSubstring(self, begin, count);
        }
コード例 #2
0
        public static MutableString GetSubstring(RubyContext/*!*/ context, MutableString/*!*/ self, [NotNull]Range/*!*/ range) {
            bool excludeEnd;
            int begin, end;
            Protocols.ConvertToIntegerRange(context, range, out begin, out end, out excludeEnd);

            begin = NormalizeIndex(self, begin);
            if (begin < 0 || begin > self.Length) {
                return null;
            }

            end = NormalizeIndex(self, end);

            int count = excludeEnd ? end - begin : end - begin + 1;
            return (count < 0) ? self.CreateInstance().TaintBy(self) : GetSubstring(self, begin, count);
        }
コード例 #3
0
        public static MutableString GetSubstring(RubyScope/*!*/ scope, MutableString/*!*/ self, 
            [NotNull]RubyRegex/*!*/ regex, [DefaultProtocol]int occurrance) {
            if (regex.IsEmpty) {
                return self.CreateInstance().TaintBy(self).TaintBy(regex, scope);
            }

            Group group = MatchRegexp(scope, self, regex, occurrance);
            if (group == null || !group.Success) {
                return null;
            }

            return self.CreateInstance().Append(group.Value).TaintBy(self).TaintBy(regex, scope);
        }
コード例 #4
0
        public static MutableString/*!*/ Repeat(MutableString/*!*/ self, [DefaultProtocol]int times) {
            if (times < 0) {
                throw RubyExceptions.CreateArgumentError("negative argument");
            }

            MutableString result = self.CreateInstance().TaintBy(self);
            for (int i = 0; i < times; i++) {
                result.Append(self);
            }

            return result;
        }
コード例 #5
0
        public static MutableString RemoveSubstringInPlace(RubyContext/*!*/ context, MutableString/*!*/ self, [NotNull]Range/*!*/ range) {
            bool excludeEnd;
            int begin, end;
            Protocols.ConvertToIntegerRange(context, range, out begin, out end, out excludeEnd);
            
            if (!InInclusiveRangeNormalized(self, ref begin)) {
                return null;
            }

            end = NormalizeIndex(self, end);

            int count = excludeEnd ? end - begin : end - begin + 1;
            return count < 0 ? self.CreateInstance() : RemoveSubstringInPlace(self, begin, count);
        }
コード例 #6
0
        private static RubyArray/*!*/ WhitespaceSplit(MutableString/*!*/ self, int maxComponents) {
            char[] separators = new char[] { ' ', '\n', '\r', '\t', '\v' };
            MutableString[] elements = self.Split(separators, (maxComponents < 0) ? Int32.MaxValue : maxComponents, StringSplitOptions.RemoveEmptyEntries);

            RubyArray result = new RubyArray(); 
            foreach (MutableString element in elements) {
                result.Add(self.CreateInstance().Append(element).TaintBy(self));
            }

            // Strange behavior to match Ruby semantics
            if (maxComponents < 0) {
                result.Add(self.CreateInstance().TaintBy(self));
            }

            return result;
        }
コード例 #7
0
        private static MutableString/*!*/ TrInternal(MutableString/*!*/ self, [DefaultProtocol, NotNull]MutableString/*!*/ from,
            [DefaultProtocol, NotNull]MutableString/*!*/ to, bool squeeze) {

            MutableString result = self.CreateInstance().TaintBy(self);
            IntervalParser parser = new IntervalParser(from);

            // TODO: a single pass to generate both?
            MutableString source = parser.ParseSequence();
            BitArray bitmap = parser.Parse();

            MutableString dest = new IntervalParser(to).ParseSequence();

            int lastChar = dest.GetLastChar();
            char? lastTranslated = null;
            for (int i = 0; i < self.Length; i++) {
                char c = self.GetChar(i);
                if (bitmap.Get(c)) {
                    char? thisTranslated = null;
                    int index = source.IndexOf(c);
                    if (index >= dest.Length) {
                        if (lastChar != -1) {
                            thisTranslated = (char)lastChar;
                        }
                    } else {
                        thisTranslated = dest.GetChar(index);
                    }
                    if (thisTranslated != null && (!squeeze || lastTranslated == null || lastTranslated.Value != thisTranslated)) {
                        result.Append(thisTranslated.Value);
                    }
                    lastTranslated = thisTranslated;
                } else {
                    result.Append(c);
                    lastTranslated = null;
                }
            }

            return result;
        }
コード例 #8
0
        public static MutableString GetSubstring(MutableString/*!*/ self, [DefaultProtocol]int start, [DefaultProtocol]int count) {
            int byteCount = self.GetByteCount();
            if (!NormalizeSubstringRange(byteCount, ref start, ref count)) {
                return (start == byteCount) ? self.CreateInstance().TaintBy(self) : null;
            }

            return self.CreateInstance().Append(self, start, count).TaintBy(self);
        }
コード例 #9
0
 public static MutableString GetSubstring(ConversionStorage<int>/*!*/ fixnumCast, MutableString/*!*/ self, [NotNull]Range/*!*/ range) {
     int begin, count;
     if (!NormalizeSubstringRange(fixnumCast, range, self.GetByteCount(), out begin, out count)) {
         return null;
     }
     return (count < 0) ? self.CreateInstance().TaintBy(self) : GetSubstring(self, begin, count);
 }
コード例 #10
0
        public static MutableString/*!*/ Repeat(MutableString/*!*/ self, [DefaultProtocol]int times) {
            if (times < 0) {
                throw RubyExceptions.CreateArgumentError("negative argument");
            }

            return self.CreateInstance().TaintBy(self).AppendMultiple(self, times);
        }
コード例 #11
0
        public static MutableString RemoveSubstringInPlace(ConversionStorage<int>/*!*/ fixnumCast, 
            MutableString/*!*/ self, [NotNull]Range/*!*/ range) {
            int begin = Protocols.CastToFixnum(fixnumCast, range.Begin);
            int end = Protocols.CastToFixnum(fixnumCast, range.End);

            if (!InInclusiveRangeNormalized(self, ref begin)) {
                return null;
            }

            end = IListOps.NormalizeIndex(self.Length, end);

            int count = range.ExcludeEnd ? end - begin : end - begin + 1;
            return count < 0 ? self.CreateInstance() : RemoveSubstringInPlace(self, begin, count);
        }
コード例 #12
0
        internal static MutableString/*!*/ Translate(MutableString/*!*/ src, MutableString/*!*/ from, MutableString/*!*/ to, 
            bool inplace, bool squeeze, out bool anyCharacterMaps) {
            Assert.NotNull(src, from, to);

            if (from.IsEmpty) {
                anyCharacterMaps = false;
                return inplace ? src : src.Clone();
            }

            MutableString dst;
            if (inplace) {
                dst = src;
            } else {
                dst = src.CreateInstance().TaintBy(src);
            }

            // TODO: KCODE
            src.RequireCompatibleEncoding(from);
            dst.RequireCompatibleEncoding(to);
            from.SwitchToCharacters();
            to.SwitchToCharacters();

            CharacterMap map = CharacterMap.Create(from, to);

            if (to.IsEmpty) {
                anyCharacterMaps = MutableString.TranslateRemove(src, dst, map);
            } else if (squeeze) {
                anyCharacterMaps = MutableString.TranslateSqueeze(src, dst, map);
            } else {
                anyCharacterMaps = MutableString.Translate(src, dst, map);
            }

            return dst;
        }
コード例 #13
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, 
            RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ regex, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();

            var matches = regex.Matches(tosConversion.Context.KCode, input);
            if (matches.Count == 0) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // create an empty result:
            result = input.CreateInstance().TaintBy(input);
            
            int offset = 0;
            foreach (MatchData match in matches) {
                matchScope.CurrentMatch = match;

                input.TrackChanges();
                if (block.Yield(match.GetValue(), out blockResult)) {
                    return true;
                }
                if (input.HasChanged) {
                    return false;
                }

                // resets the $~ scope variable to the last match (skipd if block jumped):
                matchScope.CurrentMatch = match;

                MutableString replacement = Protocols.ConvertToString(tosConversion, blockResult);
                result.TaintBy(replacement);

                // prematch:
                result.Append(input, offset, match.Index - offset);

                // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value):
                result.Append(replacement);

                offset = match.Index + match.Length;
            }

            // post-last-match:
            result.Append(input, offset, input.Length - offset);

            blockResult = null;
            return false;
        }
コード例 #14
0
 public static MutableString/*!*/ Dump(RubyContext/*!*/ context, MutableString/*!*/ self) {
     // Note that "self" could be a subclass of MutableString, and the return value should be
     // of the same type
     return self.CreateInstance().Append(GetQuotedStringRepresentation(self, context, true, '"')).TaintBy(self);
 }
コード例 #15
0
 private static MutableString/*!*/ InternalDelete(MutableString/*!*/ self, MutableString[]/*!*/ ranges) {
     BitArray map = new RangeParser(ranges).Parse();
     MutableString result = self.CreateInstance().TaintBy(self);
     for (int i = 0; i < self.Length; i++) {
         if (!map.Get(self.GetChar(i))) {
             result.Append(self.GetChar(i));
         }
     }
     return result;
 }
コード例 #16
0
        public static MutableString GetSubstring(RubyScope/*!*/ scope, MutableString/*!*/ self, 
            [NotNull]RubyRegex/*!*/ regex, [DefaultProtocol]int occurrance) {
            if (regex.IsEmpty) {
                return self.CreateInstance().TaintBy(self).TaintBy(regex, scope);
            }

            MatchData match = RegexpOps.Match(scope, regex, self);
            if (match == null || !RegexpOps.NormalizeGroupIndex(ref occurrance, match.GroupCount)) {
                return null;
            }

            MutableString result = match.AppendGroupValue(occurrance, self.CreateInstance());
            return result != null ? result.TaintBy(regex, scope) : null;
        }
コード例 #17
0
 private static RubyArray/*!*/ MakeRubyArray(MutableString/*!*/ self, MutableString[]/*!*/ elements, int start, int count) {
     RubyArray result = new RubyArray(elements.Length);
     for (int i = 0; i < count; i++) {
         result.Add(self.CreateInstance().Append(elements[start + i]).TaintBy(self));
     }
     return result;
 }
コード例 #18
0
 public static MutableString/*!*/ Chop(MutableString/*!*/ self) {
     return (self.Length == 0) ? self.CreateInstance().TaintBy(self) : ChopInteral(self.Clone());
 }
コード例 #19
0
        private static RubyArray/*!*/ InternalSplit(MutableString/*!*/ self, MutableString separator, StringSplitOptions options, int maxComponents) {
            if (separator == null || separator.Length == 1 && separator.GetChar(0) == ' ') {
                return WhitespaceSplit(self, maxComponents);
            }

            if (maxComponents <= 0) {
                maxComponents = Int32.MaxValue;
            }

            RubyArray result = new RubyArray(maxComponents == Int32.MaxValue ? 1 : maxComponents + 1);
            bool keepEmpty = (options & StringSplitOptions.RemoveEmptyEntries) != StringSplitOptions.RemoveEmptyEntries;

            int selfLength = self.Length;
            int i = 0;
            int next;
            while (maxComponents > 1 && i < selfLength && (next = IndexOf(self, separator, i)) != -1) {

                if (next > i || keepEmpty) {
                    result.Add(self.CreateInstance().Append(self, i, next - i).TaintBy(self));
                    maxComponents--;
                }

                i = next + separator.Length;
            }

            if (i < selfLength || keepEmpty) {
                result.Add(self.CreateInstance().Append(self, i, selfLength - i).TaintBy(self));
            }

            return result;
        }
コード例 #20
0
        public static MutableString/*!*/ Dump(RubyContext/*!*/ context, MutableString/*!*/ self) {
            StringBuilder result = new StringBuilder();
            result.Append('"');
            
            byte[] bytes = self.ToByteArray();
            for (int i = 0; i < bytes.Length; i++) {
                AppendStringRepresentationOfChar(result, bytes[i], i + 1 < bytes.Length ? bytes[i + 1] : -1, true);
            }

            result.Append('"');
            return self.CreateInstance().Append(result).TaintBy(self);
        }
コード例 #21
0
        public static MutableString/*!*/ RightJustify(MutableString/*!*/ self, 
            [DefaultProtocol]int width, [DefaultProtocol, NotNull]MutableString/*!*/ padding) {

            if (padding.Length == 0) {
                throw RubyExceptions.CreateArgumentError("zero width padding");
            }

            int count = width - self.Length;
            if (count <= 0) {
                return self;
            }

            int iterations = count / padding.Length;
            int remainder = count % padding.Length;
            MutableString result = self.CreateInstance().TaintBy(self).TaintBy(padding);

            for (int i = 0; i < iterations; i++) {
                result.Append(padding);
            }

            result.Append(padding.GetSlice(0, remainder));
            result.Append(self);

            return result;
        }
コード例 #22
0
        public static object EachLine(BlockParam block, MutableString/*!*/ self, [DefaultProtocol]MutableString/*!*/ separator) {
            if (separator == null) {
                separator = MutableString.Empty;
            }

            uint version = self.Version;

            MutableString paragraphSeparator;
            if (separator.IsEmpty) {
                separator = _DefaultLineSeparator;
                paragraphSeparator = _DefaultDoubleLineSeparator;
            } else {
                paragraphSeparator = null;
            }

            // TODO: this is slow, refactor when we redo MutableString
            MutableString str = self;
            int start = 0;

            // In "normal" mode just split the string at the end of each seperator occurrance.
            // In "paragraph" mode, split the string at the end of each occurrance of two or more
            // successive seperators.
            while (start < self.Length) {
                int end;
                if (paragraphSeparator == null) {
                    end = str.IndexOf(separator, start);
                    if (end >= 0) {
                        end += separator.Length;
                    } else {
                        end = str.Length;
                    }
                } else {
                    end = str.IndexOf(paragraphSeparator, start);
                    if (end >= 0) {
                        end += (2 * separator.Length);
                        while (str.IndexOf(separator, end) == end) {
                            end += separator.Length;
                        }
                    } else {
                        end = str.Length;
                    }
                }

                // Yield the current line
                if (block == null) {
                    throw RubyExceptions.NoBlockGiven();
                }

                object result;
                MutableString line = self.CreateInstance().TaintBy(self).Append(str, start, end - start);
                if (block.Yield(line, out result)) {
                    return result;
                }

                start = end;
            }

            // Ensure that the underlying string has not been mutated during the iteration
            RequireNoVersionChange(version, self);
            return self;
        }
コード例 #23
0
        public static MutableString RemoveSubstringInPlace(MutableString/*!*/ self,
            [DefaultProtocol]int start, [DefaultProtocol]int length) {

            if (length < 0) {
                return null;
            }

            if (!InInclusiveRangeNormalized(self, ref start)) {
                return null;
            }

            if (start + length > self.Length) {
                length = self.Length - start;
            }

            MutableString result = self.CreateInstance().Append(self, start, length).TaintBy(self);
            self.Remove(start, length);
            return result;
        }
コード例 #24
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ regex, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();

            MatchCollection matches = regex.Matches(input);
            if (matches.Count == 0) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // create an empty result:
            result = input.CreateInstance().TaintBy(input);
            
            int offset = 0;
            foreach (Match match in matches) {
                MatchData currentMatch = new MatchData(match, input);
                matchScope.CurrentMatch = currentMatch;

                uint version = input.Version;
                if (block.Yield(MutableString.Create(match.Value), out blockResult)) {
                    return true;
                }
                if (input.Version != version) {
                    return false;
                }

                // resets the $~ scope variable to the last match (skipd if block jumped):
                matchScope.CurrentMatch = currentMatch;

                MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult);
                result.TaintBy(replacement);

                // prematch:
                result.Append(input, offset, match.Index - offset);

                // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value):
                result.Append(replacement);

                offset = match.Index + match.Length;
            }

            // post-last-match:
            result.Append(input, offset, input.Length - offset);

            blockResult = null;
            return false;
        }
コード例 #25
0
        public static MutableString GetSubstring(MutableString/*!*/ self, 
            [DefaultProtocol]int start, [DefaultProtocol]int length) {

            start = NormalizeIndex(self, start);

            if (start == self.Length) {
                return self.CreateInstance().TaintBy(self);
            }

            if (start < 0 || start > self.Length || length < 0) {
                return null;
            }

            if (start + length > self.Length) {
                length = self.Length - start;
            }

            return self.CreateInstance().Append(self, start, length).TaintBy(self);
        }
コード例 #26
0
        private static MutableString ReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, MutableString/*!*/ replacement, RubyRegex/*!*/ pattern) {
            MatchData match = RegexpOps.Match(scope, pattern, input);
            if (match == null || !match.Success) {
                return null;
            }

            MutableString result = input.CreateInstance().TaintBy(input).TaintBy(replacement);
            
            // prematch:
            result.Append(input, 0, match.Index);

            AppendReplacementExpression(input, match, result, replacement);

            // postmatch:
            int offset = match.Index + match.Length;
            result.Append(input, offset, input.Length - offset);

            return result;
        }
コード例 #27
0
        public static MutableString GetSubstring(RubyScope/*!*/ scope, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) {
            if (regex.IsEmpty) {
                return self.CreateInstance().TaintBy(self).TaintBy(regex, scope);
            }

            MatchData match = RegexpOps.Match(scope, regex, self);
            if (match == null) {
                return null;
            }

            string result = match.Value;
            return (result.Length == 0) ? null : self.CreateInstance().TaintBy(self).Append(result).TaintBy(regex, scope);
        }
コード例 #28
0
        private static MutableString ReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, MutableString/*!*/ replacement, 
            RubyRegex/*!*/ regex) {
            var matchScope = scope.GetInnerMostClosureScope();
            
            // case of all
            MatchCollection matches = regex.Matches(input);
            if (matches.Count == 0) {
                matchScope.CurrentMatch = null;
                return null;
            }

            MutableString result = input.CreateInstance().TaintBy(input).TaintBy(replacement);

            int offset = 0;
            foreach (Match match in matches) {
                result.Append(input, offset, match.Index - offset);
                AppendReplacementExpression(input, match, result, replacement);
                offset = match.Index + match.Length;
            }

            result.Append(input, offset, input.Length - offset);

            matchScope.CurrentMatch = new MatchData(matches[matches.Count - 1], input);
            return result;
        }
コード例 #29
0
        public static MutableString/*!*/ Center(MutableString/*!*/ self, 
            [DefaultProtocol]int length,
            [Optional, DefaultProtocol]MutableString padding) {

            if (padding != null && padding.Length == 0) {
                throw RubyExceptions.CreateArgumentError("zero width padding");
            }

            if (self.Length >= length) {
                return self;
            }

            if (padding == null) {
                padding = _DefaultPadding;
            }

            char[] charArray = new char[length];
            int n = (length - self.Length) / 2;

            for (int i = 0; i < n; i++) {
                charArray[i] = padding.GetChar(i % padding.Length);
            }

            for (int i = 0; i < self.Length; i++) {
                charArray[n + i] = self.GetChar(i);
            }

            int m = length - self.Length - n;
            for (int i = 0; i < m; i++) {
                charArray[n + self.Length + i] = padding.GetChar(i % padding.Length);
            }

            return self.CreateInstance().Append(new String(charArray)).TaintBy(self).TaintBy(padding); 
        }
コード例 #30
0
        private static RubyArray/*!*/ CharacterSplit(MutableString/*!*/ str, int limit) {
            RubyArray result = new RubyArray();
            
            var charEnum = str.GetCharacters();
            int i = 0;
            while (limit <= 0 || result.Count < limit - 1) {
                if (!charEnum.MoveNext()) {
                    break;
                }

                result.Add(str.CreateInstance().Append(charEnum.Current).TaintBy(str));
                i++;
            }

            if (charEnum.HasMore || limit < 0) {
                result.Add(str.CreateInstance().AppendRemaining(charEnum).TaintBy(str));
            }
            
            return result;
        }