Example #1
0
 public StringManager(string str)
 {
     _internalString = str;
     _ropeString = new RopeString(str);
 }
Example #2
0
 /// <summary>
 /// Append another rope string to back of current.
 /// </summary>
 /// <param name="ropeString">Another rope string.</param>
 /// <param name="fromIndex">Index in another string from we append.</param>
 public void AppendToBack(RopeString ropeString, int fromIndex)
 {
     AppendToBack(ropeString, fromIndex, ropeString.Length - fromIndex);
 }
Example #3
0
        private int SearchSectorByGlobalIndex(RopeString ropeString, int fromIndex)
        {
            var estimateSectorIndex = fromIndex / RopeSector.SectorSize;

            int stepSign;

            if (ropeString._descriptors[estimateSectorIndex].FirstIndexInGlobal > fromIndex)
                stepSign = -1;
            else
            {
                stepSign = 1;
            }

            while (estimateSectorIndex >= 0 && estimateSectorIndex < ropeString._descriptors.Count)
            {
                if (ropeString._descriptors[estimateSectorIndex].FirstIndexInGlobal <= fromIndex &&
                    ropeString._descriptors[estimateSectorIndex].FirstIndexInGlobal +
                    ropeString._descriptors[estimateSectorIndex].Sector.Length > fromIndex &&
                    ropeString._descriptors[estimateSectorIndex].Sector.Length > 0)
                    return estimateSectorIndex;

                estimateSectorIndex += stepSign;
            }

            return -1;
        }
Example #4
0
        private void AppendToBack(RopeString ropeString, int fromIndex, int length)
        {
            if (length == 0)
                return;

            // First we search sector with lesser or equals first index to fromIndex
            int anotherStringSectorIndex = SearchSectorByGlobalIndex(ropeString, fromIndex);

            if (anotherStringSectorIndex == -1)
                throw new InvalidOperationException("fromIndex ouside of bounds");

            // Cope from found sector from fromIndex to end to another new sector.
            var firstNewSector = new RopeSector();
            var firstOldSector = ropeString._descriptors[anotherStringSectorIndex].Sector;
            var indexInsideFirstSector = fromIndex -
                                         ropeString._descriptors[anotherStringSectorIndex].FirstIndexInGlobal;

            // If index inside sector is zero --- just copy full sector.
            if (indexInsideFirstSector > 0)
            {
                while (indexInsideFirstSector < firstOldSector.Length && firstNewSector.Length < length)
                {
                    firstNewSector.AppendToBack(firstOldSector[indexInsideFirstSector++]);
                }

                // Add new first sector to back of current string.
                _descriptors.Add(
                    new RopeSectorDescriptor
                    {
                        FirstIndexInGlobal = Length,
                        Sector = firstNewSector
                    });
                Length += firstNewSector.Length;
                ++anotherStringSectorIndex;
            }

            int lastIndex = fromIndex + length - 1;
            // First we search sector with lesser or equals first index to fromIndex
            int anotherStringSectorFinishIndex = SearchSectorByGlobalIndex(ropeString, lastIndex);

            if (anotherStringSectorFinishIndex == -1)
                throw new InvalidOperationException("fromIndex + length ouside of bounds");

            // Batch add all next sectors to back of currect string.
            while (anotherStringSectorIndex < anotherStringSectorFinishIndex)
            {
                RopeSector sector = ropeString._descriptors[anotherStringSectorIndex++].Sector;
                _descriptors.Add(
                    new RopeSectorDescriptor
                    {
                        FirstIndexInGlobal = Length,
                        Sector = sector
                    });
                Length += sector.Length;
            }

            // Add last sector if needed.
            if (anotherStringSectorFinishIndex >= anotherStringSectorIndex &&
                anotherStringSectorFinishIndex < ropeString._descriptors.Count &&
                ropeString._descriptors[anotherStringSectorFinishIndex].FirstIndexInGlobal <= lastIndex)
            {
                var lastSector = ropeString._descriptors[anotherStringSectorFinishIndex].Sector;
                int countOfCopiedChars = lastIndex -
                                         ropeString._descriptors[anotherStringSectorFinishIndex].FirstIndexInGlobal + 1;

                var newSector = new RopeSector();

                for (int indexInsideSector = 0; indexInsideSector < countOfCopiedChars; ++indexInsideSector)
                    newSector.AppendToBack(lastSector[indexInsideSector]);

                _descriptors.Add(new RopeSectorDescriptor { FirstIndexInGlobal = Length, Sector = newSector });
                Length += newSector.Length;
            }
        }
Example #5
0
        private static RopeString ConvertFromRegularString(string regularString)
        {
            var ropeString = new RopeString();

            int currentIndex = 0;
            while (currentIndex < regularString.Length)
            {
                var sector = new RopeSector();
                while (sector.Length < RopeSector.SectorSize && currentIndex < regularString.Length)
                {
                    sector.AppendToBack(regularString[currentIndex++]);
                }

                ropeString.PushSectorToBack(sector);
            }

            return ropeString;
        }
Example #6
0
        /// <summary>
        /// Returns substring of current string.
        /// </summary>
        /// <param name="fromIndex">Index of substring start.</param>
        /// <param name="length">Length of substring.</param>
        /// <returns>Substring.</returns>
        public RopeString Substring(int fromIndex, int length)
        {
            var result = new RopeString();

            result.AppendToBack(this, fromIndex, length);

            return result;
        }