示例#1
0
 public int ReadInt()
 {
     Require(4);
     return(_easyBuffer.ReadInt());
 }
示例#2
0
        public static Options Of(params ByteString[] byteStrings)
        {
            if (byteStrings.Length == 0)
            {
                // With no choices we must always return -1. Create a trie that selects from an empty set.
                return(new Options(new ByteString[0], new int[] { 0, -1 }));
            }

            // Sort the byte strings which is required when recursively building the trie. Map the sorted
            // indexes to the caller's indexes.
            List <ByteString> list = new List <ByteString>(byteStrings);

            list.Sort();
            List <int> indexes = new List <int>();

            for (int i = 0; i < list.Count; i++)
            {
                indexes.Add(-1);
            }
            for (int i = 0; i < list.Count; i++)
            {
                int sortedIndex = list.BinarySearch(byteStrings[i]);
                indexes[sortedIndex] = i;
            }
            if (list[0].Size() == 0)
            {
                throw new ArgumentException("the empty byte string is not a supported option");
            }

            // Strip elements that will never be returned because they follow their own prefixes. For
            // example, if the caller provides ["abc", "abcde"] we will never return "abcde" because we
            // return as soon as we encounter "abc".
            for (int a = 0; a < list.Count; a++)
            {
                ByteString prefix = list[a];
                for (int b = a + 1; b < list.Count;)
                {
                    ByteString byteString = list[b];
                    if (!byteString.StartsWith(prefix))
                    {
                        break;
                    }
                    if (byteString.Size() == prefix.Size())
                    {
                        throw new ArgumentException("duplicate option: " + byteString);
                    }
                    if (indexes[b] > indexes[a])
                    {
                        list.RemoveAt(b);
                        indexes.Remove(b);
                    }
                    else
                    {
                        b++;
                    }
                }
            }

            var trieBytes = new EasyBuffer();

            BuildTrieRecursive(0L, trieBytes, 0, list, 0, list.Count, indexes);

            int[] trie = new int[IntCount(trieBytes)];
            for (int i = 0; i < trie.Length; i++)
            {
                trie[i] = trieBytes.ReadInt();
            }
            if (!trieBytes.Exhausted())
            {
                throw new AssertionException();
            }
            var cloneStrings = byteStrings.Clone();

            return(new Options((ByteString[])cloneStrings /* Defensive copy. */, trie));
        }