mirror of
https://github.com/soukoku/ntwain.git
synced 2026-01-09 11:21:06 +08:00
Cleanup boxed types.
This commit is contained in:
@@ -1,72 +0,0 @@
|
||||
using NTwain.Data;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NTwain.Caps;
|
||||
|
||||
public record ValueContainer<TValue>
|
||||
{
|
||||
public TWON ContainerType { get; set; }
|
||||
|
||||
public TValue? OneValue { get; set; }
|
||||
|
||||
public IList<TValue>? ArrayValue { get; set; }
|
||||
|
||||
public EnumValue<TValue>? EnumValue { get; set; }
|
||||
|
||||
public RangeValue<TValue>? RangeValue { get; set; }
|
||||
|
||||
public IEnumerable<TValue> GetValues()
|
||||
{
|
||||
return ContainerType switch
|
||||
{
|
||||
TWON.ONEVALUE => ToEnumerable(OneValue),
|
||||
TWON.ARRAY => ArrayValue ?? [],
|
||||
TWON.ENUMERATION => EnumValue?.Items ?? [],
|
||||
TWON.RANGE => RangeValue != null ? GenerateRangeValues(RangeValue) : [],
|
||||
_ => [],
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<TValue> ToEnumerable(TValue? value)
|
||||
{
|
||||
if (value == null) yield break;
|
||||
yield return value;
|
||||
}
|
||||
|
||||
private IEnumerable<TValue> GenerateRangeValues(RangeValue<TValue> range)
|
||||
{
|
||||
var dynamicType = typeof(DynamicEnumerator<>);
|
||||
var genericType = dynamicType.MakeGenericType(typeof(TValue));
|
||||
|
||||
var de = Activator.CreateInstance(genericType, range.Min, range.Max, range.Step) as IEnumerator;
|
||||
if (de == null) yield break;
|
||||
while (de.MoveNext())
|
||||
{
|
||||
yield return (TValue)de.Current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public record EnumValue<TValue>
|
||||
{
|
||||
public TValue[] Items { get; set; } = [];
|
||||
|
||||
public int CurrentIndex { get; set; }
|
||||
|
||||
public int DefaultIndex { get; set; }
|
||||
}
|
||||
|
||||
public record RangeValue<TValue>
|
||||
{
|
||||
public TValue Min { get; set; }
|
||||
|
||||
public TValue Max { get; set; }
|
||||
|
||||
public TValue Step { get; set; }
|
||||
|
||||
public TValue DefaultValue;
|
||||
|
||||
public TValue CurrentValue;
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
@@ -258,33 +260,37 @@ namespace NTwain.Data
|
||||
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class Enumeration<TValue>
|
||||
public record Enumeration<TValue>
|
||||
{
|
||||
public int CurrentIndex;
|
||||
public int CurrentIndex { get; set; }
|
||||
|
||||
public int DefaultIndex;
|
||||
public int DefaultIndex { get; set; }
|
||||
|
||||
public TValue[]? Items;
|
||||
public TValue[] Items { get; set; } = [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A more dotnet-friendly representation of <see cref="TW_RANGE"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public partial class Range<TValue> : IEnumerable<TValue> where TValue : struct
|
||||
public partial record Range<TValue> : IEnumerable<TValue>
|
||||
{
|
||||
public TValue MinValue;
|
||||
public TValue MaxValue;
|
||||
public TValue StepSize;
|
||||
public TValue DefaultValue;
|
||||
public TValue CurrentValue;
|
||||
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; }
|
||||
|
||||
IEnumerator<TValue> IEnumerable<TValue>.GetEnumerator()
|
||||
{
|
||||
if (MinValue is not IConvertible)
|
||||
throw new NotSupportedException($"The value type {typeof(TValue).Name} is not supported for range enumeration.");
|
||||
|
||||
return new DynamicEnumerator<TValue>(MinValue, MaxValue, StepSize);
|
||||
var dynamicType = typeof(DynamicEnumerator<>);
|
||||
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()
|
||||
@@ -292,16 +298,40 @@ namespace NTwain.Data
|
||||
return ((IEnumerable<TValue>)this).GetEnumerator();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A more dotnet-friendly representation of <see cref="TW_RANGE"/> with boxed values.
|
||||
/// A more dotnet-friendly container of CAP value.
|
||||
/// </summary>
|
||||
public partial class RangeBoxed
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public record ValueContainer<TValue>
|
||||
{
|
||||
public object MinValue;
|
||||
public object MaxValue;
|
||||
public object StepSize;
|
||||
public object DefaultValue;
|
||||
public object CurrentValue;
|
||||
public TWON ContainerType { get; set; }
|
||||
|
||||
public TValue? OneValue { get; set; }
|
||||
|
||||
public IList<TValue>? ArrayValue { get; set; }
|
||||
|
||||
public Enumeration<TValue>? EnumValue { get; set; }
|
||||
|
||||
public Range<TValue>? RangeValue { get; set; }
|
||||
|
||||
public IEnumerable<TValue> GetValues()
|
||||
{
|
||||
return ContainerType switch
|
||||
{
|
||||
TWON.ONEVALUE => ToEnumerable(OneValue),
|
||||
TWON.ARRAY => ArrayValue ?? [],
|
||||
TWON.ENUMERATION => EnumValue?.Items ?? [],
|
||||
TWON.RANGE => RangeValue != null ? RangeValue.ToArray() : [],
|
||||
_ => [],
|
||||
};
|
||||
}
|
||||
|
||||
private IEnumerable<TValue> ToEnumerable(TValue? value)
|
||||
{
|
||||
if (value == null) yield break;
|
||||
yield return value;
|
||||
}
|
||||
}
|
||||
|
||||
partial struct TW_FIX32 : IEquatable<TW_FIX32>, IConvertible
|
||||
|
||||
@@ -413,9 +413,9 @@ namespace NTwain.Data
|
||||
}
|
||||
}
|
||||
|
||||
public static RangeBoxed 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 RangeBoxed();
|
||||
var retVal = new Range<object>();
|
||||
|
||||
if (cap.ConType != TWON.RANGE || cap.hContainer == IntPtr.Zero) return retVal;
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace NTwain
|
||||
/// <param name="cap"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public STS GetCapCurrentBoxed(CAP cap, out List<object> value)
|
||||
public STS GetCapCurrentBoxed(CAP cap, out List<object> value)
|
||||
{
|
||||
value = new List<object>();
|
||||
var sts = GetCapCurrent(cap, out TW_CAPABILITY twcap);
|
||||
@@ -202,7 +202,7 @@ namespace NTwain
|
||||
/// <param name="cap"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public STS GetCapDefaultBoxed(CAP cap, out List<object> value)
|
||||
public STS GetCapDefaultBoxed(CAP cap, out List<object> value)
|
||||
{
|
||||
value = new List<object>();
|
||||
var sts = GetCapDefault(cap, out TW_CAPABILITY twcap);
|
||||
@@ -273,24 +273,12 @@ namespace NTwain
|
||||
var twenum = twcap.ReadEnumeration<TValue>(this);
|
||||
if (twenum.Items != null)
|
||||
{
|
||||
value.EnumValue = new EnumValue<TValue>
|
||||
{
|
||||
CurrentIndex = twenum.CurrentIndex,
|
||||
DefaultIndex = twenum.DefaultIndex,
|
||||
Items = twenum.Items
|
||||
};
|
||||
value.EnumValue = twenum;
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
var range = twcap.ReadRange<TValue>(this);
|
||||
value.RangeValue = new RangeValue<TValue>
|
||||
{
|
||||
Min = range.MinValue,
|
||||
Max = range.MaxValue,
|
||||
Step = range.StepSize,
|
||||
DefaultValue = range.DefaultValue,
|
||||
CurrentValue = range.CurrentValue
|
||||
};
|
||||
value.RangeValue = range;
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArray<TValue>(this);
|
||||
@@ -314,7 +302,7 @@ namespace NTwain
|
||||
/// <param name="cap"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public STS GetCapValuesBoxed(CAP cap, out ValueContainer<object> value)
|
||||
public STS GetCapValuesBoxed(CAP cap, out ValueContainer<object> value)
|
||||
{
|
||||
value = new ValueContainer<object> { ContainerType = TWON.DONTCARE };
|
||||
var sts = GetCapValues(cap, out TW_CAPABILITY twcap);
|
||||
@@ -330,24 +318,12 @@ namespace NTwain
|
||||
var twenum = twcap.ReadEnumerationBoxed(this);
|
||||
if (twenum.Items != null)
|
||||
{
|
||||
value.EnumValue = new EnumValue<object>
|
||||
{
|
||||
CurrentIndex = twenum.CurrentIndex,
|
||||
DefaultIndex = twenum.DefaultIndex,
|
||||
Items = twenum.Items
|
||||
};
|
||||
value.EnumValue = twenum;
|
||||
}
|
||||
break;
|
||||
case TWON.RANGE:
|
||||
var range = twcap.ReadRangeBoxed(this);
|
||||
value.RangeValue = new RangeValue<object>
|
||||
{
|
||||
Min = range.MinValue,
|
||||
Max = range.MaxValue,
|
||||
Step = range.StepSize,
|
||||
DefaultValue = range.DefaultValue,
|
||||
CurrentValue = range.CurrentValue
|
||||
};
|
||||
value.RangeValue = range;
|
||||
break;
|
||||
case TWON.ARRAY:
|
||||
var twarr = twcap.ReadArrayBoxed(this);
|
||||
@@ -459,6 +435,48 @@ namespace NTwain
|
||||
return SetCap(ref twcap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A cap value setter for all kinds of container types.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="cap"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public STS SetCap<TValue>(CAP cap, ValueContainer<TValue> value) where TValue : struct
|
||||
{
|
||||
switch (value.ContainerType)
|
||||
{
|
||||
case TWON.ONEVALUE:
|
||||
{
|
||||
var twcap = ValueWriter.CreateOneValueCap(cap, this, value.OneValue);
|
||||
return SetCap(ref twcap);
|
||||
}
|
||||
case TWON.ENUMERATION:
|
||||
{
|
||||
if (value.EnumValue == null)
|
||||
throw new ArgumentException("EnumValue cannot be null when ContainerType is ENUMERATION.", nameof(value));
|
||||
var twcap = ValueWriter.CreateEnumCap(cap, this, value.EnumValue);
|
||||
return SetCap(ref twcap);
|
||||
}
|
||||
case TWON.RANGE:
|
||||
{
|
||||
if (value.RangeValue == null)
|
||||
throw new ArgumentException("RangeValue cannot be null when ContainerType is RANGE.", nameof(value));
|
||||
var twcap = ValueWriter.CreateRangeCap(cap, this, value.RangeValue);
|
||||
return SetCap(ref twcap);
|
||||
}
|
||||
case TWON.ARRAY:
|
||||
{
|
||||
if (value.ArrayValue == null)
|
||||
throw new ArgumentException("ArrayValue cannot be null when ContainerType is ARRAY.", nameof(value));
|
||||
var twcap = ValueWriter.CreateArrayCap(cap, this, value.ArrayValue);
|
||||
return SetCap(ref twcap);
|
||||
}
|
||||
default:
|
||||
throw new ArgumentException("Unsupported ContainerType for setting CAP.", nameof(value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a CAP's constraint values.
|
||||
/// An easy way to create a value is to use the
|
||||
|
||||
Reference in New Issue
Block a user