internal static ArraySegment <byte> UnescapeByteStringSlow([NotNull] byte[] buffer, int offset, int count, int offsetOfFirstZero = 0)
        {
            Contract.Requires(buffer != null && offset >= 0 && count >= 0);

            var tmp = new byte[count];

            int p   = offset;
            int end = offset + count;
            int i   = 0;

            if (offsetOfFirstZero > 0)
            {
                SliceHelpers.CopyBytesUnsafe(tmp, 0, buffer, offset, offsetOfFirstZero);
                p += offsetOfFirstZero;
                i  = offsetOfFirstZero;
            }

            while (p < end)
            {
                byte b = buffer[p++];
                if (b == 0)
                {                 // skip next FF
                    //TODO: check that next byte really is 0xFF
                    ++p;
                }
                tmp[i++] = b;
            }

            return(new ArraySegment <byte>(tmp, 0, i));
        }
Пример #2
0
        private void SetTagContent()
        {
            for (var i = 0; i < Document.Children.Count; i++)
            {
                ProcessTag(Document.Children[i]);
            }

            void ProcessTag(MustacheToken tag)
            {
                switch (tag)
                {
                case InlineToken inline:
                    inline.Content = new StringSlice(
                        content.Text,
                        inline.ContentStartPosition,
                        inline.ContentEndPosition - 1);
                    break;

                case LiteralToken literal:
                    literal.Content = SliceHelpers.SplitSliceToLines(new StringSlice(
                                                                         content.Text,
                                                                         literal.ContentStartPosition,
                                                                         literal.ContentEndPosition - 1)).ToArray();
                    break;

                case BlockToken blockTag:
                    foreach (var child in blockTag.Children)
                    {
                        ProcessTag(child);
                    }

                    break;
                }
            }
        }
Пример #3
0
        public void WorksEvenWhenSliceSizeAndNumberOfSlicesDoNotEvenlyDivideData()
        {
            var originalData = new []
            {
                (byte)'C',
                (byte)'a',
                (byte)'t'
            };
            Slice
                slice1 = SliceHelpers.CreateSlice(
                coefficients: new [] { true, false },
                data: new [] { originalData[0], originalData[1] }
                ),
                slice2 = SliceHelpers.CreateSlice(
                coefficients: new [] { true, true },
                data: new [] { (byte)(originalData[0] ^ originalData[2]), originalData[1] }
                );
            var solver = new SliceSolver(2, 3);

            solver.Remember(slice2);
            solver.Remember(slice1);
            var solved = solver.TrySolve(out var solution);

            Assert.True(solved);
            Assert.NotNull(solution);
            Assert.Equal(solution.Length, 3);
            Assert.True(solution.SequenceEqual(originalData));
        }
Пример #4
0
 /// <summary>Ceate a new slice buffer with the specified page size</summary>
 /// <param name="pageSize">Initial page size</param>
 public SliceBuffer(int pageSize)
 {
     if (pageSize < 0)
     {
         throw new ArgumentOutOfRangeException("pageSize", "Page size cannt be less than zero");
     }
     m_pageSize = pageSize == 0 ? DefaultPageSize : SliceHelpers.Align(pageSize);
 }
Пример #5
0
            public void ClonesASingleSlice()
            {
                var slice    = SliceHelpers.CreateSlice(coefficients: new bool[5], data: new byte[5]);
                var sequence = new [] { slice };
                var mixed    = sequence.Mix();

                Assert.Equal(5, mixed.GetCoefficients().Count());
                Assert.Equal(5, mixed.GetData().Count());
            }
		/// <summary>Copy a slice into the buffer, with optional alignement, and return a new identical slice.</summary>
		/// <param name="data">Data to copy in the buffer</param>
		/// <param name="aligned">If true, align the index of first byte of the slice with a multiple of 8 bytes</param>
		/// <returns>Slice that is the equivalent of <paramref name="data"/>, backed by the buffer.</returns>
		public Slice Intern(Slice data, bool aligned = false)
		{
			if (data.Count == 0)
			{
				// transform into the corresponding Slice.Nil / Slice.Empty singleton
				return data.Memoize();
			}

			SliceHelpers.EnsureSliceIsValid(ref data);

			// allocate the slice
			var slice = Allocate(data.Count, aligned);
			SliceHelpers.CopyBytesUnsafe(slice.Array, slice.Offset, data.Array, data.Offset, data.Count);
			return slice;
		}
Пример #7
0
        public void Test_SliceHelpers_NextPowerOfTwo()
        {
            // 0 is a special case, to simplify bugger handling logic
            Assert.That(SliceHelpers.NextPowerOfTwo(0), Is.EqualTo(1), "Special case for 0");
            Assert.That(SliceHelpers.NextPowerOfTwo(1), Is.EqualTo(1));
            Assert.That(SliceHelpers.NextPowerOfTwo(2), Is.EqualTo(2));

            for (int i = 2; i < 31; i++)
            {
                Assert.That(SliceHelpers.NextPowerOfTwo((1 << i) - 1), Is.EqualTo(1 << i));
                Assert.That(SliceHelpers.NextPowerOfTwo(1 << i), Is.EqualTo(1 << i));
            }

            Assert.That(() => SliceHelpers.NextPowerOfTwo(-1), Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(() => SliceHelpers.NextPowerOfTwo(-42), Throws.InstanceOf <ArgumentOutOfRangeException>());
        }
		/// <summary>Copy a slice into the buffer, immediately followed by a suffix, and return a new slice that is the concatenation of the two.</summary>
		/// <param name="data">Data to copy in the buffer</param>
		/// <param name="suffix">Suffix to copy immediately after <paramref name="data"/>.</param>
		/// <param name="aligned">If true, align the index of first byte of the slice with a multiple of 8 bytes</param>
		/// <returns>Slice that is the equivalent of <paramref name="data"/> plus <paramref name="suffix"/>, backed by the buffer.</returns>
		/// <remarks>When <paramref name="data"/> is empty, <paramref name="suffix"/> is returned without being copied to the buffer itself.</remarks>
		internal Slice Intern(Slice data, Slice suffix, bool aligned = false)
		{
			if (data.Count == 0)
			{
				// note: we don't memoize the suffix, because in most case, it comes from a constant, and it would be a waste to copy it other and other again...
				return suffix.Count > 0 ? suffix : data.Array == null ? Slice.Nil : Slice.Empty;
			}

			SliceHelpers.EnsureSliceIsValid(ref data);
			SliceHelpers.EnsureSliceIsValid(ref suffix);

			var slice = Allocate(data.Count + suffix.Count, aligned);
			SliceHelpers.CopyBytesUnsafe(slice.Array, slice.Offset, data.Array, data.Offset, data.Count);
			SliceHelpers.CopyBytesUnsafe(slice.Array, slice.Offset + data.Count, suffix.Array, suffix.Offset, suffix.Count);
			return slice;
		}
 public void EnsureCapacity(int minSize)
 {
     if (minSize > m_size)
     {
         int newSize = SliceHelpers.NextPowerOfTwo(minSize);
         if (newSize < 0)
         {
             newSize = minSize;
         }
         if (newSize < 8)
         {
             newSize = 8;
         }
         Array.Resize(ref m_words, newSize);
     }
 }
Пример #10
0
        public Task WritePixel(WritePixelCommand command)
        {
            var index         = SliceHelpers.GetIndex(command.X, command.Y);
            var relativeIndex = index - Offset;

            var pixel = _slice.Pixels[relativeIndex];

            //only replace pixel if new command is newer.
            if (command.Timestamp >= pixel.LastTimestamp || !pixel.LastTimestamp.HasValue)
            {
                pixel.Color         = command.Color;
                pixel.LastAuthor    = command.Author;
                pixel.LastTimestamp = command.Timestamp;
            }

            return(TaskDone.Done);
        }
Пример #11
0
        public void PutsOneByteBackTogether()
        {
            const byte value = 0xF5;
            var        slice = SliceHelpers.CreateSlice(
                coefficients: new [] { true },
                data: new [] { value }
                );
            var solver = new SliceSolver(1, 1);

            solver.Remember(slice);
            var solved = solver.TrySolve(out var solution);

            Assert.True(solved);
            Assert.NotNull(solution);
            Assert.Equal(solution.Length, 1);
            Assert.Equal(solution[0], value);
        }
Пример #12
0
        public void Test_SliceHelpers_ComputeHashCode()
        {
            //note: if everything fails, check that the hashcode algorithm hasn't changed also !

            Assert.That(SliceHelpers.ComputeHashCode(new byte[0], 0, 0), Is.EqualTo(-2128831035));
            Assert.That(SliceHelpers.ComputeHashCode(new byte[1], 0, 1), Is.EqualTo(84696351));
            Assert.That(SliceHelpers.ComputeHashCode(new byte[2], 0, 1), Is.EqualTo(84696351));
            Assert.That(SliceHelpers.ComputeHashCode(new byte[2], 1, 1), Is.EqualTo(84696351));
            Assert.That(SliceHelpers.ComputeHashCode(new byte[2], 0, 2), Is.EqualTo(292984781));
            Assert.That(SliceHelpers.ComputeHashCode(Encoding.Default.GetBytes("hello"), 0, 5), Is.EqualTo(1335831723));

            Assert.That(SliceHelpers.ComputeHashCodeUnsafe(new byte[0], 0, 0), Is.EqualTo(-2128831035));
            Assert.That(SliceHelpers.ComputeHashCodeUnsafe(new byte[1], 0, 1), Is.EqualTo(84696351));
            Assert.That(SliceHelpers.ComputeHashCodeUnsafe(new byte[2], 0, 1), Is.EqualTo(84696351));
            Assert.That(SliceHelpers.ComputeHashCodeUnsafe(new byte[2], 1, 1), Is.EqualTo(84696351));
            Assert.That(SliceHelpers.ComputeHashCodeUnsafe(new byte[2], 0, 2), Is.EqualTo(292984781));
            Assert.That(SliceHelpers.ComputeHashCodeUnsafe(Encoding.Default.GetBytes("hello"), 0, 5), Is.EqualTo(1335831723));
        }
        /// <summary>Writes a buffer with all instances of 0 escaped as '00 FF'</summary>
        internal static void WriteNulEscapedBytes(ref TupleWriter writer, byte type, [NotNull] byte[] value, int offset, int count)
        {
            int n = count;

            // we need to know if there are any NUL chars (\0) that need escaping...
            // (we will also need to add 1 byte to the buffer size per NUL)
            for (int i = offset, end = offset + count; i < end; ++i)
            {
                if (value[i] == 0)
                {
                    ++n;
                }
            }

            writer.Output.EnsureBytes(n + 2);
            var buffer = writer.Output.Buffer;
            int p      = writer.Output.Position;

            buffer[p++] = type;
            if (n > 0)
            {
                if (n == count)
                {                 // no NULs in the string, can copy all at once
                    SliceHelpers.CopyBytesUnsafe(buffer, p, value, offset, n);
                    p += n;
                }
                else
                {                 // we need to escape all NULs
                    for (int i = offset, end = offset + count; i < end; ++i)
                    {
                        byte b = value[i];
                        buffer[p++] = b;
                        if (b == 0)
                        {
                            buffer[p++] = 0xFF;
                        }
                    }
                }
            }
            buffer[p] = 0x00;
            writer.Output.Position = p + 1;
        }
        /// <summary>Writes a buffer with all instances of 0 escaped as '00 FF'</summary>
        private static void WriteNulEscapedBytes(ref TupleWriter writer, byte type, [NotNull] byte[] value)
        {
            int n = value.Length;

            // we need to know if there are any NUL chars (\0) that need escaping...
            // (we will also need to add 1 byte to the buffer size per NUL)
            foreach (byte b in value)
            {
                if (b == 0)
                {
                    ++n;
                }
            }

            writer.Output.EnsureBytes(n + 2);
            var buffer = writer.Output.Buffer;
            int p      = writer.Output.Position;

            buffer[p++] = type;
            if (n > 0)
            {
                if (n == value.Length)
                {                 // no NULs in the string, can copy all at once
                    SliceHelpers.CopyBytesUnsafe(buffer, p, value, 0, n);
                    p += n;
                }
                else
                {                 // we need to escape all NULs
                    foreach (byte b in value)
                    {
                        buffer[p++] = b;
                        if (b == 0)
                        {
                            buffer[p++] = 0xFF;
                        }
                    }
                }
            }
            buffer[p++]            = 0x00;
            writer.Output.Position = p;
        }
Пример #15
0
 public void EnsureCapacity(int minSize)
 {
     if (minSize > m_size)
     {
         int newSize = SliceHelpers.NextPowerOfTwo(minSize);
         if (newSize < 0)
         {
             newSize = minSize;
         }
         if (newSize < 8)
         {
             newSize = 8;
         }
         //Console.WriteLine("> resize buffer to {0} words", newSize);
         Array.Resize(ref m_words, newSize);
     }
     //else
     //{
     //	Console.WriteLine("> buffer has enough capacity {0} for min size {1}", m_words.Length, minSize);
     //}
 }
Пример #16
0
        internal static CompressedWord[] DecodeWords(Slice data, int size, BitRange bounds)
        {
            Contract.Requires(size >= 0 && data.Count >= 4 && (data.Count & 3) == 0);

            int capacity = SliceHelpers.NextPowerOfTwo(size);

            if (capacity < 0)
            {
                capacity = size;
            }
            var words = new CompressedWord[capacity];

            var end = data.Offset + data.Count;

            for (int i = 0, p = data.Offset + 4; p < end; i++, p += 4)
            {
                words[i] = new CompressedWord(data.ReadUInt32(p, 4));
            }

            return(words);
        }
Пример #17
0
        public void PutsTwoSequentialSlicesBackTogether()
        {
            const byte
                value1 = 0xFF,
                value2 = 0x55;
            Slice
                slice1 = SliceHelpers.CreateSlice(
                coefficients: new [] { true, false },
                data: new [] { value1 }),
                slice2 = SliceHelpers.CreateSlice(
                coefficients: new [] { false, true },
                data: new [] { value2 });
            var solver = new SliceSolver(1, 2);

            solver.Remember(slice1);
            solver.Remember(slice2);
            var solved = solver.TrySolve(out var solution);

            Assert.True(solved);
            Assert.NotNull(solution);
            Assert.Equal(solution.Length, 2);
            Assert.Equal(solution[0], value1);
            Assert.Equal(solution[1], value2);
        }
Пример #18
0
        public void Test_SliceHelpers_Align()
        {
            // Even though 0 is a multiple of 16, it is always rounded up to 16 to simplify buffer handling logic
            Assert.That(SliceHelpers.Align(0), Is.EqualTo(16));
            // 1..16 => 16
            for (int i = 1; i <= 16; i++)
            {
                Assert.That(SliceHelpers.Align(i), Is.EqualTo(16), "Align({0}) => 16", i);
            }
            // 17..32 => 32
            for (int i = 17; i <= 32; i++)
            {
                Assert.That(SliceHelpers.Align(i), Is.EqualTo(32), "Align({0}) => 32", i);
            }
            // 33..48 => 48
            for (int i = 33; i <= 48; i++)
            {
                Assert.That(SliceHelpers.Align(i), Is.EqualTo(48), "Align({0}) => 48", i);
            }

            // 2^N-1
            for (int i = 6; i < 30; i++)
            {
                Assert.That(SliceHelpers.Align((1 << i) - 1), Is.EqualTo(1 << i));
            }
            // largest non overflowing
            Assert.That(() => SliceHelpers.Align(int.MaxValue - 15), Is.EqualTo((int.MaxValue - 15)));

            // overflow
            Assert.That(() => SliceHelpers.Align(int.MaxValue), Throws.InstanceOf <OverflowException>());
            Assert.That(() => SliceHelpers.Align(int.MaxValue - 14), Throws.InstanceOf <OverflowException>());

            // negative values
            Assert.That(() => SliceHelpers.Align(-1), Throws.InstanceOf <ArgumentOutOfRangeException>());
            Assert.That(() => SliceHelpers.Align(int.MinValue), Throws.InstanceOf <ArgumentOutOfRangeException>());
        }
Пример #19
0
        public void CanSolveWithACombinedSlice()
        {
            const byte
                value1 = 0xFF,
                value2 = 0x55;
            Slice
                slice1 = SliceHelpers.CreateSlice(
                coefficients: new [] { true, false },
                data: new [] { value1 }),
                slice2 = SliceHelpers.CreateSlice(
                coefficients: new [] { true, true },
                data: new [] { (byte)(value2 ^ value1) });
            var solver = new SliceSolver(1, 2);

            solver.Remember(slice1);
            solver.Remember(slice2);
            var solved = solver.TrySolve(out var solution);

            Assert.True(solved);
            Assert.NotNull(solution);
            Assert.Equal(solution.Length, 2);
            Assert.Equal(solution[0], value1);
            Assert.Equal(solution[1], value2);
        }