Пример #1
0
 public bool Exhausted()
 {
     if (_closed)
     {
         throw new IllegalStateException("closed");
     }
     return(_easyBuffer.Exhausted() && _source.Read(_easyBuffer, Segment.SIZE) <= 0);
 }
Пример #2
0
        private void assertCodePointDecoded(String hex, params int[] codePoints)
        {
            var buffer = new EasyBuffer().Write(ByteString.DecodeHex(hex));

            foreach (var codePoint in codePoints)
            {
                Assert.AreEqual(codePoint, buffer.ReadUtf8CodePoint());
            }
            Assert.True(buffer.Exhausted());
        }
Пример #3
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));
        }