Added tw_enum reads to ValueReader.

This commit is contained in:
Eugene Wang
2021-04-25 15:13:25 -04:00
parent 65a07e0254
commit 73e0681576
5 changed files with 108 additions and 30 deletions

View File

@@ -62,7 +62,7 @@ namespace NTwain
case TWON.ONEVALUE:
return new[] { ValueReader.ReadOneValue<TValue>(_twain, twCap) };
case TWON.ENUMERATION:
return ValueReader.ReadEnumeration<TValue>(_twain, twCap);
return ValueReader.ReadEnumeration<TValue>(_twain, twCap).Items;
case TWON.ARRAY:
return ValueReader.ReadArray<TValue>(_twain, twCap);
case TWON.RANGE:
@@ -91,7 +91,10 @@ namespace NTwain
case TWON.ONEVALUE:
return ValueReader.ReadOneValue<TValue>(_twain, twCap);
case TWON.ENUMERATION:
return ValueReader.ReadEnumeration<TValue>(_twain, twCap)[0];
var enumeration = ValueReader.ReadEnumeration<TValue>(_twain, twCap);
if (enumeration.CurrentIndex < enumeration.Items.Length)
return enumeration.Items[enumeration.CurrentIndex];
break;
case TWON.RANGE:
return ValueReader.ReadRange<TValue>(_twain, twCap).currentVal;
}
@@ -118,7 +121,10 @@ namespace NTwain
case TWON.ONEVALUE:
return ValueReader.ReadOneValue<TValue>(_twain, twCap);
case TWON.ENUMERATION:
return ValueReader.ReadEnumeration<TValue>(_twain, twCap)[0];
var enumeration = ValueReader.ReadEnumeration<TValue>(_twain, twCap);
if (enumeration.DefaultIndex < enumeration.Items.Length)
return enumeration.Items[enumeration.DefaultIndex];
break;
case TWON.RANGE:
return ValueReader.ReadRange<TValue>(_twain, twCap).defaultVal;
}

View File

@@ -24,6 +24,19 @@ namespace TWAINWorkingGroup
True = 1
}
/// <summary>
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
/// </summary>
/// <typeparam name="TValue"></typeparam>
public class Enumeration<TValue> where TValue : struct
{
public int CurrentIndex { get; set; }
public int DefaultIndex { get; set; }
public TValue[] Items { get; set; }
}
partial struct TW_FIX32 : IEquatable<TW_FIX32>
{
// the conversion logic is found in the spec.

View File

@@ -12489,11 +12489,11 @@ namespace TWAINWorkingGroup
/// using either one or both DSMs, depending on what is
/// available...
/// </summary>
private LinuxDsm m_linuxdsm;
internal LinuxDsm m_linuxdsm;
private LinuxDsm m_linux64bitdsmDatIdentity;
private bool m_blFoundLatestDsm;
private bool m_blFoundLatestDsm64;
private bool m_blFound020302Dsm64bit;
internal bool m_blFoundLatestDsm;
internal bool m_blFoundLatestDsm64;
internal bool m_blFound020302Dsm64bit;
/// <summary>
/// Use the callback system (TWAINDSM.DLL only)...

View File

@@ -47,15 +47,77 @@ namespace NTwain
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
}
public static IList<TValue> ReadEnumeration<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
public static Enumeration<TValue> ReadEnumeration<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{
throw new NotImplementedException();
Enumeration<TValue> retVal = new Enumeration<TValue>();
if (cap.hContainer == IntPtr.Zero) return retVal;
var lockedPtr = twain.DsmMemLock(cap.hContainer);
try
{
var platform = PlatformTools.GetPlatform();
TWTY itemType;
int count = 0;
// Mac has a level of indirection and a different structure (ick)...
if (platform == Platform.MACOSX)
{
// Crack the container...
var twenumerationmacosx = MarshalTo<TW_ENUMERATION_MACOSX>(lockedPtr);
itemType = (TWTY)twenumerationmacosx.ItemType;
count = (int)twenumerationmacosx.NumItems;
retVal.DefaultIndex = (int)twenumerationmacosx.DefaultIndex;
retVal.CurrentIndex = (int)twenumerationmacosx.CurrentIndex;
lockedPtr += Marshal.SizeOf(twenumerationmacosx);
}
// Windows or the 2.4+ Linux DSM...
else if ((platform == Platform.WINDOWS) || ((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
{
// Crack the container...
var twenumeration = MarshalTo<TW_ENUMERATION>(lockedPtr);
itemType = twenumeration.ItemType;
count = (int)twenumeration.NumItems;
retVal.DefaultIndex = (int)twenumeration.DefaultIndex;
retVal.CurrentIndex = (int)twenumeration.CurrentIndex;
lockedPtr += Marshal.SizeOf(twenumeration);
}
// The -2.3 Linux DSM...
else if (twain.m_blFound020302Dsm64bit && (twain.m_linuxdsm == TWAIN.LinuxDsm.Is020302Dsm64bit))
{
// Crack the container...
var twenumerationlinux64 = MarshalTo<TW_ENUMERATION_LINUX64>(lockedPtr);
itemType = twenumerationlinux64.ItemType;
count = (int)twenumerationlinux64.NumItems;
retVal.DefaultIndex = (int)twenumerationlinux64.DefaultIndex;
retVal.CurrentIndex = (int)twenumerationlinux64.CurrentIndex;
lockedPtr += Marshal.SizeOf(twenumerationlinux64);
}
// This shouldn't be possible, but what the hey...
else
{
Log.Error("This is serious, you win a cookie for getting here...");
return retVal;
}
retVal.Items = new TValue[count];
for (var i = 0; i < count; i++)
{
retVal.Items[i] = ReadContainerData<TValue>(lockedPtr, itemType, i);
}
}
finally
{
twain.DsmMemUnlock(cap.hContainer);
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
return retVal;
}
public static IList<TValue> ReadArray<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{
var list = new List<TValue>();
if (cap.hContainer == IntPtr.Zero) return list;
if (cap.hContainer == IntPtr.Zero) return new TValue[0];
var lockedPtr = twain.DsmMemLock(cap.hContainer);
@@ -68,8 +130,7 @@ namespace NTwain
if (PlatformTools.GetPlatform() == Platform.MACOSX)
{
// Crack the container...
TW_ARRAY_MACOSX twarraymacosx = default(TW_ARRAY_MACOSX);
twarraymacosx = MarshalTo<TW_ARRAY_MACOSX>(lockedPtr);
var twarraymacosx = MarshalTo<TW_ARRAY_MACOSX>(lockedPtr);
itemType = (TWTY)twarraymacosx.ItemType;
count = twarraymacosx.NumItems;
lockedPtr += Marshal.SizeOf(twarraymacosx);
@@ -77,24 +138,24 @@ namespace NTwain
else
{
// Crack the container...
TW_ARRAY twarray = default(TW_ARRAY);
twarray = MarshalTo<TW_ARRAY>(lockedPtr);
var twarray = MarshalTo<TW_ARRAY>(lockedPtr);
itemType = twarray.ItemType;
count = twarray.NumItems;
lockedPtr += Marshal.SizeOf(twarray);
}
var arr = new TValue[count];
for (var i = 0; i < count; i++)
{
list.Add(ReadContainerData<TValue>(lockedPtr, itemType, i));
arr[i] = ReadContainerData<TValue>(lockedPtr, itemType, i);
}
return arr;
}
finally
{
twain.DsmMemUnlock(cap.hContainer);
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
return list;
}
public static (TValue defaultVal, TValue currentVal, IEnumerable<TValue> values)
ReadRange<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct