mirror of
https://github.com/soukoku/ntwain.git
synced 2026-01-09 11:21:06 +08:00
Remove IEnumerable from range and add more boxed reads.
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<!--change these in each release-->
|
||||
<VersionPrefix>4.0.0.0</VersionPrefix>
|
||||
<VersionSuffix>alpha.19</VersionSuffix>
|
||||
<VersionSuffix>alpha.21</VersionSuffix>
|
||||
|
||||
<!--keep it the same until major # changes-->
|
||||
<AssemblyVersion>4.0.0.0</AssemblyVersion>
|
||||
|
||||
47
src/NTwain/CompilerTypes.cs
Normal file
47
src/NTwain/CompilerTypes.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace System.Runtime.CompilerServices
|
||||
{
|
||||
#if !NET5_0_OR_GREATER
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal static class IsExternalInit {}
|
||||
|
||||
#endif // !NET5_0_OR_GREATER
|
||||
|
||||
#if !NET7_0_OR_GREATER
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class RequiredMemberAttribute : Attribute {}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
|
||||
internal sealed class CompilerFeatureRequiredAttribute : Attribute
|
||||
{
|
||||
public CompilerFeatureRequiredAttribute(string featureName)
|
||||
{
|
||||
FeatureName = featureName;
|
||||
}
|
||||
|
||||
public string FeatureName { get; }
|
||||
public bool IsOptional { get; init; }
|
||||
|
||||
public const string RefStructs = nameof(RefStructs);
|
||||
public const string RequiredMembers = nameof(RequiredMembers);
|
||||
}
|
||||
|
||||
#endif // !NET7_0_OR_GREATER
|
||||
}
|
||||
|
||||
namespace System.Diagnostics.CodeAnalysis
|
||||
{
|
||||
#if !NET7_0_OR_GREATER
|
||||
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class SetsRequiredMembersAttribute : Attribute {}
|
||||
#endif
|
||||
}
|
||||
@@ -273,15 +273,20 @@ namespace NTwain.Data
|
||||
/// A more dotnet-friendly representation of <see cref="TW_RANGE"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public partial record Range<TValue> : IEnumerable<TValue>
|
||||
public partial record Range<TValue>
|
||||
{
|
||||
public TValue MinValue { get; set; }
|
||||
public TValue MaxValue { get; set; }
|
||||
public TValue StepSize { get; set; }
|
||||
public TValue DefaultValue { get; set; }
|
||||
public TValue CurrentValue { get; set; }
|
||||
public required TValue MinValue { get; set; }
|
||||
public required TValue MaxValue { get; set; }
|
||||
public required TValue StepSize { get; set; }
|
||||
public required TValue DefaultValue { get; set; }
|
||||
public required TValue CurrentValue { get; set; }
|
||||
|
||||
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
|
||||
/// <summary>
|
||||
/// Tries to enumerate the range values.
|
||||
/// This could be expensive depending on the range size.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<TValue> Enumerate()
|
||||
{
|
||||
if (MinValue is not IConvertible)
|
||||
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration.");
|
||||
@@ -290,12 +295,10 @@ namespace NTwain.Data
|
||||
var genericType = dynamicType.MakeGenericType(typeof(TValue));
|
||||
|
||||
var de = (IEnumerator<TValue>)Activator.CreateInstance(genericType, MinValue, MaxValue, StepSize)!;
|
||||
return de;
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable<TValue>)this).GetEnumerator();
|
||||
while (de.MoveNext())
|
||||
{
|
||||
yield return de.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +325,7 @@ namespace NTwain.Data
|
||||
TWON.ONEVALUE => ToEnumerable(OneValue),
|
||||
TWON.ARRAY => ArrayValue ?? [],
|
||||
TWON.ENUMERATION => EnumValue?.Items ?? [],
|
||||
TWON.RANGE => RangeValue != null ? RangeValue.ToArray() : [],
|
||||
TWON.RANGE => RangeValue != null ? RangeValue.Enumerate() : [],
|
||||
_ => [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -175,7 +175,7 @@ namespace NTwain.Data
|
||||
}
|
||||
}
|
||||
|
||||
public static Enumeration<object> ReadEnumerationBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||
public static Enumeration<object> ReadEnumerationBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||
{
|
||||
Enumeration<object> retVal = new();
|
||||
|
||||
@@ -319,7 +319,7 @@ namespace NTwain.Data
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static IList<object> ReadArrayBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||
public static IList<object> ReadArrayBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||
{
|
||||
if (cap.ConType != TWON.ARRAY || cap.hContainer == IntPtr.Zero) return Array.Empty<object>();
|
||||
|
||||
@@ -413,11 +413,9 @@ namespace NTwain.Data
|
||||
}
|
||||
}
|
||||
|
||||
public static Range<object> ReadRangeBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||
public static Range<object>? ReadRangeBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||
{
|
||||
var retVal = new Range<object>();
|
||||
|
||||
if (cap.ConType != TWON.RANGE || cap.hContainer == IntPtr.Zero) return retVal;
|
||||
if (cap.ConType != TWON.RANGE || cap.hContainer == IntPtr.Zero) return null;
|
||||
|
||||
var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
@@ -436,17 +434,24 @@ namespace NTwain.Data
|
||||
itemType = (TWTY)Marshal.ReadInt16(lockedPtr);
|
||||
lockedPtr += 2;
|
||||
}
|
||||
retVal.MinValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
var minValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.MaxValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
var maxValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.StepSize = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
var stepSize = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.CurrentValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
var currentValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.DefaultValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
var defaultValue = ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
return retVal;
|
||||
return new Range<object>
|
||||
{
|
||||
MinValue = minValue,
|
||||
MaxValue = maxValue,
|
||||
StepSize = stepSize,
|
||||
CurrentValue = currentValue,
|
||||
DefaultValue = defaultValue
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -459,11 +464,9 @@ namespace NTwain.Data
|
||||
}
|
||||
}
|
||||
|
||||
public static Range<TValue> ReadRange<TValue>(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true) where TValue : struct
|
||||
public static Range<TValue>? ReadRange<TValue>(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true) where TValue : struct
|
||||
{
|
||||
var retVal = new Range<TValue>();
|
||||
|
||||
if (cap.ConType != TWON.RANGE || cap.hContainer == IntPtr.Zero) return retVal;
|
||||
if (cap.ConType != TWON.RANGE || cap.hContainer == IntPtr.Zero) return null;
|
||||
|
||||
var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
@@ -482,17 +485,24 @@ namespace NTwain.Data
|
||||
itemType = (TWTY)Marshal.ReadInt16(lockedPtr);
|
||||
lockedPtr += 2;
|
||||
}
|
||||
retVal.MinValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
var minValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.MaxValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
var maxValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.StepSize = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
var stepSize = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.CurrentValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
var currentValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
retVal.DefaultValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
var defaultValue = ReadTWTYData<TValue>(lockedPtr, itemType, 0);
|
||||
lockedPtr += 4;
|
||||
return retVal;
|
||||
return new Range<TValue>
|
||||
{
|
||||
MinValue = minValue,
|
||||
MaxValue = maxValue,
|
||||
StepSize = stepSize,
|
||||
CurrentValue = currentValue,
|
||||
DefaultValue = defaultValue
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -88,7 +88,8 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
value.Add(twcap.ReadRange<TValue>(this).CurrentValue);
|
||||
var range = twcap.ReadRange<TValue>(this);
|
||||
if (range != null) value.Add(range.CurrentValue);
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArray<TValue>(this);
|
||||
@@ -110,7 +111,7 @@ namespace NTwain
|
||||
/// <returns></returns>
|
||||
public STS GetCapCurrentBoxed(CAP cap, out List<object> value)
|
||||
{
|
||||
value = new List<object>();
|
||||
value = [];
|
||||
var sts = GetCapCurrent(cap, out TW_CAPABILITY twcap);
|
||||
if (sts.RC == TWRC.SUCCESS)
|
||||
{
|
||||
@@ -128,7 +129,8 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
value.Add(twcap.ReadRangeBoxed(this).CurrentValue);
|
||||
var range = twcap.ReadRangeBoxed(this);
|
||||
if (range != null) value.Add(range.CurrentValue);
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArrayBoxed(this);
|
||||
@@ -165,7 +167,7 @@ namespace NTwain
|
||||
/// <returns></returns>
|
||||
public STS GetCapDefault<TValue>(CAP cap, out List<TValue> value) where TValue : struct
|
||||
{
|
||||
value = new List<TValue>();
|
||||
value = [];
|
||||
var sts = GetCapDefault(cap, out TW_CAPABILITY twcap);
|
||||
if (sts.RC == TWRC.SUCCESS)
|
||||
{
|
||||
@@ -182,7 +184,8 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
value.Add(twcap.ReadRange<TValue>(this).DefaultValue);
|
||||
var range = twcap.ReadRange<TValue>(this);
|
||||
if (range != null) value.Add(range.DefaultValue);
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArray<TValue>(this);
|
||||
@@ -204,7 +207,7 @@ namespace NTwain
|
||||
/// <returns></returns>
|
||||
public STS GetCapDefaultBoxed(CAP cap, out List<object> value)
|
||||
{
|
||||
value = new List<object>();
|
||||
value = [];
|
||||
var sts = GetCapDefault(cap, out TW_CAPABILITY twcap);
|
||||
if (sts.RC == TWRC.SUCCESS)
|
||||
{
|
||||
@@ -222,7 +225,8 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
value.Add(twcap.ReadRangeBoxed(this).DefaultValue);
|
||||
var range = twcap.ReadRangeBoxed(this);
|
||||
if (range != null) value.Add(range.DefaultValue);
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArrayBoxed(this);
|
||||
@@ -651,7 +655,8 @@ namespace NTwain
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
value.Add(twcap.ReadRange<TValue>(this).CurrentValue);
|
||||
var range = twcap.ReadRange<TValue>(this);
|
||||
if (range != null) value.Add(range.CurrentValue);
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArray<TValue>(this);
|
||||
@@ -664,6 +669,47 @@ namespace NTwain
|
||||
return sts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets a CAP's current value to power-on default.
|
||||
/// </summary>
|
||||
/// <param name="cap"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public STS ResetCapBoxed(CAP cap, out List<object> value)
|
||||
{
|
||||
value = [];
|
||||
var sts = ResetCap(cap, out TW_CAPABILITY twcap);
|
||||
|
||||
if (sts.RC == TWRC.SUCCESS)
|
||||
{
|
||||
switch (twcap.ConType)
|
||||
{
|
||||
case TWON.ONEVALUE:
|
||||
var read = twcap.ReadOneValueBoxed(this);
|
||||
if (read != null) value.Add(read);
|
||||
break;
|
||||
case TWON.ENUMERATION:
|
||||
var twenum = twcap.ReadEnumerationBoxed(this);
|
||||
if (twenum.Items != null && twenum.CurrentIndex < twenum.Items.Length)
|
||||
{
|
||||
value.Add(twenum.Items[twenum.CurrentIndex]);
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
var range = twcap.ReadRangeBoxed(this);
|
||||
if (range != null) value.Add(range.CurrentValue);
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArrayBoxed(this);
|
||||
if (twarr != null && twarr.Count > 0) value.AddRange(twarr);
|
||||
break;
|
||||
default:
|
||||
twcap.Free(this); break;
|
||||
}
|
||||
}
|
||||
return sts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all CAP values and constraint to power-on defaults.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user