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))); } }
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); } }
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); } }
/// <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++; }
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)); }
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); } }
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())); }
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); }
public override int Send(ReadOnlyMemory <byte> buffer, IPEndPoint remoteEndPoint) { m_SendSAEA.SetBuffer(MemoryMarshal.AsMemory(buffer)); m_SendSAEA.RemoteEndPoint = remoteEndPoint; return(SendSAEA_DoSend()); }
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); }
public NdrBuffer(ReadOnlyMemory <byte> memory, bool align = true) : this(align) { backingBuffer = MemoryMarshal.AsMemory(memory); MoveByOffset(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())); }
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())); }
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()); }
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; }
/// <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); }
internal void Sign(Memory <byte> pacUnsigned, KerberosKey key) { Validator = CryptoService.CreateChecksumValidator(Type, Signature, pacUnsigned); Validator.Sign(key); Signature = MemoryMarshal.AsMemory(Validator.Signature); IsDirty = true; }
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; }
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); }
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);
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)); }
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); } } }
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); } } }
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); } }