public bool TryFindString(String8 value, out Range matches)
        {
            if (value.IsEmpty())
            {
                matches = Range.Empty;
                return(true);
            }

            // Binary search sorted strings for the value
            int     min       = 0;
            int     max       = _sortedExistingValues.Count - 1;
            int     mid       = 0;
            int     cmp       = 0;
            String8 valueHere = String8.Empty;

            while (min <= max)
            {
                mid       = (min + max) / 2;
                valueHere = this[mid];

                cmp = value.CompareTo(valueHere, IgnoreCase);
                if (cmp == 0)
                {
                    // 'value' Found - look for bounds
                    break;
                }
                else if (cmp > 0)
                {
                    // 'value' is later - look after valueHere
                    min = mid + 1;
                }
                else
                {
                    // 'value' is earlier - look before valueHere
                    max = mid - 1;
                }
            }

            // If no match, set both bounds to insertion position
            if (cmp > 0)
            {
                // If 'value' was after last comparison, we'd insert after it
                matches = new Range(mid + 1);
                return(false);
            }
            else if (cmp < 0)
            {
                // If 'value' was before last comparison, we'd insert before it
                matches = new Range(mid);
                return(false);
            }

            matches = RangeForString(mid);
            return(true);
        }
Beispiel #2
0
        /// <summary>
        ///  Take a case insensitive range and restrict it to the case sensitive subset.
        ///  This can only be done for Ranges containing different casings of one value.
        ///  [Ranges from TryFindString, but not TryGetRangeStartingWith]
        /// </summary>
        /// <param name="r">Range to restrict</param>
        /// <param name="value">String8 casing of value to restrict to</param>
        /// <returns>Range constrained to subset matching value casing</returns>
        private Range MakeCaseSensitive(Range r, String8 value)
        {
            if (r.IsEmpty())
            {
                return(r);
            }

            // Verify this was called only for casing variations [there isn't a single Range for prefixes]
            if (this[r.End].Length != value.Length)
            {
                throw new ArgumentOutOfRangeException();
            }

            // Exclude values from start which don't match value case-sensitive
            int start;

            for (start = r.Start; start <= r.End; ++start)
            {
                if (value.CompareTo(this[start], false) == 0)
                {
                    break;
                }
            }

            // Exclude values from end which don't match value case-sensitive
            int end;

            for (end = r.End; end > start; --end)
            {
                if (value.CompareTo(this[end], false) == 0)
                {
                    break;
                }
            }

            return(new Range(start, end));
        }
Beispiel #3
0
 public int CompareValues(int leftIdentifier, int rightIdentifier)
 {
     if (leftIdentifier == 0)
     {
         if (rightIdentifier == 0)
         {
             // Both empty - equal
             return(0);
         }
         else
         {
             // Left is before right
             return(-1);
         }
     }
     else if (rightIdentifier == 0)
     {
         // Right is before left
         return(1);
     }
     else if (leftIdentifier < 0 && rightIdentifier < 0)
     {
         // If both new, compare in AddedValues
         return(_addedValues.CompareValues(-leftIdentifier, -rightIdentifier));
     }
     else if (leftIdentifier >= 0 && rightIdentifier >= 0)
     {
         // If both existing, compare in ExistingValues
         return(_existingValues.CompareValues(leftIdentifier, rightIdentifier));
     }
     else
     {
         // Otherwise, get and compare string values for each
         String8 left  = this[leftIdentifier];
         String8 right = this[rightIdentifier];
         return(left.CompareTo(right));
     }
 }