Example #1
0
        public static MemoryOwner <LineModificationType> ComputeDiff(ReadOnlySpan <char> oldText, ReadOnlySpan <char> newText, char separator)
        {
            // If the new text is empty, no modifications are returned
            if (newText.IsEmpty)
            {
                return(MemoryOwner <LineModificationType> .Empty);
            }

            int oldNumberOfLines = oldText.Count(separator) + 1;
            int newNumberOfLines = newText.Count(separator) + 1;

            // Fast path if the input text segments have the same length and are short enough
            if (oldText.Length == newText.Length &&
                oldNumberOfLines == newNumberOfLines &&
                oldNumberOfLines <= ShortPathNumberOfLinesThreshold &&
                oldText.SequenceEqual(newText))
            {
                return(MemoryOwner <LineModificationType> .Allocate(newNumberOfLines, AllocationMode.Clear));
            }

            using SpanOwner <object?> oldTemporaryValues = SpanOwner <object?> .Allocate(oldNumberOfLines);

            using SpanOwner <object?> newTemporaryValues = SpanOwner <object?> .Allocate(newNumberOfLines);

            ref object?oldTemporaryValuesRef = ref oldTemporaryValues.DangerousGetReference();
Example #2
0
        public static double ChangesRequired(string s1, string s2)
        {
            if (s1.Equals(s2))
            {
                return(0d);
            }

            if (s1.Length == 0)
            {
                return(s2.Length);
            }

            if (s2.Length == 0)
            {
                return(s1.Length);
            }

            using SpanOwner <int> v0Owner = SpanOwner <int> .Allocate(s2.Length + 1);

            using SpanOwner <int> v1Owner = SpanOwner <int> .Allocate(s2.Length + 1);

            Span <int> v0 = v0Owner.Span;
            Span <int> v1 = v1Owner.Span;

            for (int i = 0; i < v0.Length; i++)
            {
                v0[i] = i;
            }

            for (int i = 0; i < s1.Length; i++)
            {
                v1[0] = i + 1;

                int minv1 = v1[0];

                for (int j = 0; j < s2.Length; j++)
                {
                    int cost = 1;
                    if (s1[i] == s2[j])
                    {
                        cost = 0;
                    }
                    v1[j + 1] = Math.Min(
                        v1[j] + 1,                  // Cost of insertion
                        Math.Min(
                            v0[j + 1] + 1,          // Cost of remove
                            v0[j] + cost));         // Cost of substitution

                    minv1 = Math.Min(minv1, v1[j + 1]);
                }

                Span <int> vtemp = v0;
                v0 = v1;
                v1 = vtemp;
            }

            return(v0[s2.Length]);
        }
Example #3
0
        public static SpanOwner <T> Read <T>(
            this Stream stream, int elements)
            where T : unmanaged
        {
            var spanOwner = SpanOwner <T> .Allocate(elements);

            stream.Read(spanOwner.Span.Cast <T, byte>());
            return(spanOwner);
        }
            private static SpanOwner <ushort> LoadDefinitionsTable(int functionsCount)
            {
                Assert(functionsCount >= 0);

                return(functionsCount switch
                {
                    0 => SpanOwner <ushort> .Empty,
                    _ => SpanOwner <ushort> .Allocate(functionsCount)
                });
Example #5
0
    public string ReadString(int byteCount)
    {
        using var pooledBytes = byteCount > STACK_MAX ? SpanOwner <byte> .Allocate(byteCount) : SpanOwner <byte> .Empty;

        Span <byte> bytes = byteCount > STACK_MAX ? pooledBytes.Span : stackalloc byte[byteCount];

        bytes.Clear();
        int readBytes = ReadBytes(bytes);

        bytes = bytes[..readBytes];
Example #6
0
        static string CreateString(int count, Encoding encoding)
        {
            if (count == 0)
            {
                return(string.Empty);
            }
            using var spanOwner = SpanOwner <byte> .Allocate(count);

            return(encoding.GetString(spanOwner.Span));
        }
            public static MemoryOwner<Brainf_ckOperation>? TryParse(ReadOnlySpan<char> source, out SyntaxValidationResult validationResult)
            {
                // Check the syntax of the input source code
                validationResult = ValidateSyntax(source);

                if (!validationResult.IsSuccess) return null;

                // Allocate the buffer of binary items with the input operations
                using SpanOwner<Brainf_ckOperation> buffer = SpanOwner<Brainf_ckOperation>.Allocate(validationResult.OperatorsCount);
                ref Brainf_ckOperation bufferRef = ref buffer.DangerousGetReference();
        internal static unsafe string GetString(this Encoding encoding, ReadOnlySpan <byte> bytes)
        {
            using var spanOwner = SpanOwner <byte> .Allocate((int) bytes.Length);

            bytes.CopyTo(spanOwner.Span);

            fixed(byte *spanBytes = spanOwner.Span)
            {
                return(encoding.GetString(spanBytes, spanOwner.Length));
            }
        }
        public void Test_SpanOwnerOfT_AllocateAndGetMemoryAndSpan()
        {
            using var buffer = SpanOwner <int> .Allocate(127);

            Assert.IsTrue(buffer.Length == 127);
            Assert.IsTrue(buffer.Span.Length == 127);

            buffer.Span.Fill(42);

            Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42));
        }
            private static SpanOwner <int> LoadJumpTable <TOpcode>(
                Span <TOpcode> opcodes,
                out int functionsCount)
                where TOpcode : unmanaged, IOpcode
            {
                SpanOwner <int> jumpTable = SpanOwner <int> .Allocate(opcodes.Length);

                Brainf_ckInterpreter.LoadJumpTable(opcodes, jumpTable.Span, out functionsCount);

                return(jumpTable);
            }
        public static unsafe string InterleaveWithCharacter(this ReadOnlySpan <char> text, char c)
        {
            int textLength = text.Length;

            if (textLength == 0)
            {
                return(string.Empty);
            }

            using SpanOwner <char> buffer = SpanOwner <char> .Allocate(textLength * 2);

            ref char textRef   = ref text.DangerousGetReference();
Example #12
0
        public int SpanOwner()
        {
            var sum         = 0;
            var repetitions = Repetitions;

            for (var i = 0; i < repetitions; i++)
            {
                using var buffer = SpanOwner <byte> .Allocate(SizeInBytes, AllocationMode.Default);

                sum += buffer.Length;
            }

            return(sum);
        }
Example #13
0
        static void Main(string[] args)
        {
            var dis = Levenshtein.Distance("aaaaa", "aaaab");

            Console.WriteLine("Hello World!");
            using MemoryOwner <int> own = MemoryOwner <int> .Allocate(1);

            _ = own.Span;
            _ = own.Memory;
            using SpanOwner <int> ownSpan = SpanOwner <int> .Allocate(1);

            _ = ownSpan.Span;

            // Create an array and run the callback
            float[] array = new float[10_000];
        public void Test_SpanOwnerOfT_AllocateAndGetArray()
        {
            using var buffer = SpanOwner <int> .Allocate(127);

            var segment = buffer.DangerousGetArray();

            // See comments in the MemoryOwner<T> tests about this. The main difference
            // here is that we don't do the disposed checks, as SpanOwner<T> is optimized
            // with the assumption that usages after dispose are undefined behavior. This
            // is all documented in the XML docs for the SpanOwner<T> type.
            Assert.IsNotNull(segment.Array);
            Assert.IsTrue(segment.Array.Length >= buffer.Length);
            Assert.AreEqual(segment.Offset, 0);
            Assert.AreEqual(segment.Count, buffer.Length);
        }
        public void Test_SpanOwnerOfT_PooledBuffersAndClear()
        {
            using (var buffer = SpanOwner <int> .Allocate(127))
            {
                buffer.Span.Fill(42);
            }

            using (var buffer = SpanOwner <int> .Allocate(127))
            {
                Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42));
            }

            using (var buffer = SpanOwner <int> .Allocate(127, AllocationMode.Clear))
            {
                Assert.IsTrue(buffer.Span.ToArray().All(i => i == 0));
            }
        }
        public void Test_SpanOwnerOfT_AllocateFromCustomPoolAndGetMemoryAndSpan()
        {
            var pool = new TrackingArrayPool <int>();

            using (var buffer = SpanOwner <int> .Allocate(127, pool))
            {
                Assert.AreEqual(pool.RentedArrays.Count, 1);

                Assert.IsTrue(buffer.Length == 127);
                Assert.IsTrue(buffer.Span.Length == 127);

                buffer.Span.Fill(42);

                Assert.IsTrue(buffer.Span.ToArray().All(i => i == 42));
            }

            Assert.AreEqual(pool.RentedArrays.Count, 0);
        }
Example #17
0
        /// <summary>
        /// Prepares the input to MAC, following RFC 8439, section 2.8.
        /// </summary>
        /// <param name="aad">The associated data.</param>
        /// <param name="ciphertext">The ciphertext.</param>
        /// <returns>System.Byte[].</returns>
        private SpanOwner <byte> GetMacDataRfc8439(ReadOnlySpan <byte> aad, ReadOnlySpan <byte> ciphertext)
        {
            var aadPaddedLen        = (aad.Length % 16 == 0) ? aad.Length : (aad.Length + 16 - aad.Length % 16);
            var ciphertextLen       = ciphertext.Length;
            var ciphertextPaddedLen = (ciphertextLen % 16 == 0) ? ciphertextLen : (ciphertextLen + 16 - ciphertextLen % 16);

            var macData = SpanOwner <byte> .Allocate(aadPaddedLen + ciphertextPaddedLen + 16, AllocationMode.Clear);

            // Mac Text
            aad.CopyTo(macData.Span);
            ciphertext.CopyTo(macData.Span.Slice(aadPaddedLen, ciphertextLen));

            // Mac Length
            //macData[aadPaddedLen + ciphertextPaddedLen] = (byte)aad.Length;
            //macData[aadPaddedLen + ciphertextPaddedLen + 8] = (byte)ciphertextLen;
            SetMacLength(macData.Span, aadPaddedLen + ciphertextPaddedLen, aad.Length);
            SetMacLength(macData.Span, aadPaddedLen + ciphertextPaddedLen + sizeof(ulong), ciphertextLen);

            return(macData);
        }
Example #18
0
        /// <summary>
        /// The MAC key is the first 32 bytes of the first key stream block.
        /// </summary>
        /// <param name="nonce">The nonce.</param>
        /// <returns>System.Byte[].</returns>
        private SpanOwner <byte> GetMacKey(ReadOnlySpan <byte> nonce)
        {
            //var firstBlock = new byte[Snuffle.BLOCK_SIZE_IN_BYTES];
            //_macKeySnuffle.ProcessKeyStreamBlock(nonce, 0, firstBlock);

            //var result = new byte[Poly1305.MAC_KEY_SIZE_IN_BYTES];
            //Array.Copy(firstBlock, result, result.Length);
            //return result;

            using (var firstBlock = SpanOwner <byte> .Allocate(Snuffle.BLOCK_SIZE_IN_BYTES, AllocationMode.Clear))
            {
                //Span<byte> firstBlock = new byte[Snuffle.BLOCK_SIZE_IN_BYTES];
                _macKeySnuffle.ProcessKeyStreamBlock(nonce, 0, firstBlock.Span);

                var macKey = SpanOwner <byte> .Allocate(Poly1305.MAC_KEY_SIZE_IN_BYTES, AllocationMode.Clear);

                firstBlock.Span.Slice(0, Poly1305.MAC_KEY_SIZE_IN_BYTES).CopyTo(macKey.Span);
                firstBlock.Span.Clear();
                return(macKey);
            }
        }
        public static unsafe string GetFormattedPath(this IFile file)
        {
            const int separatorLength = 3; // " » "
            int
                numberOfSeparators = file.Path.Count(Path.DirectorySeparatorChar),
                formattedLength    = file.Path.Length + numberOfSeparators * (separatorLength - 1) + separatorLength;

            // The temporary buffer has space for one extra separator that is
            // always initialized even if it's not used in the final string.
            // This is done to avoid having to check the current index in the
            // main loop, which would be needed to check whether or not
            // the current separator should be written or not to the buffer.
            using SpanOwner <char> buffer = SpanOwner <char> .Allocate(formattedLength);

            fixed(char *p = &buffer.DangerousGetReference())
            {
                // Write the path parts
                int i = 0;

                foreach (ReadOnlySpan <char> part in file.Path.Tokenize(Path.DirectorySeparatorChar))
                {
                    part.CopyTo(new Span <char>(p + i, part.Length));

                    i += part.Length;

                    // Write the characters manually to avoid another stackalloc
                    p[i]     = ' ';
                    p[i + 1] = '»';
                    p[i + 2] = ' ';

                    i += 3;
                }

                // Create a string from the buffer and skip the last separator
                return(new string(p, 0, formattedLength - 3));
            }
        }
Example #20
0
        /*
         * Save a game using Quetzal format. Return 1 if OK, 0 if failed.
         */

        internal static zword SaveQuetzal(FileStream svf, System.IO.Stream stf)
        {
            zlong stkslen = 0;
            zword i, j, n;
            int   nvars, nargs, nstk, p;
            zbyte var;
            long  cmempos, stkspos;
            int   c;

            /* Write `IFZS' header. */
            if (!WriteChunk(svf, ID_FORM, 0))
            {
                return(0);
            }
            if (!WriteLong(svf, ID_IFZS))
            {
                return(0);
            }

            /* Write `IFhd' chunk. */
            FastMem.GetPc(out long pc);
            if (!WriteChunk(svf, ID_IFhd, 13))
            {
                return(0);
            }
            if (!WriteWord(svf, Main.h_release))
            {
                return(0);
            }
            for (i = ZMachine.H_SERIAL; i < ZMachine.H_SERIAL + 6; ++i)
            {
                if (!WriteByte(svf, FastMem.ZMData[FastMem.Zmp + i]))
                {
                    return(0);
                }
            }
            if (!WriteWord(svf, Main.h_checksum))
            {
                return(0);
            }
            if (!WriteLong(svf, pc << 8)) /* Includes pad. */ return {
                (0);
            }

            /* Write `CMem' chunk. */
            if ((cmempos = svf.Position) < 0)
            {
                return(0);
            }
            if (!WriteChunk(svf, ID_CMem, 0))
            {
                return(0);
            }
            // (void) fseek (stf, 0, SEEK_SET);
            stf.Position = 0;
            uint cmemlen;

            /* j holds current run length. */
            for (i = 0, j = 0, cmemlen = 0; i < Main.h_dynamic_size; ++i)
            {
                if ((c = stf.ReadByte()) == -1)
                {
                    return(0);
                }
                c ^= FastMem.ZMData[i];
                if (c == 0)
                {
                    ++j;    /* It's a run of equal bytes. */
                }
                else
                {
                    /* Write out any run there may be. */
                    if (j > 0)
                    {
                        for (; j > 0x100; j -= 0x100)
                        {
                            if (!WriteRun(svf, 0xFF))
                            {
                                return(0);
                            }
                            cmemlen += 2;
                        }
                        if (!WriteRun(svf, (byte)(j - 1)))
                        {
                            return(0);
                        }
                        cmemlen += 2;
                        j        = 0;
                    }
                    /* Any runs are now written. Write this (nonzero) byte. */
                    if (!WriteByte(svf, (zbyte)c))
                    {
                        return(0);
                    }
                    ++cmemlen;
                }
            }

            /*
             * Reached end of dynamic memory. We ignore any unwritten run there may be
             * at this point.
             */
            if ((cmemlen & 1) > 0)      /* Chunk length must be even. */
            {
                if (!WriteByte(svf, 0))
                {
                    return(0);
                }
            }

            /* Write `Stks' chunk. You are not expected to understand this. ;) */
            if ((stkspos = svf.Position) < 0)
            {
                return(0);
            }
            if (!WriteChunk(svf, ID_Stks, 0))
            {
                return(0);
            }

            using var buffer = SpanOwner <zword> .Allocate(General.STACK_SIZE / 4 + 1);

            var frames = buffer.Span;

            /*
             * We construct a list of frame indices, most recent first, in `frames'.
             * These indices are the offsets into the `stack' array of the word before
             * the first word pushed in each frame.
             */
            frames[0] = (zword)Main.sp; /* The frame we'd get by doing a call now. */
            for (i = (zword)(Main.fp + 4), n = 0; i < General.STACK_SIZE + 4; i = (zword)(Main.Stack[i - 3] + 5))
            {
                frames[++n] = i;
            }

            /*
             * All versions other than V6 can use evaluation stack outside a function
             * context. We write a faked stack frame (most fields zero) to cater for
             * this.
             */
            if (Main.h_version != ZMachine.V6)
            {
                for (i = 0; i < 6; ++i)
                {
                    if (!WriteByte(svf, 0))
                    {
                        return(0);
                    }
                }
                nstk = General.STACK_SIZE - frames[n];
                if (!WriteWord(svf, nstk))
                {
                    return(0);
                }
                for (j = General.STACK_SIZE - 1; j >= frames[n]; --j)
                {
                    if (!WriteWord(svf, Main.Stack[j]))
                    {
                        return(0);
                    }
                }
                stkslen = (zword)(8 + 2 * nstk);
            }

            /* Write out the rest of the stack frames. */
            for (i = n; i > 0; --i)
            {
                p     = frames[i] - 4; // p = stack + frames[i] - 4;	/* Points to call frame. */
                nvars = (Main.Stack[p] & 0x0F00) >> 8;
                nargs = Main.Stack[p] & 0x00FF;
                nstk  = (zword)(frames[i] - frames[i - 1] - nvars - 4);
                pc    = ((zlong)Main.Stack[p + 3] << 9) | Main.Stack[p + 2];

                switch (Main.Stack[p] & 0xF000) /* Check type of call. */
                {
                case 0x0000:                    /* Function. */
                    var = FastMem.ZMData[FastMem.Zmp + pc];
                    pc  = ((pc + 1) << 8) | (zlong)nvars;
                    break;

                case 0x1000:                               /* Procedure. */
                    var = 0;
                    pc  = (pc << 8) | 0x10 | (zlong)nvars; /* Set procedure flag. */
                    break;

                /* case 0x2000: */
                default:
                    Err.RuntimeError(ErrorCodes.ERR_SAVE_IN_INTER);
                    return(0);
                }
                if (nargs != 0)
                {
                    nargs = (zword)((1 << nargs) - 1);  /* Make args into bitmap. */
                }
                /* Write the main part of the frame... */
                if (!WriteLong(svf, pc) ||
                    !WriteByte(svf, var) ||
                    !WriteByte(svf, (byte)nargs) ||
                    !WriteWord(svf, nstk))
                {
                    return(0);
                }

                /* Write the variables and eval stack. */
                for (j = 0, --p; j < nvars + nstk; ++j, --p)
                {
                    if (!WriteWord(svf, Main.Stack[p]))
                    {
                        return(0);
                    }
                }

                /* Calculate length written thus far. */
                stkslen += (zword)(8 + 2 * (nvars + nstk));
            }

            /* Fill in variable chunk lengths. */
            uint ifzslen = 3 * 8 + 4 + 14 + cmemlen + stkslen;

            if ((cmemlen & 1) > 0)
            {
                ++ifzslen;
            }
            svf.Position = 4;
            if (!WriteLong(svf, ifzslen))
            {
                return(0);
            }
            svf.Position = cmempos + 4;
            if (!WriteLong(svf, cmemlen))
            {
                return(0);
            }
            svf.Position = stkspos + 4;
            if (!WriteLong(svf, stkslen))
            {
                return(0);
            }

            /* After all that, still nothing went wrong! */
            return(1);
        }
        public void Test_SpanOwnerOfT_InvalidRequestedSize()
        {
            using var buffer = SpanOwner <int> .Allocate(-1);

            Assert.Fail("You shouldn't be here");
        }