public static CharacterMap /*!*/ Create(MutableString /*!*/ from, MutableString /*!*/ to)
        {
            Debug.Assert(!from.IsEmpty);

            int  fromLength   = from.GetCharCount();
            bool complemental = from.StartsWith('^') && fromLength > 1;

            // TODO: kcodings
            // TODO: surrogates
            // TODO: max - min > threshold

            int min, max;

            if (from.DetectByteCharacters())
            {
                min = 0;
                max = 255;
            }
            else
            {
                min = Int32.MaxValue;
                max = -1;
                for (int i = (complemental ? 1 : 0); i < fromLength; i++)
                {
                    int c = from.GetChar(i);
                    if (c < min)
                    {
                        min = c;
                    }
                    if (c > max)
                    {
                        max = c;
                    }
                }
            }

            BitArray map;

            char[] image;

            if (complemental || to.IsEmpty)
            {
                image = null;
                map   = MakeBitmap(from, fromLength, complemental, min, max);
            }
            else
            {
                map   = null;
                image = new char[max - min + 1];

                // no need to initialize the array:
                Debug.Assert(Unmapped == 0);

                bool needMap = false;
                var  toEnum  = ExpandRanges(to, 0, to.GetCharCount(), true).GetEnumerator();
                foreach (var f in ExpandRanges(from, 0, fromLength, false))
                {
                    toEnum.MoveNext();
                    needMap |= (image[f - min] = toEnum.Current) == Unmapped;
                }

                if (needMap)
                {
                    map = MakeBitmap(from, fromLength, false, min, max);
                }
            }

            return(new CharacterMap(map, image, complemental ? to.GetLastChar() : -1, complemental, min, max));
        }
Example #2
0
 public bool EndsWith(char value)
 {
     return(_string.GetLastChar() == value);
 }
Example #3
0
        public static MutableString /*!*/ Basename(RubyClass /*!*/ self,
                                                   [DefaultProtocol, NotNull] MutableString /*!*/ path, [DefaultProtocol, NotNull, Optional] MutableString suffix)
        {
            if (path.IsEmpty)
            {
                return(path);
            }

            string strPath = path.ConvertToString();

            string[] parts = strPath.Split(new[] { DirectorySeparatorChar, AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries);

            if (parts.Length == 0)
            {
                return(MutableString.CreateMutable(path.Encoding).Append((char)path.GetLastChar()).TaintBy(path));
            }

            if (Environment.OSVersion.Platform != PlatformID.Unix && Environment.OSVersion.Platform != PlatformID.MacOSX)
            {
                string first = parts[0];
                if (strPath.Length >= 2 && IsDirectorySeparator(strPath[0]) && IsDirectorySeparator(strPath[1]))
                {
                    // UNC: skip 2 parts
                    if (parts.Length <= 2)
                    {
                        return(MutableString.CreateMutable(path.Encoding).Append(DirectorySeparatorChar).TaintBy(path));
                    }
                }
                else if (first.Length == 2 && Tokenizer.IsLetter(first[0]) && first[1] == ':')
                {
                    // skip drive letter "X:"
                    if (parts.Length <= 1)
                    {
                        var result = MutableString.CreateMutable(path.Encoding).TaintBy(path);
                        if (strPath.Length > 2)
                        {
                            result.Append(strPath[2]);
                        }
                        return(result);
                    }
                }
            }

            string last = parts[parts.Length - 1];

            if (MutableString.IsNullOrEmpty(suffix))
            {
                return(MutableString.CreateMutable(last, path.Encoding));
            }

            StringComparison comparison = Environment.OSVersion.Platform == PlatformID.Unix ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
            int matchLength             = last.Length;

            if (suffix != null)
            {
                string strSuffix = suffix.ToString();
                if (strSuffix.LastCharacter() == '*' && strSuffix.Length > 1)
                {
                    int suffixIdx = last.LastIndexOf(
                        strSuffix.Substring(0, strSuffix.Length - 1),
                        comparison
                        );
                    if (suffixIdx >= 0 && suffixIdx + strSuffix.Length <= last.Length)
                    {
                        matchLength = suffixIdx;
                    }
                }
                else if (last.EndsWith(strSuffix, comparison))
                {
                    matchLength = last.Length - strSuffix.Length;
                }
            }

            return(MutableString.CreateMutable(path.Encoding).Append(last, 0, matchLength).TaintBy(path));
        }