示例#1
0
        /// <summary>
        /// Returns <b>true</b> if a Ruby file is successfully loaded, <b>false</b> if it is already loaded.
        /// </summary>
        /// <param name="globalScope">
        /// A scope against which the file should be executed or null to create a new scope.
        /// </param>
        /// <param name="self"></param>
        /// <param name="path"></param>
        /// <param name="flags"></param>
        /// <param name="loaded"></param>
        /// <returns>True if the file was loaded/executed by this call.</returns>
        public bool LoadFile(Scope globalScope, object self, MutableString /*!*/ path, LoadFlags flags, out object loaded)
        {
            Assert.NotNull(path);

            string assemblyName, typeName;

            string strPath = path.ConvertToString();

            if (TryParseAssemblyName(strPath, out typeName, out assemblyName))
            {
                if (AlreadyLoaded(strPath, (string)null, flags))
                {
                    loaded = ((flags & LoadFlags.ResolveLoaded) != 0) ? GetAssembly(assemblyName, true, false) : null;
                    return(false);
                }

                Assembly assembly = LoadAssembly(assemblyName, typeName, false, false);
                if (assembly != null)
                {
                    FileLoaded(path.Clone(), flags);
                    loaded = assembly;
                    return(true);
                }
            }

            return(LoadFromPath(globalScope, self, strPath, path.Encoding, flags, out loaded));
        }
示例#2
0
        public void ICloneable_op_Clone()
        {
            ICloneable expected = new MutableString("One");
            var actual = expected.Clone();

            Assert.Equal(expected, actual);
            Assert.NotSame(expected, actual);
        }
示例#3
0
        private MatchData(Match/*!*/ match, MutableString/*!*/ originalString, int[] kIndices) {
            Debug.Assert(match.Success);
            
            _match = match;

            // TODO (opt): create groups instead?
            _originalString = originalString.Clone().Freeze();

            _kIndices = kIndices;
            IsTainted = originalString.IsTainted;
        }
示例#4
0
        public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, 
            RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]RubyRegex pattern)
        {
            object blockResult;
            MutableString result;
            self.TrackChanges();
            object r = BlockReplaceAll(tosConversion, scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone());

            RequireNoVersionChange(self);
            return r;
        }
示例#5
0
        public static object SetHashElement(RubyContext /*!*/ context, IDictionary <object, object> /*!*/ obj, object key, object value)
        {
            MutableString str = key as MutableString;

            if (str != null)
            {
                key = str.Duplicate(context, false, str.Clone()).Freeze();
            }
            else
            {
                key = BaseSymbolDictionary.NullToObj(key);
            }
            return(obj[key] = value);
        }
示例#6
0
        public LexicalMatch MatchBeginning(string value)
        {
            if (null == value)
            {
                throw new ArgumentNullException("value");
            }

            if (0 == value.Length)
            {
                return(null);
            }

            var result = Match(value);

            if (null != result)
            {
                return(result);
            }

            var substring = new MutableString(value);
            var clone     = substring.Clone();

#if NET20
            foreach (var word in IEnumerableExtensionMethods.Reverse(substring.ToString().Split(' ')))
#else
            foreach (var word in substring.ToString().Split(' ').Reverse())
#endif
            {
                if (0 == word.Length)
                {
                    continue;
                }

                substring.RemoveFromEnd(word).Trim();
                result = Match(substring);
                if (null == result)
                {
                    continue;
                }

                result.Suffix = clone.Suffix(substring).Trim();
                return(result);
            }

            return(null);
        }
示例#7
0
        public static MutableString RemoveSubstringInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, 
            [NotNull]RubyRegex/*!*/ regex, [DefaultProtocol]int occurrance) {

            if (regex.IsEmpty) {
                return self.Clone().TaintBy(regex, scope);
            }

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

            return match.GroupSuccess(occurrance) ?
                RemoveSubstringInPlace(self, match.GetGroupStart(occurrance), match.GetGroupLength(occurrance)).TaintBy(regex, scope) : null;
        }
示例#8
0
        public static void TestHashCodeMultithread(TestedClass testWhat)
        {
            Int32 threadCount     = 2;
            Int32 iterationsCount = 1000000;


            BinaryArray   a           = new BinaryArray();
            MutableString s           = new MutableString();
            Barrier       beforeWrite = new Barrier(threadCount);
            Barrier       beforeRead  = new Barrier(threadCount);

            Action <int> action = (x) =>
            {
                while (index < iterationsCount)
                {
                    beforeWrite.SignalAndWait();
                    if ((previousIndex % threadCount) == x)
                    {
                        index++;
                        expectedHash = index;
                        switch (testWhat)
                        {
                        case TestedClass.BinaryArray: a.Assign(index); break;

                        case TestedClass.MutableString: s.Assign(index); expectedHash = s.Clone().GetHashCode(); break;
                        }
                        a.Assign(index);
                        if ((index % 100000) == 0)
                        {
                            Console.WriteLine("Index = " + index);
                        }
                    }
                    beforeRead.SignalAndWait();
                    int currentHash = 0;
                    switch (testWhat)
                    {
                    case TestedClass.BinaryArray: currentHash = a.GetHashCode(); break;

                    case TestedClass.MutableString: currentHash = s.GetHashCode(); break;
                    }
                    Assert.AreEqual(currentHash, expectedHash);
                    previousIndex = index;
                }
            };

            Task[] t = new Task[threadCount];
            for (int i = 0; i < threadCount; ++i)
            {
                int id = i;
                t[i] = new Task(() => action(id));
                t[i].Start();
            }

            Task.WaitAll(t);
        }
示例#9
0
 public static MutableString/*!*/ Squeeze(RubyContext/*!*/ context, MutableString/*!*/ self, [NotNull]params object[] args) {
     MutableString result = self.Clone();
     SqueezeMutableString(result, Protocols.CastToStrings(context, args));
     return result;
 }
示例#10
0
        public static MutableString ReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ self, 
            [DefaultProtocol, NotNull]RubyRegex/*!*/ pattern, [DefaultProtocol, NotNull]MutableString/*!*/ replacement) {

            return ReplaceAll(scope, self, replacement, pattern) ?? self.Clone();
        }
示例#11
0
        public static object BlockReplaceFirst(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]MutableString matchString) {

            object blockResult;
            MutableString result;
            var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE);

            return BlockReplaceFirst(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone());
        }
示例#12
0
        public static object BlockReplaceFirst(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]RubyRegex/*!*/ pattern) {

            object blockResult;
            MutableString result;
            return BlockReplaceFirst(scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone());
        }
示例#13
0
 public static MutableString/*!*/ Chop(MutableString/*!*/ self) {
     return self.IsEmpty ? self.CreateInstance().TaintBy(self) : ChopInteral(self.Clone());
 }
示例#14
0
        public void IListTest(IListTestType type)
        {
            MutableString s  = new MutableString();
            MutableString s1 = new MutableString();

            if (type == IListTestType.Contains)
            {
                s.Assign("qwertyui");
                Assert.AreEqual(s.Contains('r'), true);
                Assert.AreEqual(s.Contains('q'), true);
                Assert.AreEqual(s.Contains('i'), true);
                Assert.AreEqual(s.Contains('a'), false);
                Assert.AreEqual(s.Contains('s'), false);
                Assert.AreEqual(s.Contains('d'), false);
            }
            if (type == IListTestType.CopyTo)
            {
                s.Assign("sadfsf");
                s1.Assign("r");
                s1.CopyTo(s);
                Assert.AreEqual(s1, "r");
                Assert.AreEqual(s, "r");
                s.Assign("sadfsf");
                s1.Assign("r");
                s.CopyTo(s1);
                Assert.AreEqual(s1, "sadfsf");
                Assert.AreEqual(s, "sadfsf");
                s.Assign("qwer");
                Array.Resize(ref ar1, 10);
                s.CopyTo(ar1, 0);
                Assert.AreEqual(ar1[0], 'q');
                Assert.AreEqual(ar1[1], 'w');
                Assert.AreEqual(ar1[2], 'e');
                Assert.AreEqual(ar1[3], 'r');
            }
            if (type == IListTestType.IndexOf)
            {
                s.Assign("qwertyui");
                Assert.AreEqual(s.IndexOf('r'), 3);
                Assert.AreEqual(s.IndexOf('q'), 0);
                Assert.AreEqual(s.IndexOf('i'), 7);
                Assert.AreEqual(s.IndexOf('a'), -1);
                Assert.AreEqual(s.IndexOf('s'), -1);
                Assert.AreEqual(s.IndexOf('d'), -1);
            }
            if (type == IListTestType.Insert)
            {
                s.Assign("qazxcv");
                s.Insert(0, '1');
                Assert.AreEqual(s, "1qazxcv");
                s.Insert(2, '2');
                Assert.AreEqual(s, "1q2azxcv");
                s.Insert(8, '8');
                Assert.AreEqual(s, "1q2azxcv8");
            }
            if (type == IListTestType.Remove)
            {
                s.Assign("qwaedszf");
                s.Remove('e');
                Assert.AreEqual(s, "qwadszf");
                s.Remove('q');
                Assert.AreEqual(s, "wadszf");
                s.Remove('f');
                Assert.AreEqual(s, "wadsz");
            }
            if (type == IListTestType.RemoveAt)
            {
                s.Assign("qwaedszf");
                s.RemoveAt(3);
                Assert.AreEqual(s, "qwadszf");
                s.RemoveAt(0);
                Assert.AreEqual(s, "wadszf");
                s.RemoveAt(5);
                Assert.AreEqual(s, "wadsz");
            }
            if (type == IListTestType.Equals)
            {
                s.Assign("sd");
                Assert.AreEqual(s.Equals(s), true);
                Assert.AreEqual(MutableString.Equals(s, s), true);
                s1.Assign("sd");
                Assert.AreEqual(s.Equals(s1), true);
                Assert.AreEqual(true, s.Equals((IReadOnlyString)s1));

                s1.Assign("sdsd");
                Assert.AreEqual(s.Equals(s1), false);

                Assert.AreEqual(false, s.Equals((IReadOnlyString)s1));
                Assert.AreEqual(s1.Equals("sdsd"), true);
                Assert.AreEqual(s1.Equals("sdsd1"), false);
                Assert.AreEqual(s1.Equals("sdsq"), false);
                Assert.AreEqual(s1.Equals((MutableString)null), false);
                Assert.AreEqual(MutableString.Equals(null, null), true);
                Assert.AreEqual(MutableString.Equals(s, null), false);
                Assert.AreEqual(MutableString.Equals(null, s), false);

                Assert.AreEqual(MutableString.Equals(new MutableString(), new MutableString()), true);
            }
            if (type == IListTestType.Clone)
            {
                s.Assign("qwer");
                MutableString s2 = s.Clone();
                Assert.AreEqual(s2, "qwer");
                Assert.AreEqual(s2, s);
            }
            if (type == IListTestType.CompareTo)
            {
                s.Assign("qwer");
                s1.Assign("qwzz");
                Assert.AreEqual(s.CompareTo(s1) < 0, true);
                Assert.AreEqual(MutableString.Compare(s, s1) < 0, true);
                Assert.AreEqual(s1.CompareTo(s) > 0, true);
                Assert.AreEqual(MutableString.Compare(s1, s) > 0, true);
                s1.Assign("qwer");
                Assert.AreEqual(s.CompareTo(s1), 0);
                Assert.AreEqual(s1.CompareTo(s), 0);
                Assert.AreEqual(MutableString.Compare(s, s1), 0);
            }
        }
示例#15
0
        // Expand directory path - these cases exist:
        //
        // 1. Empty string or nil means return current directory
        // 2. ~ with non-existent HOME directory throws exception
        // 3. ~, ~/ or ~\ which expands to HOME
        // 4. ~foo is left unexpanded
        // 5. Expand to full path if path is a relative path
        // 
        // No attempt is made to determine whether the path is valid or not
        // Returned path is always canonicalized to forward slashes

        private static MutableString/*!*/ ExpandPath(RubyContext/*!*/ context, MutableString/*!*/ path) {
            PlatformAdaptationLayer pal = context.DomainManager.Platform;
            int length = path.Length;
            bool raisingRubyException = false;
            try {
                if (path == null || length == 0)
                    return RubyUtils.CanonicalizePath(MutableString.Create(Directory.GetCurrentDirectory()));

                if (path.GetChar(0) == '~') {
                    if (length == 1 || (path.GetChar(1) == Path.DirectorySeparatorChar ||
                                        path.GetChar(1) == Path.AltDirectorySeparatorChar)) {

                        string homeDirectory = pal.GetEnvironmentVariable("HOME");
                        if (homeDirectory == null) {
                            raisingRubyException = true;
                            throw RubyExceptions.CreateArgumentError("couldn't find HOME environment -- expanding `~'");
                        }
                        if (length <= 2) {
                            path = MutableString.Create(homeDirectory);
                        } else {
                            path = MutableString.Create(Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString()));
                        }
                        return RubyUtils.CanonicalizePath(path);
                    } else {
                        return path;
                    }
                } else {
                    string pathStr = path.ConvertToString();
                    MutableString result = RubyUtils.CanonicalizePath(MutableString.Create(Path.GetFullPath(pathStr)));

                    // Path.GetFullPath("c:/winDOWS/foo") returns "c:/winDOWS/foo", but Path.GetFullPath("c:/winDOWS/~") returns "c:/Windows/~".
                    // So we special-case it as this is not the Ruby behavior. Also, the Ruby behavior is very complicated about when it
                    // matches the case of the input argument, and when it matches the case of the file system. It can match the file system case
                    // for part of the result and not the rest. So we restrict the special-case to a very limited scenarios that unblock real-world code.
                    if (pathStr[pathStr.Length - 1] == '~' && String.Compare(pathStr, result.ConvertToString(), true) == 0) {
                        result = path.Clone();
                    }

                    return result;
                }
            } catch (Exception e) {
                if (raisingRubyException) {
                    throw;
                }
                // Re-throw exception as a reasonable Ruby exception
                throw RubyErrno.CreateEINVAL(path.ConvertToString(), e);
            }
        }
示例#16
0
文件: Loader.cs 项目: TerabyteX/main
        /// <summary>
        /// Returns <b>true</b> if a Ruby file is successfully loaded, <b>false</b> if it is already loaded.
        /// </summary>
        /// <param name="globalScope">
        /// A scope against which the file should be executed or null to create a new scope.
        /// </param>
        /// <param name="self"></param>
        /// <param name="path"></param>
        /// <param name="flags"></param>
        /// <param name="loaded"></param>
        /// <returns>True if the file was loaded/executed by this call.</returns>
        public bool LoadFile(Scope globalScope, object self, MutableString/*!*/ path, LoadFlags flags, out object loaded) {
            Assert.NotNull(path);

            string assemblyName, typeName;

            string strPath = path.ConvertToString();
            if (TryParseAssemblyName(strPath, out typeName, out assemblyName)) {

                if (AlreadyLoaded(strPath, (string)null, flags)) {
                    loaded = ((flags & LoadFlags.ResolveLoaded) != 0) ? GetAssembly(assemblyName, true, false) : null;
                    return false;
                }

                Assembly assembly = LoadAssembly(assemblyName, typeName, false, false);
                if (assembly != null) {
                    FileLoaded(path.Clone(), flags);
                    loaded = assembly;
                    return true;
                }
            }

            return LoadFromPath(globalScope, self, strPath, path.Encoding, flags, out loaded);
        }
示例#17
0
        public static MutableString FirstChar(MutableString/*!*/ self)
        {
            if (self.IsEmpty) {
                return self.Clone();
            }

            // TODO: optimize
            var enumerator = self.GetCharacters();
            enumerator.MoveNext();
            return enumerator.Current.ToMutableString(self.Encoding);
        }
示例#18
0
 public static MutableString Encode(
     ConversionStorage<IDictionary<object, object>>/*!*/ toHash,
     ConversionStorage<MutableString>/*!*/ toStr,
     MutableString/*!*/ self,
     [Optional]object toEncoding,
     [Optional]object fromEncoding,
     [DefaultParameterValue(null), DefaultProtocol]IDictionary<object, object> options)
 {
     // TODO: optimize
     return EncodeInPlace(toHash, toStr, self.Clone(), toEncoding, fromEncoding, options);
 }
示例#19
0
 public static MutableString/*!*/ Chop(MutableString/*!*/ self) {
     return (self.Length == 0) ? self.CreateInstance().TaintBy(self) : ChopInteral(self.Clone());
 }
示例#20
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ pattern, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();
            MatchData match = RegexpOps.Match(scope, pattern, input);
            if (match == null || !match.Success) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // copy upfront so that no modifications to the input string are included in the result:
            result = input.Clone();
            matchScope.CurrentMatch = match;

            if (block.Yield(MutableString.Create(match.Value), out blockResult)) {
                return true;
            }

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

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

            // Note - we don't interpolate special sequences like \1 in block return value
            result.Replace(match.Index, match.Length, replacement);

            blockResult = null;
            return false;
        }
示例#21
0
        public static MutableString/*!*/ ReplaceAll(ConversionStorage<MutableString>/*!*/ toS, BinaryOpStorage/*!*/ hashDefault, RubyScope/*!*/ scope, MutableString/*!*/ self,
            [DefaultProtocol, NotNull]RubyRegex/*!*/ pattern, [DefaultProtocol, NotNull]Union<IDictionary<object, object>, MutableString>/*!*/ replacement) {

            return ReplaceAll(toS, hashDefault, scope, self, replacement, pattern) ?? self.Clone();
        }
示例#22
0
        public static object BlockReplaceAll(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]RubyRegex pattern) {

            object blockResult;
            MutableString result;
            uint version = self.Version;
            object r = BlockReplaceAll(scope, self, block, pattern, out blockResult, out result) ? blockResult : (result ?? self.Clone());

            RequireNoVersionChange(version, self);
            return r;
        }
示例#23
0
        internal static MatchData Create(Match/*!*/ match, MutableString/*!*/ input, bool freezeInput, string/*!*/ encodedInput, RubyEncoding kcoding, int kStart) {
            if (!match.Success) {
                return null;
            }
            
            int[] kIndices;
            if (kcoding != null) {
                // TODO (opt): minimize GetByteCount calls, remove ToCharArray:
                char[] kCodedChars = encodedInput.ToCharArray();
                Encoding encoding = kcoding.StrictEncoding;
                kIndices = new int[match.Groups.Count * 2];
                for (int i = 0; i < match.Groups.Count; i++) {
                    var group = match.Groups[i];
                    if (group.Success) {
                        // group start index:
                        kIndices[i * 2] = kStart + encoding.GetByteCount(kCodedChars, 0, group.Index);
                        // group length:
                        kIndices[i * 2 + 1] = encoding.GetByteCount(kCodedChars, group.Index, group.Length);
                    } else {
                        kIndices[i * 2] = -1;
                    }
                }
            } else {
                kIndices = null;
            }

            if (freezeInput) {
                input = input.Clone().Freeze();
            }
            return new MatchData(match, input, kIndices);
        }
示例#24
0
        public static object BlockReplaceAll(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]MutableString matchString) {

            object blockResult;
            MutableString result;
            var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE);

            uint version = self.Version;
            object r = BlockReplaceAll(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone());
            RequireNoVersionChange(version, self);
            return r;
        }
示例#25
0
        public static MutableString/*!*/ LeftJustify(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.Clone().TaintBy(padding);

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

            result.Append(padding, 0, remainder);

            return result;
        }
示例#26
0
 public static MutableString/*!*/ Succ(MutableString/*!*/ self) {
     return SuccInPlace(self.Clone());
 }
示例#27
0
        public static MutableString RemoveSubstringInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, 
            [NotNull]RubyRegex/*!*/ regex, [DefaultProtocol]int occurrance) {

            if (regex.IsEmpty) {
                return self.Clone().TaintBy(regex, scope);
            }

            Group group = MatchRegexp(scope, self, regex, occurrance);
            return group == null ? null : RemoveSubstringInPlace(self, group.Index, group.Length).TaintBy(regex, scope);
        }
示例#28
0
 public static MutableString/*!*/ GetReversed(MutableString/*!*/ self) {
     return self.Clone().Reverse();
 }
示例#29
0
 public static MutableString/*!*/ UpCase(MutableString/*!*/ self) {
     MutableString result = self.Clone();
     UpCaseMutableString(result);
     return result;
 }
示例#30
0
        public static MutableString RemoveSubstringInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) {
            if (regex.IsEmpty) {
                return self.Clone().TaintBy(regex, scope);
            }

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

            return RemoveSubstringInPlace(self, match.Index, match.Length).TaintBy(regex, scope);
        }
示例#31
0
        public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, 
            RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]MutableString matchString) {

            object blockResult;
            MutableString result;
            // TODO:
            var regex = new RubyRegex(MutableString.CreateMutable(Regex.Escape(matchString.ToString()), matchString.Encoding), RubyRegexOptions.NONE);

            self.TrackChanges();
            object r = BlockReplaceAll(tosConversion, scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone());
            RequireNoVersionChange(self);
            return r;
        }
示例#32
0
 public static MutableString/*!*/ Capitalize(MutableString/*!*/ self) {
     MutableString result = self.Clone();
     CapitalizeMutableString(result);
     return result;
 }
示例#33
0
 public static MutableString/*!*/ Squeeze(RubyContext/*!*/ context, MutableString/*!*/ self, 
     [DefaultProtocol, NotNull, NotNullItems]params MutableString/*!*/[]/*!*/ args) {
     MutableString result = self.Clone();
     SqueezeMutableString(result, args);
     return result;
 }
示例#34
0
        private static MutableString InternalChomp(MutableString/*!*/ self, MutableString separator) {
            if (separator == null) {
                return self.Clone();
            }

            // Remove multiple trailing CR/LFs
            if (separator.Length == 0) {
                return ChompTrailingCarriageReturns(self, false).TaintBy(self);
            }

            // Remove single trailing CR/LFs
            MutableString result = self.Clone();
            int length = result.Length;
            if (separator.Length == 1 && separator.GetChar(0) == '\n') {
                if (length > 1 && result.GetChar(length - 2) == '\r' && result.GetChar(length - 1) == '\n') {
                    result.Remove(length - 2, 2);
                } else if (length > 0 && (self.GetChar(length - 1) == '\n' || result.GetChar(length - 1) == '\r')) {
                    result.Remove(length - 1, 1);
                }
            } else if (EndsWith(result, separator)) {
                result.Remove(length - separator.Length, separator.Length);
            }

            return result;
        }
示例#35
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;
        }