public void ReadOnlySpanReadFail() { ReadOnlySpan <byte> span = new byte[] { 1 }; Assert.Equal <byte>(1, MemoryMarshal.Read <byte>(span)); Assert.True(MemoryMarshal.TryRead(span, out byte byteValue)); Assert.Equal(1, byteValue); TestHelpers.AssertThrows <ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read <short>(_span)); Assert.False(MemoryMarshal.TryRead(span, out short shortValue)); TestHelpers.AssertThrows <ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read <int>(_span)); Assert.False(MemoryMarshal.TryRead(span, out int intValue)); TestHelpers.AssertThrows <ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read <long>(_span)); Assert.False(MemoryMarshal.TryRead(span, out long longValue)); TestHelpers.AssertThrows <ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read <ushort>(_span)); Assert.False(MemoryMarshal.TryRead(span, out ushort ushortValue)); TestHelpers.AssertThrows <ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read <uint>(_span)); Assert.False(MemoryMarshal.TryRead(span, out uint uintValue)); TestHelpers.AssertThrows <ArgumentOutOfRangeException, byte>(span, (_span) => MemoryMarshal.Read <ulong>(_span)); Assert.False(MemoryMarshal.TryRead(span, out ulong ulongValue)); ReadOnlySpan <byte> largeSpan = new byte[100]; TestHelpers.AssertThrows <ArgumentException, byte>(largeSpan, (_span) => MemoryMarshal.Read <TestHelpers.TestValueTypeWithReference>(_span)); TestHelpers.AssertThrows <ArgumentException, byte>(largeSpan, (_span) => MemoryMarshal.TryRead(_span, out TestHelpers.TestValueTypeWithReference stringValue)); }
public static Guid GenerateImproved(Guid guid, DateTime nowInput) { var newGuid = guid; Span <byte> guidArray = stackalloc byte[16]; #if NETCOREAPP if (!newGuid.TryWriteBytes(guidArray)) #elif NETFRAMEWORK if (!MemoryMarshal.TryWrite(guidArray, ref newGuid)) #endif { guidArray = newGuid.ToByteArray(); } var now = nowInput; // Internal use, no need for DateTimeOffset // Get the days and milliseconds which will be used to build the byte string var days = new TimeSpan(now.Ticks - BaseDateTicksConst); var timeOfDay = now.TimeOfDay; // Convert to a byte array Span <byte> scratchArray = stackalloc byte[sizeof(long)] { 0, 0, 0, 0, 0, 0, 0, 0 }; // Reverse the bytes to match SQL Servers ordering if (BitConverter.IsLittleEndian) { BinaryPrimitives.WriteInt32BigEndian(scratchArray, days.Days); } else { BinaryPrimitives.WriteInt32LittleEndian(scratchArray, days.Days); } // Copy the bytes into the guid scratchArray.Slice(2, 2).CopyTo(guidArray.Slice(10, 2)); // Reverse the bytes to match SQL Servers ordering // Note that SQL Server is accurate to 1/300th of a millisecond so we divide by 3.333333 if (BitConverter.IsLittleEndian) { BinaryPrimitives.WriteInt64BigEndian(scratchArray, (long)(timeOfDay.TotalMilliseconds / 3.333333)); } else { BinaryPrimitives.WriteInt64LittleEndian(scratchArray, (long)(timeOfDay.TotalMilliseconds / 3.333333)); } // Copy the bytes into the guid scratchArray.Slice(3, 4).CopyTo(guidArray.Slice(12, 4)); #if NETCOREAPP return(new Guid(guidArray)); #elif NETFRAMEWORK if (!MemoryMarshal.TryRead(guidArray, out Guid readGuid)) { readGuid = new Guid(guidArray.ToArray()); } return(readGuid); #endif }
/// <summary> /// Try to read the manifest from a given file path. /// </summary> /// <param name="manifestPath">The path to the manifest file</param> /// <param name="graphicsApi">The graphics api used by the cache</param> /// <param name="hashType">The hash type of the cache</param> /// <param name="header">The manifest header read</param> /// <param name="entries">The entries read from the cache manifest</param> /// <returns>Return true if the manifest was read</returns> public static bool TryReadManifestFile(string manifestPath, CacheGraphicsApi graphicsApi, CacheHashType hashType, out CacheManifestHeader header, out HashSet <Hash128> entries) { header = default; entries = new HashSet <Hash128>(); if (File.Exists(manifestPath)) { Memory <byte> rawManifest = File.ReadAllBytes(manifestPath); if (MemoryMarshal.TryRead(rawManifest.Span, out header)) { Memory <byte> hashTableRaw = rawManifest.Slice(Unsafe.SizeOf <CacheManifestHeader>()); bool isValid = header.IsValid(graphicsApi, hashType, hashTableRaw.Span); if (isValid) { ReadOnlySpan <Hash128> hashTable = MemoryMarshal.Cast <byte, Hash128>(hashTableRaw.Span); foreach (Hash128 hash in hashTable) { entries.Add(hash); } } return(isValid); } } return(false); }
public static bool TryReadUInt64LittleEndian(ReadOnlySpan <byte> source, out ulong value) { bool success = MemoryMarshal.TryRead(source, out value); if (!BitConverter.IsLittleEndian) { value = ReverseEndianness(value); } return(success); }
/// <summary> /// Load the cache manifest file and recreate it if invalid. /// </summary> private void Load() { bool isInvalid = false; if (!Directory.Exists(_cacheDirectory)) { isInvalid = true; } else { string manifestPath = GetManifestPath(); if (File.Exists(manifestPath)) { Memory <byte> rawManifest = File.ReadAllBytes(manifestPath); if (MemoryMarshal.TryRead(rawManifest.Span, out CacheManifestHeader manifestHeader)) { Memory <byte> hashTableRaw = rawManifest.Slice(Unsafe.SizeOf <CacheManifestHeader>()); isInvalid = !manifestHeader.IsValid(_version, _graphicsApi, _hashType, hashTableRaw.Span); if (!isInvalid) { ReadOnlySpan <Hash128> hashTable = MemoryMarshal.Cast <byte, Hash128>(hashTableRaw.Span); foreach (Hash128 hash in hashTable) { _hashTable.Add(hash); } } } } else { isInvalid = true; } } if (isInvalid) { Logger.Warning?.Print(LogClass.Gpu, $"Shader collection \"{_cacheDirectory}\" got invalidated, cache will need to be rebuilt."); if (Directory.Exists(_cacheDirectory)) { Directory.Delete(_cacheDirectory, true); } Directory.CreateDirectory(_cacheDirectory); SaveManifest(); } FlushToArchive(); }
public Guid SpanAndMemoryMarshal() { Span <byte> guidBytes = stackalloc byte[16]; data.AsSpan().CopyTo(guidBytes); if (!MemoryMarshal.TryRead <Guid>(guidBytes, out var lockTokenGuid)) { lockTokenGuid = new Guid(guidBytes.ToArray()); } return(lockTokenGuid); }
private static bool tryReadAndAdvance <T>(out T val, ref ReadOnlySpan <byte> span) where T : struct { bool res = MemoryMarshal.TryRead(span, out val); if (res) { span = span.Slice(Unsafe.SizeOf <T>()); } return(res); }
/// <summary> /// Reads a <see cref="float" /> from the beginning of a read-only span of bytes, as little endian. /// </summary> /// <param name="source">The read-only span of bytes to read.</param> /// <param name="value">When this method returns, the value read out of the read-only span of bytes, as little endian.</param> /// <returns> /// <see langword="true" /> if the span is large enough to contain a <see cref="float" />; otherwise, <see langword="false" />. /// </returns> /// <remarks>Reads exactly 4 bytes from the beginning of the span.</remarks> public static bool TryReadSingleLittleEndian(ReadOnlySpan <byte> source, out float value) { if (!BitConverter.IsLittleEndian) { bool success = MemoryMarshal.TryRead(source, out int tmp); value = BitConverter.Int32BitsToSingle(ReverseEndianness(tmp)); return(success); } return(MemoryMarshal.TryRead(source, out value)); }
public static bool TryReadDoubleLittleEndian(ReadOnlySpan <byte> source, out double value) { if (!BitConverter.IsLittleEndian) { bool success = MemoryMarshal.TryRead(source, out long tmp); value = BitConverter.Int64BitsToDouble(ReverseEndianness(tmp)); return(success); } return(MemoryMarshal.TryRead(source, out value)); }
public static bool TryReadUInt32BigEndian(ReadOnlySpan <byte> source, out uint value) { if (BitConverter.IsLittleEndian) { bool success = MemoryMarshal.TryRead(source, out uint tmp); value = ReverseEndianness(tmp); return(success); } return(MemoryMarshal.TryRead(source, out value)); }
public static bool TryReadHalfLittleEndian(ReadOnlySpan <byte> source, out Half value) { if (!BitConverter.IsLittleEndian) { bool success = MemoryMarshal.TryRead(source, out short tmp); value = BitConverter.Int16BitsToHalf(ReverseEndianness(tmp)); return(success); } return(MemoryMarshal.TryRead(source, out value)); }
public static T ReadValue <T>(ReadOnlySpan <byte> src, int offset = 0) where T : struct { if (MemoryMarshal.TryRead(src.Slice(offset), out T value)) { return(value); } else { throw new Exception(); } }
public static bool TryRead(ReadOnlySpan <char> text, out PollId pollId) { try { return(MemoryMarshal.TryRead(Base58.Flickr.Decode(text), out pollId)); } catch (Exception) { pollId = default; return(false); } }
public static bool TryReadInt64LittleEndian(ReadOnlySpan <byte> source, out long value) { if (BitConverter.IsLittleEndian) { return(MemoryMarshal.TryRead(source, out value)); } bool success = MemoryMarshal.TryRead(source, out long tmp); value = ReverseEndianness(tmp); return(success); }
public uint ReadUInt32() { if (MemoryMarshal.TryRead(this.data.Slice(this.Position, 4), out ushort value)) { this.Position += 4; return(value); } else { throw new InvalidOperationException(); } }
public static AddrInfoSerialized Read(ReadOnlySpan <byte> buffer, out ReadOnlySpan <byte> rest) { if (!MemoryMarshal.TryRead(buffer, out AddrInfoSerializedHeader header)) { rest = buffer; return(null); } AddrInfo4? socketAddress = null; Array4 <byte>?rawIPv4Address = null; string canonicalName = null; buffer = buffer[Unsafe.SizeOf <AddrInfoSerializedHeader>()..];
public unsafe void Ctor_SafeHandle_UnknownSocket_Success() { const int PF_INET = 2; const int NETLINK_ROUTE = 0; const int SOCK_DGRAM = 2; const int RTM_NEWROUTE = 24; const int RTM_GETROUTE = 26; const int NLM_F_REQUEST = 1; const int NLM_F_DUMP = 0x300; const int NLMSG_ERROR = 2; const int SEQ = 42; int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); Assert.InRange(fd, 0, int.MaxValue); using (Socket netlink = new Socket(new SafeSocketHandle((IntPtr)fd, ownsHandle: true))) { Assert.Equal(AddressFamily.Unknown, netlink.AddressFamily); netlink.Bind(new NlEndPoint(Environment.ProcessId)); nl_request req = default; req.nlh.nlmsg_pid = (uint)Environment.ProcessId; req.nlh.nlmsg_type = RTM_GETROUTE; /* We wish to get routes */ req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; req.nlh.nlmsg_len = sizeof(nl_request); req.nlh.nlmsg_seq = SEQ; req.rtm.rtm_family = PF_INET; netlink.Send(new ReadOnlySpan <byte>(Unsafe.AsPointer(ref req), sizeof(nl_request))); Assert.True(netlink.Poll(TestSettings.PassingTestTimeout, SelectMode.SelectRead)); byte[] response = new byte[4000]; int readBytes = netlink.Receive(response); // We should get at least header. Assert.True(readBytes > sizeof(nlmsghdr)); MemoryMarshal.TryRead <nlmsghdr>(response.AsSpan(), out nlmsghdr nlh); Assert.Equal(SEQ, nlh.nlmsg_seq); if (nlh.nlmsg_type == NLMSG_ERROR) { MemoryMarshal.TryRead <nlmsgerr>(response.AsSpan(sizeof(nlmsghdr)), out nlmsgerr err); _output.WriteLine("Netlink request failed with {0}", err.error); } Assert.Equal(RTM_NEWROUTE, nlh.nlmsg_type); } }
private static bool TryReadLowerCaseUInt32(ReadOnlySpan <byte> byteValue, out uint value) { if (MemoryMarshal.TryRead(byteValue, out uint result)) { if (!BitConverter.IsLittleEndian) { result = (result & 0xffff_0000) >> 16 | (result & 0x0000_ffff) << 16; } value = result | 0x0020_0020; return(true); } value = 0; return(false); }
/// <summary> /// Try to read the manifest header from a given file path. /// </summary> /// <param name="manifestPath">The path to the manifest file</param> /// <param name="header">The manifest header read</param> /// <returns>Return true if the manifest header was read</returns> public static bool TryReadManifestHeader(string manifestPath, out CacheManifestHeader header) { header = default; if (File.Exists(manifestPath)) { Memory <byte> rawManifest = File.ReadAllBytes(manifestPath); if (MemoryMarshal.TryRead(rawManifest.Span, out header)) { return(true); } } return(false); }
static Guid DeterministicGuid(string src) { var byteCount = Encoding.UTF8.GetByteCount(src); var buffer = ArrayPool <byte> .Shared.Rent(byteCount); try { var numberOfBytesWritten = Encoding.UTF8.GetBytes(src.AsSpan(), buffer); using var sha1CryptoServiceProvider = SHA1.Create(); var guidBytes = sha1CryptoServiceProvider.ComputeHash(buffer, 0, numberOfBytesWritten).AsSpan().Slice(0, 16); if (!MemoryMarshal.TryRead <Guid>(guidBytes, out var deterministicGuid)) { deterministicGuid = new Guid(guidBytes.ToArray()); } return(deterministicGuid); } finally { ArrayPool <byte> .Shared.Return(buffer, clearArray : true); } }
/// <summary> /// Tries to load a <see cref="V1"/> instance from the input binary blob and returns a result. /// </summary> /// <param name="blob">The input binary blob to deserialize.</param> /// <param name="data">The resulting <see cref="V1"/> instance, if successful.</param> /// <returns>The result of the loading operation.</returns> private static LoadingResult TryLoadAndGetResult(ReadOnlyMemory <byte> blob, out V1 data) { data = default; if (blob.IsEmpty) { return(LoadingResult.EmptyBuffer); } ReadOnlySpan <byte> span = blob.Span; // Blob id if (!MemoryMarshal.TryRead(span, out Guid blobId)) { return(LoadingResult.BufferTooShort); } // Validate the blob id if (blobId != BlobId) { return(LoadingResult.MismatchedBlobVersionId); } span = span.Slice(sizeof(Guid)); // Effect class id if (!MemoryMarshal.TryRead(span, out Guid effectId)) { return(LoadingResult.BufferTooShort); } span = span.Slice(sizeof(Guid)); // Number of inputs if (!MemoryMarshal.TryRead(span, out int numberOfInputs)) { return(LoadingResult.BufferTooShort); } // Validate the number of inputs if (numberOfInputs < 0) { return(LoadingResult.InvalidNumberOfInputs); } span = span.Slice(sizeof(int)); // Effect property XML int lengthOfXml = span.IndexOf((byte)'\0'); if (lengthOfXml == -1) { return(LoadingResult.InvalidPropertyXml); } string xml = Encoding.UTF8.GetString(span.Slice(0, lengthOfXml)); span = span.Slice(lengthOfXml + 1); // Number of bindings if (!MemoryMarshal.TryRead(span, out int numberOfBindings)) { return(LoadingResult.BufferTooShort); } // Validate the number of bindings if (numberOfBindings < 0) { return(LoadingResult.InvalidNumberOfBindings); } span = span.Slice(sizeof(int)); D2D1PropertyBinding[] propertyBindings = new D2D1PropertyBinding[numberOfBindings]; // Property bindings for (int i = 0; i < numberOfBindings; i++) { // Property name int lengthOfName = span.IndexOf((byte)'\0'); if (lengthOfName == -1) { return(LoadingResult.InvalidBindingPropertyName); } string name = Encoding.UTF8.GetString(span.Slice(0, lengthOfName)); span = span.Slice(lengthOfName + 1); // Property get function if (!MemoryMarshal.TryRead(span, out nint getFunction)) { return(LoadingResult.BufferTooShort); } span = span.Slice(sizeof(nint)); // Property set function if (!MemoryMarshal.TryRead(span, out nint setFunction)) { return(LoadingResult.BufferTooShort); } span = span.Slice(sizeof(nint)); propertyBindings[i] = new D2D1PropertyBinding(name, (void *)getFunction, (void *)setFunction); } // Effect factory if (!MemoryMarshal.TryRead(span, out nint effectFactory)) { return(LoadingResult.BufferTooShort); } span = span.Slice(sizeof(nint)); // If the buffer is bigger than expected, also consider it malformed if (span.Length > 0) { return(LoadingResult.BufferTooLong); } data = new V1( effectId, numberOfInputs, xml, propertyBindings, effectFactory); return(LoadingResult.Success); }
/// <summary> /// Gets reparse point information associated to <paramref name="linkPath"/>. /// </summary> /// <returns>The immediate link target, absolute or relative or null if the file is not a supported link.</returns> internal static unsafe string?GetImmediateLinkTarget(string linkPath, bool isDirectory, bool throwOnError, bool returnFullPath) { using SafeFileHandle handle = OpenSafeFileHandle(linkPath, Interop.Kernel32.FileOperations.FILE_FLAG_BACKUP_SEMANTICS | Interop.Kernel32.FileOperations.FILE_FLAG_OPEN_REPARSE_POINT); if (handle.IsInvalid) { if (!throwOnError) { return(null); } int error = Marshal.GetLastWin32Error(); // File not found doesn't make much sense coming from a directory. if (isDirectory && error == Interop.Errors.ERROR_FILE_NOT_FOUND) { error = Interop.Errors.ERROR_PATH_NOT_FOUND; } throw Win32Marshal.GetExceptionForWin32Error(error, linkPath); } byte[] buffer = ArrayPool <byte> .Shared.Rent(Interop.Kernel32.MAXIMUM_REPARSE_DATA_BUFFER_SIZE); try { bool success = Interop.Kernel32.DeviceIoControl( handle, dwIoControlCode: Interop.Kernel32.FSCTL_GET_REPARSE_POINT, lpInBuffer: IntPtr.Zero, nInBufferSize: 0, lpOutBuffer: buffer, nOutBufferSize: Interop.Kernel32.MAXIMUM_REPARSE_DATA_BUFFER_SIZE, out _, IntPtr.Zero); if (!success) { if (!throwOnError) { return(null); } int error = Marshal.GetLastWin32Error(); // The file or directory is not a reparse point. if (error == Interop.Errors.ERROR_NOT_A_REPARSE_POINT) { return(null); } throw Win32Marshal.GetExceptionForWin32Error(error, linkPath); } Span <byte> bufferSpan = new(buffer); success = MemoryMarshal.TryRead(bufferSpan, out Interop.Kernel32.SymbolicLinkReparseBuffer rbSymlink); Debug.Assert(success); // We always use SubstituteName(Offset|Length) instead of PrintName(Offset|Length), // the latter is just the display name of the reparse point and it can show something completely unrelated to the target. if (rbSymlink.ReparseTag == Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_SYMLINK) { int offset = sizeof(Interop.Kernel32.SymbolicLinkReparseBuffer) + rbSymlink.SubstituteNameOffset; int length = rbSymlink.SubstituteNameLength; Span <char> targetPath = MemoryMarshal.Cast <byte, char>(bufferSpan.Slice(offset, length)); bool isRelative = (rbSymlink.Flags & Interop.Kernel32.SYMLINK_FLAG_RELATIVE) != 0; if (!isRelative) { // Absolute target is in NT format and we need to clean it up before return it to the user. if (targetPath.StartsWith(PathInternal.UncNTPathPrefix.AsSpan())) { // We need to prepend the Win32 equivalent of UNC NT prefix. return(Path.Join(PathInternal.UncPathPrefix.AsSpan(), targetPath.Slice(PathInternal.UncNTPathPrefix.Length))); } return(GetTargetPathWithoutNTPrefix(targetPath)); } else if (returnFullPath) { return(Path.Join(Path.GetDirectoryName(linkPath.AsSpan()), targetPath)); } else { return(targetPath.ToString()); } } else if (rbSymlink.ReparseTag == Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_MOUNT_POINT) { success = MemoryMarshal.TryRead(bufferSpan, out Interop.Kernel32.MountPointReparseBuffer rbMountPoint); Debug.Assert(success); int offset = sizeof(Interop.Kernel32.MountPointReparseBuffer) + rbMountPoint.SubstituteNameOffset; int length = rbMountPoint.SubstituteNameLength; Span <char> targetPath = MemoryMarshal.Cast <byte, char>(bufferSpan.Slice(offset, length)); // Unlike symbolic links, mount point paths cannot be relative. Debug.Assert(!PathInternal.IsPartiallyQualified(targetPath)); // Mount points cannot point to a remote location. Debug.Assert(!targetPath.StartsWith(PathInternal.UncNTPathPrefix.AsSpan())); return(GetTargetPathWithoutNTPrefix(targetPath)); } return(null); } finally { ArrayPool <byte> .Shared.Return(buffer); }
internal static string GetSingleSymbolicLinkTarget(string path) { using (SafeFileHandle handle = Interop.Kernel32.CreateFile(path, 0, // No file access required, this avoids file in use FileShare.ReadWrite | FileShare.Delete, // Share all access FileMode.Open, Interop.Kernel32.FileOperations.FILE_FLAG_OPEN_REPARSE_POINT | // Open the reparse point, not its target Interop.Kernel32.FileOperations.FILE_FLAG_BACKUP_SEMANTICS)) // Permit opening of directories { // https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/fsctl-get-reparse-point Interop.Kernel32.REPARSE_DATA_BUFFER_SYMLINK header; int sizeHeader = Marshal.SizeOf <Interop.Kernel32.REPARSE_DATA_BUFFER_SYMLINK>(); uint bytesRead = 0; ReadOnlySpan <byte> validBuffer; int bufferSize = sizeHeader + Interop.Kernel32.MAX_PATH; while (true) { byte[] buffer = ArrayPool <byte> .Shared.Rent(bufferSize); try { int result = Interop.Kernel32.DeviceIoControl(handle, Interop.Kernel32.FSCTL_GET_REPARSE_POINT, inBuffer: null, cbInBuffer: 0, buffer, (uint)buffer.Length, out bytesRead, overlapped: IntPtr.Zero) ? 0 : Marshal.GetLastWin32Error(); if (result != Interop.Errors.ERROR_SUCCESS && result != Interop.Errors.ERROR_INSUFFICIENT_BUFFER && result != Interop.Errors.ERROR_MORE_DATA) { throw new Win32Exception(result); } validBuffer = buffer.AsSpan().Slice(0, (int)bytesRead); if (!MemoryMarshal.TryRead(validBuffer, out header)) { if (result == Interop.Errors.ERROR_SUCCESS) { // didn't read enough for header throw new InvalidDataException("FSCTL_GET_REPARSE_POINT did not return sufficient data"); } // can't read header, guess at buffer length buffer = new byte[buffer.Length + Interop.Kernel32.MAX_PATH]; continue; } // we only care about SubstituteName. // Per https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/b41f1cbf-10df-4a47-98d4-1c52a833d913 print name is only valid for displaying to the user bufferSize = sizeHeader + header.SubstituteNameOffset + header.SubstituteNameLength; // bufferSize = sizeHeader + Math.Max(header.SubstituteNameOffset + header.SubstituteNameLength, header.PrintNameOffset + header.PrintNameLength); if (bytesRead >= bufferSize) { // got entire payload with valid header. #if NETSTANDARD2_0 string target = Encoding.Unicode.GetString(validBuffer.Slice(sizeHeader + header.SubstituteNameOffset, header.SubstituteNameLength).ToArray()); #elif NETCOREAPP3_1 || NET5_0 string target = Encoding.Unicode.GetString(validBuffer.Slice(sizeHeader + header.SubstituteNameOffset, header.SubstituteNameLength)); #else #error Platform not supported #endif if ((header.Flags & Interop.Kernel32.SYMLINK_FLAG_RELATIVE) != 0) { if (PathInternal.IsExtended(path)) { var rootPath = Path.GetDirectoryName(path.Substring(4)); if (rootPath != null) { target = path.Substring(0, 4) + Path.GetFullPath(Path.Combine(rootPath, target)); } else { target = path.Substring(0, 4) + Path.GetFullPath(target); } } else { var rootPath = Path.GetDirectoryName(path); if (rootPath != null) { target = Path.GetFullPath(Path.Combine(rootPath, target)); } else { target = Path.GetFullPath(target); } } } return(target); } if (bufferSize < buffer.Length) { throw new InvalidDataException($"FSCTL_GET_REPARSE_POINT did not return sufficient data ({bufferSize}) when provided buffer ({buffer.Length})."); } } finally { ArrayPool <byte> .Shared.Return(buffer); } } } }
public static ServiceBusReceivedMessage AmqpMessageToSBMessage(AmqpMessage amqpMessage, bool isPeeked = false) { Argument.AssertNotNull(amqpMessage, nameof(amqpMessage)); AmqpAnnotatedMessage annotatedMessage; if ((amqpMessage.BodyType & SectionFlag.Data) != 0 && amqpMessage.DataBody != null) { annotatedMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromData(BodyMemory.FromAmqpData(amqpMessage.DataBody))); } else if ((amqpMessage.BodyType & SectionFlag.AmqpValue) != 0 && amqpMessage.ValueBody?.Value != null) { if (TryGetNetObjectFromAmqpObject(amqpMessage.ValueBody.Value, MappingType.MessageBody, out object netObject)) { annotatedMessage = new AmqpAnnotatedMessage(AmqpMessageBody.FromValue(netObject)); } else { throw new NotSupportedException(Resources.InvalidAmqpMessageValueBody.FormatForUser(amqpMessage.ValueBody.Value.GetType())); } } else if ((amqpMessage.BodyType & SectionFlag.AmqpSequence) != 0) { annotatedMessage = new AmqpAnnotatedMessage( AmqpMessageBody.FromSequence(amqpMessage.SequenceBody.Select(s => (IList <object>)s.List).ToList())); } // default to using an empty Data section if no data else { annotatedMessage = new AmqpAnnotatedMessage(new AmqpMessageBody(Enumerable.Empty <ReadOnlyMemory <byte> >())); } ServiceBusReceivedMessage sbMessage = new ServiceBusReceivedMessage(annotatedMessage); SectionFlag sections = amqpMessage.Sections; if ((sections & SectionFlag.Header) != 0) { if (amqpMessage.Header.Ttl != null) { annotatedMessage.Header.TimeToLive = TimeSpan.FromMilliseconds(amqpMessage.Header.Ttl.Value); } if (amqpMessage.Header.DeliveryCount != null) { annotatedMessage.Header.DeliveryCount = isPeeked ? (amqpMessage.Header.DeliveryCount.Value) : (amqpMessage.Header.DeliveryCount.Value + 1); } } if ((sections & SectionFlag.Properties) != 0) { if (amqpMessage.Properties.MessageId != null) { annotatedMessage.Properties.MessageId = new AmqpMessageId(amqpMessage.Properties.MessageId.ToString()); } if (amqpMessage.Properties.CorrelationId != null) { annotatedMessage.Properties.CorrelationId = new AmqpMessageId(amqpMessage.Properties.CorrelationId.ToString()); } if (amqpMessage.Properties.ContentType.Value != null) { annotatedMessage.Properties.ContentType = amqpMessage.Properties.ContentType.Value; } if (amqpMessage.Properties.Subject != null) { annotatedMessage.Properties.Subject = amqpMessage.Properties.Subject; } if (amqpMessage.Properties.To != null) { annotatedMessage.Properties.To = new AmqpAddress(amqpMessage.Properties.To.ToString()); } if (amqpMessage.Properties.ReplyTo != null) { annotatedMessage.Properties.ReplyTo = new AmqpAddress(amqpMessage.Properties.ReplyTo.ToString()); } if (amqpMessage.Properties.GroupId != null) { annotatedMessage.Properties.GroupId = amqpMessage.Properties.GroupId; } if (amqpMessage.Properties.ReplyToGroupId != null) { annotatedMessage.Properties.ReplyToGroupId = amqpMessage.Properties.ReplyToGroupId; } } // Do application properties before message annotations, because the application properties // can be updated by entries from message annotation. if ((sections & SectionFlag.ApplicationProperties) != 0) { foreach (var pair in amqpMessage.ApplicationProperties.Map) { if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject)) { annotatedMessage.ApplicationProperties[pair.Key.ToString()] = netObject; } } } if ((sections & SectionFlag.MessageAnnotations) != 0) { foreach (var pair in amqpMessage.MessageAnnotations.Map) { var key = pair.Key.ToString(); switch (key) { case AmqpMessageConstants.EnqueuedTimeUtcName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueuedTimeUtcName] = pair.Value; break; case AmqpMessageConstants.ScheduledEnqueueTimeUtcName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.ScheduledEnqueueTimeUtcName] = pair.Value; break; case AmqpMessageConstants.SequenceNumberName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.SequenceNumberName] = pair.Value; break; case AmqpMessageConstants.EnqueueSequenceNumberName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.EnqueueSequenceNumberName] = pair.Value; break; case AmqpMessageConstants.LockedUntilName: DateTimeOffset lockedUntil = (DateTime)pair.Value >= DateTimeOffset.MaxValue.UtcDateTime ? DateTimeOffset.MaxValue : (DateTime)pair.Value; annotatedMessage.MessageAnnotations[AmqpMessageConstants.LockedUntilName] = lockedUntil.UtcDateTime; break; case AmqpMessageConstants.PartitionKeyName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionKeyName] = pair.Value; break; case AmqpMessageConstants.PartitionIdName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.PartitionIdName] = pair.Value; break; case AmqpMessageConstants.ViaPartitionKeyName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.ViaPartitionKeyName] = pair.Value; break; case AmqpMessageConstants.DeadLetterSourceName: annotatedMessage.MessageAnnotations[AmqpMessageConstants.DeadLetterSourceName] = pair.Value; break; default: if (TryGetNetObjectFromAmqpObject(pair.Value, MappingType.ApplicationProperty, out var netObject)) { annotatedMessage.MessageAnnotations[key] = netObject; } break; } } } if (amqpMessage.DeliveryTag.Count == GuidSizeInBytes) { Span <byte> guidBytes = stackalloc byte[GuidSizeInBytes]; amqpMessage.DeliveryTag.AsSpan().CopyTo(guidBytes); if (!MemoryMarshal.TryRead <Guid>(guidBytes, out var lockTokenGuid)) { lockTokenGuid = new Guid(guidBytes.ToArray()); } sbMessage.LockTokenGuid = lockTokenGuid; } amqpMessage.Dispose(); return(sbMessage); }
public void SpanRead() { ulong value; // [11 22 33 44 55 66 77 88] if (BitConverter.IsLittleEndian) { value = 0x8877665544332211; } else { value = 0x1122334455667788; } Span <byte> span; unsafe { span = new Span <byte>(&value, 8); } Assert.Equal <byte>(0x11, MemoryMarshal.Read <byte>(span)); Assert.True(MemoryMarshal.TryRead(span, out byte byteValue)); Assert.Equal(0x11, byteValue); Assert.Equal <sbyte>(0x11, MemoryMarshal.Read <sbyte>(span)); Assert.True(MemoryMarshal.TryRead(span, out byte sbyteValue)); Assert.Equal(0x11, byteValue); Assert.Equal <ushort>(0x1122, ReadUInt16BigEndian(span)); Assert.True(TryReadUInt16BigEndian(span, out ushort ushortValue)); Assert.Equal(0x1122, ushortValue); Assert.Equal <ushort>(0x2211, ReadUInt16LittleEndian(span)); Assert.True(TryReadUInt16LittleEndian(span, out ushortValue)); Assert.Equal(0x2211, ushortValue); Assert.Equal <short>(0x1122, ReadInt16BigEndian(span)); Assert.True(TryReadInt16BigEndian(span, out short shortValue)); Assert.Equal(0x1122, shortValue); Assert.Equal <short>(0x2211, ReadInt16LittleEndian(span)); Assert.True(TryReadInt16LittleEndian(span, out shortValue)); Assert.Equal(0x2211, ushortValue); Assert.Equal <uint>(0x11223344, ReadUInt32BigEndian(span)); Assert.True(TryReadUInt32BigEndian(span, out uint uintValue)); Assert.Equal <uint>(0x11223344, uintValue); Assert.Equal <uint>(0x44332211, ReadUInt32LittleEndian(span)); Assert.True(TryReadUInt32LittleEndian(span, out uintValue)); Assert.Equal <uint>(0x44332211, uintValue); Assert.Equal <int>(0x11223344, ReadInt32BigEndian(span)); Assert.True(TryReadInt32BigEndian(span, out int intValue)); Assert.Equal <int>(0x11223344, intValue); Assert.Equal <int>(0x44332211, ReadInt32LittleEndian(span)); Assert.True(TryReadInt32LittleEndian(span, out intValue)); Assert.Equal <int>(0x44332211, intValue); Assert.Equal <ulong>(0x1122334455667788, ReadUInt64BigEndian(span)); Assert.True(TryReadUInt64BigEndian(span, out ulong ulongValue)); Assert.Equal <ulong>(0x1122334455667788, ulongValue); Assert.Equal <ulong>(0x8877665544332211, ReadUInt64LittleEndian(span)); Assert.True(TryReadUInt64LittleEndian(span, out ulongValue)); Assert.Equal <ulong>(0x8877665544332211, ulongValue); Assert.Equal <long>(0x1122334455667788, ReadInt64BigEndian(span)); Assert.True(TryReadInt64BigEndian(span, out long longValue)); Assert.Equal <long>(0x1122334455667788, longValue); Assert.Equal <long>(unchecked ((long)0x8877665544332211), ReadInt64LittleEndian(span)); Assert.True(TryReadInt64LittleEndian(span, out longValue)); Assert.Equal <long>(unchecked ((long)0x8877665544332211), longValue); Half expectedHalf = BitConverter.Int16BitsToHalf(0x1122); Assert.Equal <Half>(expectedHalf, ReadHalfBigEndian(span)); Assert.True(TryReadHalfBigEndian(span, out Half halfValue)); Assert.Equal <Half>(expectedHalf, halfValue); expectedHalf = BitConverter.Int16BitsToHalf(0x2211); Assert.Equal <Half>(expectedHalf, ReadHalfLittleEndian(span)); Assert.True(TryReadHalfLittleEndian(span, out halfValue)); Assert.Equal <Half>(expectedHalf, halfValue); float expectedFloat = BitConverter.Int32BitsToSingle(0x11223344); Assert.Equal <float>(expectedFloat, ReadSingleBigEndian(span)); Assert.True(TryReadSingleBigEndian(span, out float floatValue)); Assert.Equal <float>(expectedFloat, floatValue); expectedFloat = BitConverter.Int32BitsToSingle(0x44332211); Assert.Equal <float>(expectedFloat, ReadSingleLittleEndian(span)); Assert.True(TryReadSingleLittleEndian(span, out floatValue)); Assert.Equal <float>(expectedFloat, floatValue); double expectedDouble = BitConverter.Int64BitsToDouble(0x1122334455667788); Assert.Equal <double>(expectedDouble, ReadDoubleBigEndian(span)); Assert.True(TryReadDoubleBigEndian(span, out double doubleValue)); Assert.Equal <double>(expectedDouble, doubleValue); expectedDouble = BitConverter.Int64BitsToDouble(unchecked ((long)0x8877665544332211)); Assert.Equal <double>(expectedDouble, ReadDoubleLittleEndian(span)); Assert.True(TryReadDoubleLittleEndian(span, out doubleValue)); Assert.Equal <double>(expectedDouble, doubleValue); }
public void ReadOnlySpanRead() { Assert.True(BitConverter.IsLittleEndian); ulong value = 0x8877665544332211; // [11 22 33 44 55 66 77 88] ReadOnlySpan <byte> span; unsafe { span = new ReadOnlySpan <byte>(&value, 8); } Assert.Equal <byte>(0x11, MemoryMarshal.Read <byte>(span)); Assert.True(MemoryMarshal.TryRead(span, out byte byteValue)); Assert.Equal(0x11, byteValue); Assert.Equal <sbyte>(0x11, MemoryMarshal.Read <sbyte>(span)); Assert.True(MemoryMarshal.TryRead(span, out byte sbyteValue)); Assert.Equal(0x11, byteValue); Assert.Equal <ushort>(0x1122, ReadUInt16BigEndian(span)); Assert.True(TryReadUInt16BigEndian(span, out ushort ushortValue)); Assert.Equal(0x1122, ushortValue); Assert.Equal <ushort>(0x2211, ReadUInt16LittleEndian(span)); Assert.True(TryReadUInt16LittleEndian(span, out ushortValue)); Assert.Equal(0x2211, ushortValue); Assert.Equal <short>(0x1122, ReadInt16BigEndian(span)); Assert.True(TryReadInt16BigEndian(span, out short shortValue)); Assert.Equal(0x1122, shortValue); Assert.Equal <short>(0x2211, ReadInt16LittleEndian(span)); Assert.True(TryReadInt16LittleEndian(span, out shortValue)); Assert.Equal(0x2211, ushortValue); Assert.Equal <uint>(0x11223344, ReadUInt32BigEndian(span)); Assert.True(TryReadUInt32BigEndian(span, out uint uintValue)); Assert.Equal <uint>(0x11223344, uintValue); Assert.Equal <uint>(0x44332211, ReadUInt32LittleEndian(span)); Assert.True(TryReadUInt32LittleEndian(span, out uintValue)); Assert.Equal <uint>(0x44332211, uintValue); Assert.Equal <int>(0x11223344, ReadInt32BigEndian(span)); Assert.True(TryReadInt32BigEndian(span, out int intValue)); Assert.Equal <int>(0x11223344, intValue); Assert.Equal <int>(0x44332211, ReadInt32LittleEndian(span)); Assert.True(TryReadInt32LittleEndian(span, out intValue)); Assert.Equal <int>(0x44332211, intValue); Assert.Equal <ulong>(0x1122334455667788, ReadUInt64BigEndian(span)); Assert.True(TryReadUInt64BigEndian(span, out ulong ulongValue)); Assert.Equal <ulong>(0x1122334455667788, ulongValue); Assert.Equal <ulong>(0x8877665544332211, ReadUInt64LittleEndian(span)); Assert.True(TryReadUInt64LittleEndian(span, out ulongValue)); Assert.Equal <ulong>(0x8877665544332211, ulongValue); Assert.Equal <long>(0x1122334455667788, ReadInt64BigEndian(span)); Assert.True(TryReadInt64BigEndian(span, out long longValue)); Assert.Equal <long>(0x1122334455667788, longValue); Assert.Equal <long>(unchecked ((long)0x8877665544332211), ReadInt64LittleEndian(span)); Assert.True(TryReadInt64LittleEndian(span, out longValue)); Assert.Equal <long>(unchecked ((long)0x8877665544332211), longValue); }
public static bool TryReadInt64(this ReadOnlySpan <byte> source, out Int64 value) => MemoryMarshal.TryRead(source, out value);
public static bool TryReadGuid(this ReadOnlySpan <byte> source, out Guid value) => MemoryMarshal.TryRead(source, out value);
/// <summary> /// Gets reparse point information associated to <paramref name="linkPath"/>. /// </summary> /// <returns>The immediate link target, absolute or relative or null if the file is not a supported link.</returns> internal static unsafe string?GetImmediateLinkTarget(string linkPath, bool isDirectory, bool throwOnError, bool returnFullPath) { using SafeFileHandle handle = OpenSafeFileHandle(linkPath, Interop.Kernel32.FileOperations.FILE_FLAG_BACKUP_SEMANTICS | Interop.Kernel32.FileOperations.FILE_FLAG_OPEN_REPARSE_POINT); if (handle.IsInvalid) { if (!throwOnError) { return(null); } int error = Marshal.GetLastWin32Error(); // File not found doesn't make much sense coming from a directory. if (isDirectory && error == Interop.Errors.ERROR_FILE_NOT_FOUND) { error = Interop.Errors.ERROR_PATH_NOT_FOUND; } throw Win32Marshal.GetExceptionForWin32Error(error, linkPath); } byte[] buffer = ArrayPool <byte> .Shared.Rent(Interop.Kernel32.MAXIMUM_REPARSE_DATA_BUFFER_SIZE); try { bool success = Interop.Kernel32.DeviceIoControl( handle, dwIoControlCode: Interop.Kernel32.FSCTL_GET_REPARSE_POINT, lpInBuffer: IntPtr.Zero, nInBufferSize: 0, lpOutBuffer: buffer, nOutBufferSize: Interop.Kernel32.MAXIMUM_REPARSE_DATA_BUFFER_SIZE, out _, IntPtr.Zero); if (!success) { if (!throwOnError) { return(null); } int error = Marshal.GetLastWin32Error(); // The file or directory is not a reparse point. if (error == Interop.Errors.ERROR_NOT_A_REPARSE_POINT) { return(null); } throw Win32Marshal.GetExceptionForWin32Error(error, linkPath); } Span <byte> bufferSpan = new(buffer); success = MemoryMarshal.TryRead(bufferSpan, out Interop.Kernel32.REPARSE_DATA_BUFFER rdb); Debug.Assert(success); // Only symbolic links are supported at the moment. if ((rdb.ReparseTag & Interop.Kernel32.IOReparseOptions.IO_REPARSE_TAG_SYMLINK) == 0) { return(null); } // We use PrintName instead of SubstitutneName given that we don't want to return a NT path when the link wasn't created with such NT path. // Unlike SubstituteName and GetFinalPathNameByHandle(), PrintName doesn't start with a prefix. // Another nuance is that SubstituteName does not contain redundant path segments while PrintName does. // PrintName can ONLY return a NT path if the link was created explicitly targeting a file/folder in such way. e.g: mklink /D linkName \??\C:\path\to\target. int printNameNameOffset = sizeof(Interop.Kernel32.REPARSE_DATA_BUFFER) + rdb.ReparseBufferSymbolicLink.PrintNameOffset; int printNameNameLength = rdb.ReparseBufferSymbolicLink.PrintNameLength; Span <char> targetPath = MemoryMarshal.Cast <byte, char>(bufferSpan.Slice(printNameNameOffset, printNameNameLength)); Debug.Assert((rdb.ReparseBufferSymbolicLink.Flags & Interop.Kernel32.SYMLINK_FLAG_RELATIVE) == 0 || !PathInternal.IsExtended(targetPath)); if (returnFullPath && (rdb.ReparseBufferSymbolicLink.Flags & Interop.Kernel32.SYMLINK_FLAG_RELATIVE) != 0) { // Target path is relative and is for ResolveLinkTarget(), we need to append the link directory. return(Path.Join(Path.GetDirectoryName(linkPath.AsSpan()), targetPath)); } return(targetPath.ToString()); } finally { ArrayPool <byte> .Shared.Return(buffer); } }
public static bool TryRead <T>(this ReadOnlySpan <byte> source, out T value) where T : struct => MemoryMarshal.TryRead <T>(source, out value);