예제 #1
0
        internal bool ResolveStringsTo(StringStore store)
        {
            // If we've already resolved to this store, don't re-resolve
            if (store == this.LastResolvedStore)
            {
                return(this.LastResolveResult);
            }

            // Record we last resolved against this store and failed
            this.LastResolvedStore = store;
            this.LastResolveResult = false;

            // Look up symbol name *prefix* parts (all exact)
            for (int i = 0; i < this.SplitSymbolName8.Count - 1; ++i)
            {
                if (!store.TryFindString(this.SplitSymbolName8[i], this.IgnoreCase, out this.SymbolNamePrefixIdentifiers[i]))
                {
                    return(false);
                }
            }

            // Look up symbol name suffix (exact only if IsFullSuffix)
            if (this.IsFullSuffix)
            {
                if (!store.TryFindString(this.SymbolNameSuffix, this.IgnoreCase, out this.SymbolNameSuffixIdentifiers))
                {
                    return(false);
                }
            }
            else
            {
                if (this.SymbolNameSuffix.IsEmpty())
                {
                    this.SymbolNameSuffixIdentifiers = Range.Max;
                }
                else
                {
                    if (!store.TryGetRangeStartingWith(this.SymbolNameSuffix, out this.SymbolNameSuffixIdentifiers))
                    {
                        return(false);
                    }

                    // NOTE: Can't make a prefix Range case sensitive, so have to validate casing later
                    // Case-insensitive sort means you can have [..., array, Array, arrayList, ArrayList, ...], so no way to return case sensitive range starting with 'Array'
                }
            }

            // Look up parameters [and get the copy from the StringStore for fast comparison on signature]
            if (!store.TryFindString(this.Parameters8, this.IgnoreCase, out this.ParametersIdentifiers))
            {
                return(false);
            }
            this.Parameters8 = store[this.ParametersIdentifiers.Start];

            // If we found everything, record we succeeded
            this.LastResolveResult = true;

            return(true);
        }
예제 #2
0
        private string MatchesForWordToString(MemberIndex index, StringStore strings, String8 word)
        {
            Range matches;

            if (!strings.TryFindString(word, out matches))
            {
                return(String.Empty);
            }
            return(MatchesToString(index, matches));
        }
예제 #3
0
        private bool TryFindByPath(int parentNodeIndex, int currentPathPartIndex, String8Set path, StringStore strings, ref int matchingIndex)
        {
            // Try to find the string identifier for the next path part name
            Range currentPartIdentifier;

            if (!strings.TryFindString(path[currentPathPartIndex], out currentPartIdentifier))
            {
                return(false);
            }

            // Try to find nodes matching this name part and search within each of them
            int child = this.GetFirstChild(parentNodeIndex);

            while (child > 0)
            {
                if (currentPartIdentifier.Contains(this.GetNameIdentifier(child)))
                {
                    // If we've matched all parts, return success.
                    if (currentPathPartIndex == path.Count - 1)
                    {
                        matchingIndex = child;
                        return(true);
                    }
                    else
                    {
                        // Record that we matched up to this point
                        matchingIndex = child;

                        // If not, search under here for the remaining parts (for each match at this level)
                        if (TryFindByPath(child, currentPathPartIndex + 1, path, strings, ref matchingIndex))
                        {
                            return(true);
                        }
                    }
                }

                child = this.GetNextSibling(child);
            }

            return(false);
        }
예제 #4
0
        public void StringStore_CaseSensitivity()
        {
            // Sample Strings: Not all in order, including casing differences, including duplicates
            StringStore store = new StringStore();

            string[] strings  = { "bool", "bool", "boolean", "Boolean", "BOOLEAN", "array", "Array", "aRRay", "ARRAY", "Array", "Collections", "ARR", "BIT" };
            int[]    addedIDs = new int[strings.Length];

            // Add each value
            for (int i = 0; i < strings.Length; ++i)
            {
                addedIDs[i] = store.FindOrAddString(strings[i]);
            }

            // Verify each value comes back cased correctly (case sensitive add)
            for (int i = 0; i < strings.Length; ++i)
            {
                Assert.AreEqual(strings[i], store[addedIDs[i]].ToString());
            }

            // Convert to Immutable
            store.ConvertToImmutable();

            // Remap IDs
            for (int i = 0; i < strings.Length; ++i)
            {
                addedIDs[i] = store.GetSerializationIdentifier(addedIDs[i]);
            }

            // Verify each value comes back cased correctly (case sensitive values preserved on convert)
            for (int i = 0; i < strings.Length; ++i)
            {
                Assert.AreEqual(strings[i], store[addedIDs[i]].ToString());
            }

            // Verify values have ascending IDs and are in case insensitive *stable* order
            string last = store[0].ToString();

            for (int i = 1; i < store.Count; ++i)
            {
                string current = store[i].ToString();

                // Verify all strings are in case insensitive order
                int cmp = string.Compare(last, current, StringComparison.OrdinalIgnoreCase);
                Assert.IsTrue(cmp <= 0);

                // Verify case-insensitive ties are in case sensitive order relative to each other
                if (cmp == 0)
                {
                    Assert.IsTrue(string.Compare(last, current, StringComparison.Ordinal) < 0);
                }
                last = current;
            }

            // Verify searches return the range of capitalizations for the value
            byte[] buffer = new byte[20];
            for (int i = 0; i < strings.Length; ++i)
            {
                String8 value8 = String8.Convert(strings[i], buffer);

                // Verify the string is found
                Range range;
                Assert.IsTrue(store.TryFindString(value8, out range));

                // Verify the ID for the exact casing is reported within the range
                Assert.IsTrue(range.Contains(addedIDs[i]));

                // Verify every value in the range matches the value (case-insensitive)
                for (int j = range.Start; j <= range.End; ++j)
                {
                    String8 otherMatch = store[j];
                    Assert.AreEqual(0, value8.CompareTo(otherMatch, true), String.Format("'{0}' in match range wasn't reported equal to '{1}' being matched", otherMatch, value8));
                }

                // Verify the values just before and after the range don't match
                if (range.Start > 0)
                {
                    String8 valueBefore = store[range.Start - 1];
                    Assert.IsTrue(value8.CompareTo(valueBefore, true) > 0, String.Format("'{0}' before match range wasn't reported before '{1}' being matched", valueBefore, value8));
                }

                if (range.End < store.Count - 1)
                {
                    String8 valueAfter = store[range.End + 1];
                    Assert.IsTrue(value8.CompareTo(valueAfter, true) < 0, String.Format("'{0}' after match range wasn't reported after '{1}' being matched", valueAfter, value8));
                }

                // Ask for the case-sensitive range
                Range caseSensitive;
                Assert.IsTrue(store.TryFindString(value8, false, out caseSensitive));

                // Verify every value in the range matches the value (case-sensitive)
                for (int j = caseSensitive.Start; j <= caseSensitive.End; ++j)
                {
                    String8 otherMatch = store[j];
                    Assert.AreEqual(0, value8.CompareTo(otherMatch, false), String.Format("'{0}' in case sensitive range wasn't reported equal to '{1}' being matched", otherMatch, value8));
                }

                // Verify the values just before and after the range don't match
                if (caseSensitive.Start > 0)
                {
                    String8 valueBefore = store[caseSensitive.Start - 1];
                    Assert.IsTrue(value8.CompareTo(valueBefore, false) != 0, String.Format("'{0}' before case sensitive range still matches '{1}'", valueBefore, value8));
                }

                if (caseSensitive.End < store.Count - 1)
                {
                    String8 valueAfter = store[caseSensitive.End + 1];
                    Assert.IsTrue(value8.CompareTo(valueAfter, false) != 0, String.Format("'{0}' after case sensitive range still matches '{1}'", valueAfter, value8));
                }
            }

            // Verify MakeCaseSensitive goes to empty if the provided casing isn't any of the values
            String8 BOOLean = String8.Convert("BOOLean", buffer);
            Range   booleanRange;

            Assert.IsFalse(store.TryFindString(BOOLean, false, out booleanRange));
        }