Пример #1
0
        public static bool Is <TOut>(this object?input, [NotNullWhen(true)] out TOut?output)
        {
            // if (input is TOut temp)
            // {
            //     output = temp;
            //     return true;
            // }
            // else
            // {
            //     output = default;
            //     return false;
            // }

            Emit.Ldarg(nameof(input));
            Emit.Isinst <TOut>();
            Emit.Brfalse("isnot");

            Emit.Ldarg(nameof(output));
            Emit.Ldarg(nameof(input));
            Emit.Unbox_Any <TOut>();
            Emit.Stobj <TOut>();
            Emit.Ldc_I4_1();
            Emit.Ret();

            MarkLabel("isnot");
            Emit.Ldarg(nameof(output));
            Emit.Initobj <TOut>();
            Emit.Ldc_I4_0();
            Emit.Ret();

            throw Unreachable();
        }
Пример #2
0
        /// <summary>
        /// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation.
        /// </summary>
        /// <typeparam name="TIn">The type of the <paramref name="inVal"/>.</typeparam>
        /// <typeparam name="TOut">The type of the return value.</typeparam>
        /// <param name="hDevice">
        /// A handle to the device on which the operation is to be performed. The device is typically a volume, directory, file, or stream.
        /// To retrieve a device handle, use the CreateFile function. For more information, see Remarks.
        /// </param>
        /// <param name="ioControlCode">
        /// The control code for the operation. This value identifies the specific operation to be performed and the type of device on which
        /// to perform it.
        /// </param>
        /// <param name="inVal">
        /// The input value required to perform the operation. The type of this data depends on the value of the <paramref
        /// name="ioControlCode"/> parameter.
        /// </param>
        /// <returns>An asynchronous result containing the populated data supplied by <typeparamref name="TOut"/>.</returns>
        /// <remarks>
        /// <para>
        /// To retrieve a handle to the device, you must call the CreateFile function with either the name of a device or the name of the
        /// driver associated with a device. To specify a device name, use the following format:
        /// </para>
        /// <para>\\.\DeviceName</para>
        /// <para>
        /// DeviceIoControl can accept a handle to a specific device. For example, to open a handle to the logical drive
        /// A: with CreateFile, specify \\.\a:. Alternatively, you can use the names \\.\PhysicalDrive0, \\.\PhysicalDrive1, and so on, to
        /// open handles to the physical drives on a system.
        /// </para>
        /// <para>
        /// You should specify the FILE_SHARE_READ and FILE_SHARE_WRITE access flags when calling CreateFile to open a handle to a device
        /// driver. However, when you open a communications resource, such as a serial port, you must specify exclusive access. Use the other
        /// CreateFile parameters as follows when opening a device handle:
        /// </para>
        /// <list type="bullet">
        /// <item>
        /// <description>The fdwCreate parameter must specify OPEN_EXISTING.</description>
        /// </item>
        /// <item>
        /// <description>The hTemplateFile parameter must be NULL.</description>
        /// </item>
        /// <item>
        /// <description>
        /// The fdwAttrsAndFlags parameter can specify FILE_FLAG_OVERLAPPED to indicate that the returned handle can be used in overlapped
        /// (asynchronous) I/O operations.
        /// </description>
        /// </item>
        /// </list>
        /// </remarks>
        public static Task <TOut?> DeviceIoControlAsync <TIn, TOut>(HFILE hDevice, uint ioControlCode, TIn?inVal) where TIn : struct where TOut : struct
        {
            TOut?outValue = default(TOut);
            var  buf      = Pack(inVal, outValue);

            return(Task.Factory.FromAsync(BeginDeviceIoControl <TIn, TOut>, EndDeviceIoControl <TIn, TOut>, hDevice, ioControlCode, buf, null));
        }
Пример #3
0
        /// <inheritdoc cref="IDisposable.Dispose"/>
        public void Dispose()
        {
            if (!IsAlive)
            {
                return;
            }

            _handle.Updated -= OnUpdate;
            _handle.Deleted -= OnDelete;

            _cached = default;
            IsAlive = false;
        }
Пример #4
0
 private static byte[] Pack <TIn, TOut>(TIn?inVal, TOut?outVal) where TIn : struct where TOut : struct
 {
     using (var ms = new MemoryStream())
         using (var wtr = new BinaryWriter(ms))
         {
             wtr.Write(inVal.HasValue ? Marshal.SizeOf(typeof(TIn)) : 0);
             wtr.Write(outVal.HasValue ? Marshal.SizeOf(typeof(TOut)) : 0);
             if (inVal.HasValue)
             {
                 wtr.Write(inVal.Value);
             }
             if (outVal.HasValue)
             {
                 wtr.Write(outVal.Value);
             }
             return(ms.ToArray());
         }
 }
Пример #5
0
        private bool TryRewriteStrict <TSyntax, TOut>(TSyntax?syntax, [NotNullIfNotNull("syntax")] out TOut?newSyntax)
            where TSyntax : SyntaxBase
            where TOut : SyntaxBase
        {
            if (syntax is null)
            {
                newSyntax = null;
                return(false);
            }

            var newSyntaxUntyped = RewriteInternal(syntax);
            var hasChanges       = !object.ReferenceEquals(syntax, newSyntaxUntyped);

            if (newSyntaxUntyped is not TOut newSyntaxTyped)
            {
                throw new InvalidOperationException($"Expected {nameof(currentSyntax)} to be of type {typeof(TSyntax)}");
            }

            newSyntax = newSyntaxTyped;
            return(hasChanges);
        }
Пример #6
0
 public static TOut?Get <TOut, TKey, TValue>(this IDictionary <TKey, TValue> dictionary, TKey key, TOut?defaultValue = default)
 {
     if (dictionary is null || key is null)
     {
         return(default);
Пример #7
0
 /// <summary>TODO</summary>
 public static int?CompareTo <TOut>(this TOut? @this, TOut?other) where TOut : struct, IComparable
 => (from lhs in @this from rhs in other select lhs.CompareTo(rhs)).ElseDefault();
Пример #8
0
 /// <summary>TODO</summary>
 public static TOut?Max <TOut>(this TOut? @this, TOut?other) where TOut : struct, IComparable
 => from lhs in @this from rhs in other select lhs.CompareTo(rhs) < 0 ? lhs : rhs;
Пример #9
0
 /// <summary>Executes <paramref name="action"/> on <paramref name="this"/> exactly if it has a value.</summary>
 /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam>
 /// <returns>Returns <paramref name="this"/>.</returns>
 public static TOut?IfHasValueDo <TOut>(this TOut? @this, Action <TOut> action)
     where TOut : struct
 => @this.HasValue ? @this.Match(value => { action(value); return(@this.Value); }, () => @this.Value)
                   : null as TOut?;
Пример #10
0
 /// <summary>TODO</summary>
 public static TOut?Where <TOut>(this TOut? @this, Func <TOut, bool> predicate) where TOut : struct
 => @this.Bind(e => predicate(e) ? e : default(TOut?));
Пример #11
0
 /// <summary>Executes <paramref name="action"/> on <paramref name="this"/> exactly if it hasn't any value.</summary>
 /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam>
 /// <returns>Returns <paramref name="this"/>.</returns>
 public static TOut?ElseDo <TOut>(this TOut? @this, Action action) where TOut : struct
 => @this.Match(value => @this, () => { action(); return(@this); });
Пример #12
0
 /// <summary>Returns the value of <paramref name="this"/> if it has one, otherwise throws an <see cref="InvalidOperationException"/>.</summary>
 /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam>
 /// <returns>Returns the value of <paramref name="this"/>.</returns>
 /// <exception cref="InvalidOperationException"></exception>
 public static TOut  ForceGetValue <TOut>(this TOut? @this) where TOut : struct
 => @this.Match(e => e, () => { throw new InvalidOperationException(@this.ToString()); });
Пример #13
0
 /// <summary>Returns the value of <paramref name="this">this</paramref> it it has one; otherwise returns <paramref name="alternate"/>().</summary>
 /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam>
 /// <param name="this">The <typeparamref name="TOut"/>? being operated upon.</param>
 /// <param name="alternate">The action to be perrofmed if <paramref name="this"/> has no value.</param>
 public static TOut?Else <TOut>(this TOut? @this, Func <TOut> alternate) where TOut : struct
 => @this.Match(e => e, alternate);
Пример #14
0
 /// <summary>Returns the value of <paramref name="this">this</paramref> it it has one; otherwise returns default(<typeparamref name="TOut"/>).</summary>
 /// <typeparam name="TOut">The struct basis for the rtuern type TOut?.</typeparam>
 /// <param name="this">The <see cref="Maybe{T}"/> being operated upon.</param>
 public static TOut  ElseDefault <TOut>(this TOut? @this) where TOut : struct
 => @this.Match(e => e, () => default(TOut));
Пример #15
0
        /// <summary>
        /// Sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation.
        /// </summary>
        /// <typeparam name="TIn">The type of the <paramref name="inVal"/>.</typeparam>
        /// <typeparam name="TOut">The type of the <paramref name="outVal"/>.</typeparam>
        /// <param name="hDevice">A handle to the device on which the operation is to be performed. The device is typically a volume, directory, file, or stream. To retrieve a device
        /// handle, use the CreateFile function. For more information, see Remarks.</param>
        /// <param name="ioControlCode">The control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it.</param>
        /// <param name="inVal">The input value required to perform the operation. The type of this data depends on the value of the <paramref name="ioControlCode"/> parameter.</param>
        /// <param name="outVal">The output value that is to receive the data returned by the operation. The type of this data depends on the value of the dwIoControlCode parameter.</param>
        /// <returns>An asynchronous result containing the populated data supplied by <paramref name="outVal"/>.</returns>
        /// <remarks>
        /// <para>
        /// To retrieve a handle to the device, you must call the CreateFile function with either the name of a device or the name of the driver associated with
        /// a device. To specify a device name, use the following format:
        /// </para>
        /// <para>\\.\DeviceName</para>
        /// <para>
        /// DeviceIoControl can accept a handle to a specific device. For example, to open a handle to the logical drive
        /// A: with CreateFile, specify \\.\a:. Alternatively, you can use the names \\.\PhysicalDrive0, \\.\PhysicalDrive1, and so on, to open handles to the
        /// physical drives on a system.
        /// </para>
        /// <para>
        /// You should specify the FILE_SHARE_READ and FILE_SHARE_WRITE access flags when calling CreateFile to open a handle to a device driver. However, when
        /// you open a communications resource, such as a serial port, you must specify exclusive access. Use the other CreateFile parameters as follows when
        /// opening a device handle:
        /// </para>
        /// <list type="bullet">
        ///   <item>
        ///     <description>The fdwCreate parameter must specify OPEN_EXISTING.</description>
        ///   </item>
        ///   <item>
        ///     <description>The hTemplateFile parameter must be NULL.</description>
        ///   </item>
        ///   <item>
        ///     <description>The fdwAttrsAndFlags parameter can specify FILE_FLAG_OVERLAPPED to indicate that the returned handle can be used in overlapped (asynchronous) I/O operations.</description>
        ///   </item>
        /// </list>
        /// </remarks>
        public static Task <TOut?> DeviceIoControlAsync <TIn, TOut>(HFILE hDevice, uint ioControlCode, TIn?inVal, TOut?outVal) where TIn : struct where TOut : struct
        {
            var buf = Pack(inVal, outVal);

            return(new TaskFactory().FromAsync(BeginDeviceIoControl <TIn, TOut>, EndDeviceIoControl <TIn, TOut>, hDevice, ioControlCode, buf, null));
        }
Пример #16
0
        public static TOut?TryTransform <TIn, TOut>(this TIn?instance, [NotNull] Func <TIn, TOut> transform, TOut?elseValue = null)
            where TIn : struct
            where TOut : struct
        {
            if (transform == null)
            {
                throw new ArgumentNullException(nameof(transform));
            }

            if (instance == null)
            {
                return(elseValue);
            }

            return(transform(instance.Value));
        }
Пример #17
0
 public ResourceState(bool loading, TOut?data, Exception?exception)
 {
     Loading   = loading;
     Data      = data;
     Exception = exception;
 }
Пример #18
0
 public static ResourceState FromData(TOut?data) =>
 new ResourceState(false, data, null);
Пример #19
0
 public static TOut?Get <TOut, TKey, TValue>(this IDictionary <TKey, TValue> dictionary, TKey key, TOut?defaultValue = default)
 {
     if (dictionary is null || key is null)
     {
         return(defaultValue);
     }
     if (!dictionary.ContainsKey(key))
     {
         if (defaultValue is TValue value)
         {
             dictionary.Add(key, value);
         }
         return(defaultValue);
     }
     if (dictionary[key] is TOut o)
     {
         return(o);
     }
     return(defaultValue);
 }
Пример #20
0
 public static Optional <TOut> FromNullable <TOut>(TOut?value) where TOut : struct
 {
     return(value.HasValue
         ? new Optional <TOut>(value.Value)
         : new Optional <TOut>());
 }
Пример #21
0
        public static IAsyncResult BeginDeviceIoControl <TIn, TOut>(SafeFileHandle hDevice, uint dwIoControlCode, TIn?inVal, TOut?outVal, AsyncCallback userCallback) where TIn : struct where TOut : struct
        {
            var buffer = Pack(inVal, outVal);

            return(BeginDeviceIoControl <TIn, TOut>(hDevice, dwIoControlCode, buffer, userCallback, null));
        }
Пример #22
0
        private static unsafe Task <TOut?> ExplicitDeviceIoControlAsync <TIn, TOut>(HFILE hDevice, uint ioControlCode, TIn?inVal, TOut?outVal) where TIn : struct where TOut : struct
        {
#pragma warning disable CS0618 // Type or member is obsolete
            ThreadPool.BindHandle((IntPtr)hDevice);
#pragma warning restore CS0618 // Type or member is obsolete
            var tcs              = new TaskCompletionSource <TOut?>();
            var buffer           = Pack(inVal, outVal);
            var nativeOverlapped = new Overlapped().Pack((code, bytes, overlap) =>
            {
                try
                {
                    switch (code)
                    {
                    case Win32Error.ERROR_SUCCESS:
                        outVal = Unpack <TIn, TOut>(buffer).Item2;
                        tcs.TrySetResult(outVal);
                        break;

                    case Win32Error.ERROR_OPERATION_ABORTED:
                        tcs.TrySetCanceled();
                        break;

                    default:
                        tcs.TrySetException(new Win32Exception((int)code));
                        break;
                    }
                }
                finally
                {
                    Overlapped.Unpack(overlap);
                    Overlapped.Free(overlap);
                }
            }, buffer);

            var unpack = true;
            try
            {
                var inSz = Marshal.SizeOf(typeof(TIn));
                fixed(byte *pIn = buffer, pOut = &buffer[inSz])
                {
                    uint bRet;
                    var  ret = DeviceIoControl(hDevice, ioControlCode, pIn, (uint)inSz, pOut, (uint)(buffer.Length - inSz), out bRet,
                                               nativeOverlapped);

                    if (ret)
                    {
                        outVal = Unpack <TIn, TOut>(buffer).Item2;
                        tcs.SetResult(outVal);
                        return(tcs.Task);
                    }
                }

                var lastWin32Error = Marshal.GetLastWin32Error();
                if (lastWin32Error != Win32Error.ERROR_IO_PENDING && lastWin32Error != Win32Error.ERROR_SUCCESS)
                {
                    throw new Win32Exception(lastWin32Error);
                }
                unpack = false;
                return(tcs.Task);
            }
            finally
            {
                if (unpack)
                {
                    Overlapped.Unpack(nativeOverlapped);
                    Overlapped.Free(nativeOverlapped);
                }
            }
        }
Пример #23
0
 private void OnUpdate()
 {
     // Invalidate cache
     _cached = default;
 }