Exemple #1
0
        internal ValueTask <int> SendAsync(ReadOnlyMemory <byte> buffer, SocketFlags socketFlags, bool fromNetworkStream, CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return(new ValueTask <int>(Task.FromCanceled <int>(cancellationToken)));
            }

            // TODO https://github.com/dotnet/corefx/issues/24430:
            // Fully plumb cancellation down into socket operations.

            Int32TaskSocketAsyncEventArgs saea = RentSocketAsyncEventArgs(isReceive: false);

            if (saea != null)
            {
                // We got a cached instance. Configure the buffer and initate the operation.
                ConfigureBuffer(saea, MemoryMarshal.AsMemory <byte>(buffer), socketFlags, wrapExceptionsInIOExceptions: fromNetworkStream);
                return(GetValueTaskForSendReceive(SendAsync(saea), saea, fromNetworkStream, isReceive: false));
            }
            else
            {
                // We couldn't get a cached instance, due to a concurrent send operation on the socket.
                // Fall back to wrapping APM.
                return(new ValueTask <int>(SendAsyncApm(buffer, socketFlags)));
            }
        }
Exemple #2
0
        async Task SendAsync(ReadOnlySequence <byte> buffer)
        {
            if (buffer.IsEmpty)
            {
                return;
            }

            if (buffer.IsSingleSegment)
            {
                await socket.SendAsync(MemoryMarshal.AsMemory(buffer.First), SocketFlags.None);
            }
            else
            {
                var list = new List <ArraySegment <byte> >();

                foreach (var memory in buffer)
                {
                    if (MemoryMarshal.TryGetArray(memory, out var segment))
                    {
                        list.Add(segment);
                    }
                    else
                    {
                        throw new Exception("BOOM!");
                    }
                }

                await socket.SendAsync(list, SocketFlags.None);
            }
        }
Exemple #3
0
        public unsafe void Test_MemoryExtensions_FromString_CastAndPin(int size, int preOffset, int postOffset)
        {
            // Same test as before to validate pinning, but starting from a string
            var           data          = new string('a', size);
            Memory <char> memoryOfChars = MemoryMarshal.AsMemory(data.AsMemory()).Slice(preOffset);
            Memory <byte> memoryOfBytes = memoryOfChars.Cast <char, byte>().Slice(postOffset);

            using (var handle1 = memoryOfBytes.Pin())
            {
                void *p1 = handle1.Pointer;
                void *p2 = Unsafe.AsPointer(ref data.DangerousGetReferenceAt(preOffset + (postOffset * sizeof(byte) / sizeof(char))));

                Assert.IsTrue(p1 == p2);
            }

            // Here we also add an extra test just like the one above, but casting to a type
            // that is bigger in byte size than char. Just to double check the casting logic.
            Memory <int> memoryOfInts = memoryOfChars.Cast <char, int>().Slice(postOffset);

            using (var handle2 = memoryOfInts.Pin())
            {
                void *p3 = handle2.Pointer;
                void *p4 = Unsafe.AsPointer(ref data.DangerousGetReferenceAt(preOffset + (postOffset * sizeof(int) / sizeof(char))));

                Assert.IsTrue(p3 == p4);
            }
        }
Exemple #4
0
        /// <summary>
        /// Modifies a file path by lowercasing the file name.
        /// </summary>
        /// <param name="filePath">A file path.</param>
        public static void FileNameToLower(ReadOnlyMemory <char> filePath)
        {
            if (filePath.IsEmpty)
            {
                return;
            }

            Memory <char> filePathMemory = MemoryMarshal.AsMemory(filePath);
            int           current        = filePath.Span.LastIndexOf(Path.DirectorySeparatorChar) + 1;

            if (current < 1)
            {
                return;
            }

            while (current < filePath.Length)
            {
                ref char start = ref filePathMemory.Span[current];

                if (start >= 'A' && start <= 'Z')
                {
                    start = (char)(start + 32);
                }

                current++;
            }
Exemple #5
0
        private static SocketAwaitable DoSendAsync(Socket socket, SocketAsyncEventArgs args, ReadOnlyMemory <byte> memory, string name)
        {
            // The BufferList getter is much less expensive then the setter.
            if (args.BufferList != null)
            {
                args.BufferList = null;
            }

#if SOCKET_STREAM_BUFFERS
            args.SetBuffer(MemoryMarshal.AsMemory(memory));
#else
            var segment = memory.GetArray();

            args.SetBuffer(segment.Array, segment.Offset, segment.Count);
#endif
            Helpers.DebugLog(name, $"## {nameof(socket.SendAsync)} {memory.Length}");
            if (socket.SendAsync(args))
            {
                Helpers.Incr(Counter.SocketSendAsyncSingleAsync);
            }
            else
            {
                Helpers.Incr(Counter.SocketSendAsyncSingleSync);
                SocketAwaitable.OnCompleted(args);
            }

            return(GetAwaitable(args));
        }
Exemple #6
0
        private static unsafe void AsMemory_Roundtrips_Core <T>(ReadOnlyMemory <T> readOnlyMemory)
        {
            Memory <T>         memory        = MemoryMarshal.AsMemory(readOnlyMemory);
            ReadOnlyMemory <T> readOnlyClone = memory;

            // Equals
            Assert.True(readOnlyMemory.Equals(readOnlyClone));
            Assert.True(readOnlyMemory.Equals((object)readOnlyClone));
            Assert.True(readOnlyMemory.Equals((object)memory));

            // Span
            Assert.True(readOnlyMemory.Span == readOnlyClone.Span);
            Assert.True(readOnlyMemory.Span == memory.Span);

            // TryGetArray
            Assert.True(MemoryMarshal.TryGetArray(readOnlyMemory, out ArraySegment <T> array1) == memory.TryGetArray(out ArraySegment <T> array2));
            Assert.Same(array1.Array, array2.Array);
            Assert.Equal(array1.Offset, array2.Offset);
            Assert.Equal(array1.Count, array2.Count);

            // Retain
            using (MemoryHandle readOnlyMemoryHandle = readOnlyMemory.Retain())
                using (MemoryHandle readOnlyCloneHandle = readOnlyMemory.Retain())
                    using (MemoryHandle memoryHandle = readOnlyMemory.Retain())
                    {
                        Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)readOnlyCloneHandle.Pointer);
                        Assert.Equal((IntPtr)readOnlyMemoryHandle.Pointer, (IntPtr)memoryHandle.Pointer);
                    }
        }
Exemple #7
0
        public static void Memory_ToArray_Roundtrips(string input)
        {
            ReadOnlyMemory <char> readonlyMemory = input.AsMemory();
            Memory <char>         m = MemoryMarshal.AsMemory(readonlyMemory);

            Assert.Equal(input, new string(m.ToArray()));
        }
Exemple #8
0
 protected override Memory <byte> GetByteMemory(int start, int length)
 {
     // We play a trick with memory marshal to convert the readonly memory into
     // a writable memory. Why is this safe? Because this class takes a writable memory object
     // in the constructor, so we're just functionally casting memory -> readonlymemory -> memory.
     return(MemoryMarshal.AsMemory(this.GetReadOnlyByteMemory(start, length)));
 }
        public static void Write(this BinaryWriter writer, ReadOnlySpan <char> chars)
        {
            if (_writeCharsShim != null)
            {
                _writeCharsShim(writer, chars);
                return;
            }

            var encoding = TryGetEncoding(writer);

            if (encoding != null)
            {
                var array = ArrayPool <byte> .Shared.Rent(encoding.GetByteCount(chars));

                try
                {
                    var byteCount = encoding.GetBytes(chars, array);

                    PrefixCodingHelper.Write7BitEncodedInt(writer, byteCount);
                    writer.Write(array, index: 0, byteCount);
                }
                finally
                {
                    ArrayPool <byte> .Shared.Return(array);
                }
            }

            var str = new string('\0', chars.Length);

            chars.CopyTo(MemoryMarshal.AsMemory(str.AsMemory()).Span);

            writer.Write(str);
        }
Exemple #10
0
        public override int Send(ReadOnlyMemory <byte> buffer, IPEndPoint remoteEndPoint)
        {
            m_SendSAEA.SetBuffer(MemoryMarshal.AsMemory(buffer));
            m_SendSAEA.RemoteEndPoint = remoteEndPoint;

            return(SendSAEA_DoSend());
        }
Exemple #11
0
        public static void ToStringMemoryOverFullStringReturnsOriginal()
        {
            string original = TestHelpers.BuildString(10, 42);

            ReadOnlyMemory <char> readOnlyMemory = original.AsMemory();
            Memory <char>         memory         = MemoryMarshal.AsMemory(readOnlyMemory);

            string returnedString           = memory.ToString();
            string returnedStringUsingSlice = memory.Slice(0, original.Length).ToString();

            string subString1 = memory.Slice(1).ToString();
            string subString2 = memory.Slice(0, 2).ToString();
            string subString3 = memory.Slice(1, 2).ToString();

            Assert.Equal(original, returnedString);
            Assert.Equal(original, returnedStringUsingSlice);

            Assert.Equal(original.Substring(1), subString1);
            Assert.Equal(original.Substring(0, 2), subString2);
            Assert.Equal(original.Substring(1, 2), subString3);

            Assert.Same(original, returnedString);
            Assert.Same(original, returnedStringUsingSlice);

            Assert.NotSame(original, subString1);
            Assert.NotSame(original, subString2);
            Assert.NotSame(original, subString3);

            Assert.NotSame(subString1, subString2);
            Assert.NotSame(subString1, subString3);
            Assert.NotSame(subString2, subString3);
        }
Exemple #12
0
        public NdrBuffer(ReadOnlyMemory <byte> memory, bool align = true)
            : this(align)
        {
            backingBuffer = MemoryMarshal.AsMemory(memory);

            MoveByOffset(0);
        }
Exemple #13
0
        public static void Memory_Span_Roundtrips(string input)
        {
            ReadOnlyMemory <char> readonlyMemory = input.AsReadOnlyMemory();
            Memory <char>         m = MemoryMarshal.AsMemory(readonlyMemory);
            ReadOnlySpan <char>   s = m.Span;

            Assert.Equal(input, new string(s.ToArray()));
        }
Exemple #14
0
        public static void Memory_Slice_MatchesSubstring(string input, int offset, int count)
        {
            ReadOnlyMemory <char> readonlyMemory = input.AsMemory();
            Memory <char>         m = MemoryMarshal.AsMemory(readonlyMemory);

            Assert.Equal(input.Substring(offset, count), new string(m.Slice(offset, count).ToArray()));
            Assert.Equal(input.Substring(offset, count), new string(m.Slice(offset, count).Span.ToArray()));
            Assert.Equal(input.Substring(offset), new string(m.Slice(offset).ToArray()));
        }
Exemple #15
0
        public static void ToStringMemoryFromReadOnlyMemory()
        {
            string        testString = "abcdefg";
            Memory <char> memory     = MemoryMarshal.AsMemory(testString.AsMemory());

            Assert.Equal(testString, memory.ToString());
            Assert.Equal(testString.Substring(1, 1), memory.Slice(1, 1).ToString());
            Assert.Equal(testString, memory.Span.ToString());
        }
Exemple #16
0
        public PrivilegedAttributeCertificate(KrbAuthorizationData authz)
            : base(authz.Type, AuthorizationDataType.AdWin2kPac)
        {
            var pac = authz.Data;

            pacData = MemoryMarshal.AsMemory(pac);

            var stream = new NdrBuffer(pac, align: false);

            var count = stream.ReadInt32LittleEndian();

            Version = stream.ReadInt32LittleEndian();

            if (Version != PAC_VERSION)
            {
                throw new InvalidDataException($"Unknown PAC Version {Version}");
            }

            var errors = new List <PacDecodeError>();

            for (var i = 0; i < count; i++)
            {
                var type = (PacType)stream.ReadInt32LittleEndian();
                var size = stream.ReadInt32LittleEndian();

                var offset = stream.ReadInt64LittleEndian();

                var pacInfoBuffer = pac.Slice((int)offset, size);

                int exclusionStart;
                int exclusionLength;

                try
                {
                    ParsePacType(type, pacInfoBuffer, out exclusionStart, out exclusionLength);
                }
                catch (Exception ex)
                {
                    errors.Add(new PacDecodeError()
                    {
                        Type      = type,
                        Data      = pacInfoBuffer,
                        Exception = ex
                    });

                    throw;
                }

                if (exclusionStart > 0 && exclusionLength > 0)
                {
                    pacData.Span.Slice((int)offset + exclusionStart, exclusionLength).Fill(0);
                }
            }

            DecodingErrors = errors;
        }
Exemple #17
0
        /// <summary>
        /// Creates an instance of <see cref="ReadOnlySequence{T}"/> from the <see cref="ReadOnlyMemory{T}"/>.
        /// Consumer is expected to manage lifetime of memory until <see cref="ReadOnlySequence{T}"/> is not used anymore.
        /// </summary>
        public ReadOnlySequence(ReadOnlyMemory <T> readOnlyMemory)
        {
            ReadOnlySequenceSegment segment = new ReadOnlySequenceSegment
            {
                Memory = MemoryMarshal.AsMemory(readOnlyMemory)
            };

            _sequenceStart = new SequencePosition(segment, 0 | MemoryListStartMask);
            _sequenceEnd   = new SequencePosition(segment, readOnlyMemory.Length | MemoryListEndMask);
        }
Exemple #18
0
        internal void Sign(Memory <byte> pacUnsigned, KerberosKey key)
        {
            Validator = CryptoService.CreateChecksumValidator(Type, Signature, pacUnsigned);

            Validator.Sign(key);

            Signature = MemoryMarshal.AsMemory(Validator.Signature);

            IsDirty = true;
        }
Exemple #19
0
        internal void Sign(Memory <byte> pacUnsigned, KerberosKey key)
        {
            this.Validator = CryptoService.CreateChecksum(this.Type, this.Signature, pacUnsigned);

            this.Validator.Sign(key);

            this.Signature = MemoryMarshal.AsMemory(this.Validator.Signature);

            this.IsDirty = true;
        }
        public PrivilegedAttributeCertificate(KrbAuthorizationData authz)
            : base(authz.Type, AuthorizationDataType.AdWin2kPac)
        {
            var pac = authz.Data;

            Stream = new NdrBinaryStream(pac);

            pacData = MemoryMarshal.AsMemory(authz.Data);

            var count   = Stream.ReadInt();
            var version = Stream.ReadInt();

            if (version != PAC_VERSION)
            {
                throw new InvalidDataException($"Unknown PAC Version {version}");
            }

            var errors = new List <PacDecodeError>();

            for (var i = 0; i < count; i++)
            {
                var type = (PacType)Stream.ReadInt();
                var size = Stream.ReadInt();

                var offset = Stream.ReadLong();

                var pacInfoBuffer = pac.Slice((int)offset, size);

                int exclusionStart  = 0;
                int exclusionLength = 0;

                try
                {
                    ParsePacType(type, pacInfoBuffer, out exclusionStart, out exclusionLength);
                }
                catch (Exception ex)
                {
                    errors.Add(new PacDecodeError()
                    {
                        Type      = type,
                        Data      = pacInfoBuffer,
                        Exception = ex
                    });
                }

                if (exclusionStart > 0 && exclusionLength > 0)
                {
                    pacData.Span.Slice((int)offset + exclusionStart, exclusionLength).Fill(0);
                }
            }

            DecodingErrors = errors;

            HasRequiredFields = ServerSignature != null && KdcSignature != null;
        }
Exemple #21
0
        public static void SpanFromStringAsMemory()
        {
            string a = "1234-";
            ReadOnlyMemory <char> memory;

            memory = a.AsMemory();
            MemoryMarshal.AsMemory(memory).Span.Validate('1', '2', '3', '4', '-');

            memory = a.AsMemory(0, a.Length);
            MemoryMarshal.AsMemory(memory).Span.Validate('1', '2', '3', '4', '-');
        }
        public static string Create(ReadOnlySpan <char> value)
        {
            if (_createShim != null)
            {
                return(_createShim(value));
            }
            var result = new string('\0', value.Length);
            var dest   = MemoryMarshal.AsMemory(result.AsMemory()).Span;

            value.CopyTo(dest);
            return(result);
        }
Exemple #23
0
        static void Main(string[] args)
        {
            // Working with strings
            // Old
            string text = "Imagine this is some extremely long string.....................";

            string substring = text.Substring(0, text.Length - 1); //Allocates a new string with length - 1, expensive! Surely we can do better?

            // New
            ReadOnlySpan <char> textSpan      = text.AsSpan();                      //Converts the string to a span (in dotnet core this can be done implicitly), no heap allocations will happen so this is very fast.
            ReadOnlySpan <char> fastSubstring = textSpan.Slice(0, textSpan.Length); //Does not allocate a new string, fast!

            // Also works for unmanaged memory
            unsafe
            {
                IntPtr      unmanagedHandle = Marshal.AllocHGlobal(256);
                Span <byte> unmanagedBytes  = new Span <byte>(unmanagedHandle.ToPointer(), 256);

                // Do something with this unmanaged memory

                Marshal.FreeHGlobal(unmanagedHandle);
            }

            // And even stack allocated memory (and yes it works without unsafe!)
            Span <byte> stackallocatedBytes = stackalloc byte[256];
            // Do something with this stack allocated memory

            // Because of its extreme versatility span is limited to the stack as such the following will not compile because it cannot be boxed
            //var castedSpan = textSpan as object; //Error CS0039  Cannot convert type 'System.ReadOnlySpan<char>' to 'object' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

            // Neither can you use it in a closure
            Action action = () =>
            {
                //textSpan.Slice(); // Error CS8175  Cannot use ref local 'textSpan' inside an anonymous method, lambda expression, or query expression
            };

            // For scenarios where a span is needed outside the stack Memory can be used.
            ReadOnlyMemory <char> memory     = text.AsMemory();
            ReadOnlySpan <char>   memoryspan = memory.Span; //Memory is a factory for spans;


            #region BadCode
            // We can also do weird stuff though.... Atleast its using safe code. As you will see below use this with care!
            Memory <char> foo = MemoryMarshal.AsMemory(text.AsMemory());
            foo.Span[0] = 'Z';                                                                //You thought strings were immutable? Think again.
            Console.WriteLine(text);                                                          //Prints out text but the first character is replaced with a Z. Yup we modified the original string.
            string text2 = "Imagine this is some extremely long string....................."; //But now we get to the weird part
            Console.WriteLine(text2);                                                         //This prints out text2 but here the first character is also replaced with a Z! Guess why.
            #endregion

            //BenchmarkRunner.Run<ReinterpretBinaryDataBenchmark>();
            Console.ReadKey();
        }
        public static string Replace(this string str, string oldValue, string newValue, StringComparison comparisonType)
        {
            var index = 0;

            while ((index = str.IndexOf(oldValue, index, comparisonType)) >= 0)
            {
                var newStr = new string('\0', str.Length - oldValue.Length + newValue.Length);

                var newStrBuffer = MemoryMarshal.AsMemory(newStr.AsMemory());
                var strBuffer    = str.AsMemory();

                strBuffer[..index].CopyTo(newStrBuffer);
Exemple #25
0
        private SocketAwaitableArgs SendSingleMessageAsync(ReadOnlyMemory <byte> buffer)
        {
            if (this.sndArgs.BufferList != null)
            {
                this.sndArgs.BufferList = null;
            }
#if NETSTANDARD2_0
            var segment = buffer.GetBinaryArray();
            this.sndArgs.SetBuffer(segment.Array, segment.Offset, segment.Count);
#elif NET5_0
            this.sndArgs.SetBuffer(MemoryMarshal.AsMemory(buffer));
#endif
            return(this.SocketSndAsync());
        }
        [DataRow(LoremIpsum, 93)] // tamper later block
        public void TestIntegrityCheck(string text, int tamperIndex)
        {
            byte[] hmacKey = new byte[32];
            byte[] aesKey  = new byte[32];
            RandomNumberGenerator.Fill(hmacKey);
            RandomNumberGenerator.Fill(aesKey);

            ReadOnlyMemory <byte> data       = Encoding.UTF8.GetBytes(text);
            Memory <byte>         ciphertext = MemoryMarshal.AsMemory(AesStatic.EncryptWithHmac(data, hmacKey, aesKey));

            ciphertext.Span[tamperIndex] = (byte)~ciphertext.Span[tamperIndex];

            Assert.ThrowsException <CryptographicException>(() => AesStatic.DecryptWithHmac(ciphertext, hmacKey, aesKey));
        }
Exemple #27
0
 private protected virtual void ImplReadBytes(ref State state, ReadOnlySequence <byte> target)
 {
     if (target.IsSingleSegment)
     {
         ImplReadBytes(ref state, MemoryMarshal.AsMemory(target.First).Span);
     }
     else
     {
         foreach (var segment in target)
         {
             ImplReadBytes(ref state, MemoryMarshal.AsMemory(segment).Span);
         }
     }
 }
Exemple #28
0
        public static unsafe void Memory_Pin_ExpectedPointerValue()
        {
            string input = "0123456789";
            ReadOnlyMemory <char> readonlyMemory = input.AsMemory();
            Memory <char>         m = MemoryMarshal.AsMemory(readonlyMemory);

            using (MemoryHandle h = m.Pin())
            {
                GC.Collect();
                fixed(char *ptr = input)
                {
                    Assert.Equal((IntPtr)ptr, (IntPtr)h.Pointer);
                }
            }
        }
Exemple #29
0
        public ReadOnlyBytes(ReadOnlyMemory <byte> bytes)
        {
            Memory <byte> memory = MemoryMarshal.AsMemory(bytes);

            if (!memory.TryGetArray(out var segment))
            {
                // TODO: once we are in System.Memory, this will get OwnedMemory out of the Memory
                throw new NotImplementedException();
            }
            _start      = segment.Array;
            _startIndex = segment.Offset;
            _end        = segment.Array;
            _endIndex   = segment.Count + _startIndex;

            Validate();
        }
        private static async Task WriteToStream(Stream stream, ReadOnlyMemory <byte> readOnlyMemory)
        {
            var memory = MemoryMarshal.AsMemory(readOnlyMemory);

            if (memory.TryGetArray(out ArraySegment <byte> data))
            {
                await stream.WriteAsync(data.Array, data.Offset, data.Count)
                .ConfigureAwait(continueOnCapturedContext: false);
            }
            else
            {
                // Copy required
                var array = memory.Span.ToArray();
                await stream.WriteAsync(array, 0, array.Length).ConfigureAwait(continueOnCapturedContext: false);
            }
        }