Added array and enum container writers.

This commit is contained in:
Eugene Wang 2021-04-26 21:45:50 -04:00
parent 690876eebd
commit 8e47fd370e
3 changed files with 206 additions and 33 deletions

View File

@ -39,7 +39,7 @@ namespace NTwain
var sts = _twain.DatCapability(DG.CONTROL, MSG.QUERYSUPPORT, ref twCap);
if (sts == STS.SUCCESS && twCap.ConType == TWON.ONEVALUE)
{
return ValueReader.ReadOneValue<TWQC>(_twain, twCap);
return ValueReader.ReadOneValueContainer<TWQC>(_twain, ref twCap);
}
return TWQC.Uknown;
}
@ -61,13 +61,13 @@ namespace NTwain
switch (twCap.ConType)
{
case TWON.ONEVALUE:
return new[] { ValueReader.ReadOneValue<TValue>(_twain, twCap) };
return new[] { ValueReader.ReadOneValueContainer<TValue>(_twain, ref twCap) };
case TWON.ENUMERATION:
return ValueReader.ReadEnumeration<TValue>(_twain, twCap).Items;
return ValueReader.ReadEnumerationContainer<TValue>(_twain, ref twCap).Items;
case TWON.ARRAY:
return ValueReader.ReadArray<TValue>(_twain, twCap);
return ValueReader.ReadArrayContainer<TValue>(_twain, ref twCap);
case TWON.RANGE:
return ValueReader.ReadRange<TValue>(_twain, twCap).ToList();
return ValueReader.ReadRangeContainer<TValue>(_twain, ref twCap).ToList();
}
}
return EmptyArray<TValue>.Value;
@ -90,14 +90,14 @@ namespace NTwain
switch (twCap.ConType)
{
case TWON.ONEVALUE:
return ValueReader.ReadOneValue<TValue>(_twain, twCap);
return ValueReader.ReadOneValueContainer<TValue>(_twain, ref twCap);
case TWON.ENUMERATION:
var enumeration = ValueReader.ReadEnumeration<TValue>(_twain, twCap);
var enumeration = ValueReader.ReadEnumerationContainer<TValue>(_twain, ref twCap);
if (enumeration.CurrentIndex < enumeration.Items.Length)
return enumeration.Items[enumeration.CurrentIndex];
break;
case TWON.RANGE:
return ValueReader.ReadRange<TValue>(_twain, twCap).CurrentValue;
return ValueReader.ReadRangeContainer<TValue>(_twain, ref twCap).CurrentValue;
}
}
return default;
@ -120,14 +120,14 @@ namespace NTwain
switch (twCap.ConType)
{
case TWON.ONEVALUE:
return ValueReader.ReadOneValue<TValue>(_twain, twCap);
return ValueReader.ReadOneValueContainer<TValue>(_twain, ref twCap);
case TWON.ENUMERATION:
var enumeration = ValueReader.ReadEnumeration<TValue>(_twain, twCap);
var enumeration = ValueReader.ReadEnumerationContainer<TValue>(_twain, ref twCap);
if (enumeration.DefaultIndex < enumeration.Items.Length)
return enumeration.Items[enumeration.DefaultIndex];
break;
case TWON.RANGE:
return ValueReader.ReadRange<TValue>(_twain, twCap).DefaultValue;
return ValueReader.ReadRangeContainer<TValue>(_twain, ref twCap).DefaultValue;
}
}
return default;
@ -147,7 +147,7 @@ namespace NTwain
var sts = _twain.DatCapability(DG.CONTROL, MSG.GETLABEL, ref twCap);
if (sts == STS.SUCCESS)
{
return ValueReader.ReadOneString(_twain, twCap);
return ValueReader.ReadOneValueContainerString(_twain, twCap);
}
return null;
}
@ -166,7 +166,7 @@ namespace NTwain
var sts = _twain.DatCapability(DG.CONTROL, MSG.GETHELP, ref twCap);
if (sts == STS.SUCCESS)
{
return ValueReader.ReadOneString(_twain, twCap);
return ValueReader.ReadOneValueContainerString(_twain, twCap);
}
return null;
}
@ -204,7 +204,7 @@ namespace NTwain
};
try
{
ValueWriter.WriteOneValue(_twain, ref twCap, value);
ValueWriter.WriteOneValueContainer(_twain, ref twCap, value);
return _twain.DatCapability(DG.CONTROL, setMsg, ref twCap);
}
finally
@ -233,7 +233,7 @@ namespace NTwain
};
try
{
ValueWriter.WriteArray(_twain, ref twCap, values);
ValueWriter.WriteArrayContainer(_twain, ref twCap, values);
return _twain.DatCapability(DG.CONTROL, setMsg, ref twCap);
}
finally
@ -262,7 +262,7 @@ namespace NTwain
};
try
{
ValueWriter.WriteRange(_twain, ref twCap, value);
ValueWriter.WriteRangeContainer(_twain, ref twCap, value);
return _twain.DatCapability(DG.CONTROL, setMsg, ref twCap);
}
finally
@ -291,7 +291,7 @@ namespace NTwain
};
try
{
ValueWriter.WriteEnum(_twain, ref twCap, value);
ValueWriter.WriteEnumContainer(_twain, ref twCap, value);
return _twain.DatCapability(DG.CONTROL, setMsg, ref twCap);
}
finally

View File

@ -16,7 +16,7 @@ namespace NTwain
{
// most of these are modified from the original TWAIN.CapabilityToCsv()
public static TValue ReadOneValue<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
public static TValue ReadOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{
if (cap.hContainer == IntPtr.Zero) return default;
@ -49,7 +49,7 @@ namespace NTwain
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
}
public static Enumeration<TValue> ReadEnumeration<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
public static Enumeration<TValue> ReadEnumerationContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{
Enumeration<TValue> retVal = new Enumeration<TValue>();
@ -117,7 +117,7 @@ namespace NTwain
}
return retVal;
}
public static IList<TValue> ReadArray<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
public static IList<TValue> ReadArrayContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{
if (cap.hContainer == IntPtr.Zero) return EmptyArray<TValue>.Value;
@ -159,7 +159,7 @@ namespace NTwain
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
}
}
public static Range<TValue> ReadRange<TValue>(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
public static Range<TValue> ReadRangeContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
{
var retVal = new Range<TValue>();
@ -260,7 +260,7 @@ namespace NTwain
/// <param name="cap"></param>
/// <param name="freeMemory"></param>
/// <returns></returns>
public static string ReadOneString(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true)
public static string ReadOneValueContainerString(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true)
{
if (cap.hContainer == IntPtr.Zero) return null;

View File

@ -13,21 +13,26 @@ namespace NTwain
/// </summary>
public static class ValueWriter
{
// most of these are modified from the original TWAIN.CsvToCapability()
public static void WriteOneValue<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue value) where TValue : struct
public static void WriteOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue value) where TValue : struct
{
IntPtr lockedPtr = IntPtr.Zero;
try
{
if (twCap.hContainer != IntPtr.Zero) twain.DsmMemFree(ref twCap.hContainer);
TWTY itemType = GetItemType<TValue>();
// Allocate the container (go for worst case, which is TW_STR255)...
if (PlatformTools.GetPlatform() == Platform.MACOSX)
{
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE_MACOSX)) + Marshal.SizeOf(default(TW_STR255))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
TW_ONEVALUE_MACOSX twonevaluemacosx = default(TW_ONEVALUE_MACOSX);
TW_ONEVALUE_MACOSX twonevaluemacosx = default;
twonevaluemacosx.ItemType = (uint)itemType;
Marshal.StructureToPtr(twonevaluemacosx, lockedPtr, true);
Marshal.StructureToPtr(twonevaluemacosx, lockedPtr, false);
lockedPtr += Marshal.SizeOf(twonevaluemacosx);
}
@ -36,9 +41,9 @@ namespace NTwain
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE)) + Marshal.SizeOf(default(TW_STR255))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
TW_ONEVALUE twonevalue = default(TW_ONEVALUE);
TW_ONEVALUE twonevalue = default;
twonevalue.ItemType = itemType;
Marshal.StructureToPtr(twonevalue, lockedPtr, true);
Marshal.StructureToPtr(twonevalue, lockedPtr, false);
lockedPtr += Marshal.SizeOf(twonevalue);
}
@ -51,18 +56,183 @@ namespace NTwain
}
}
public static void WriteArray<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue[] values) where TValue : struct
public static void WriteArrayContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue[] values) where TValue : struct
{
throw new NotImplementedException();
IntPtr lockedPtr = IntPtr.Zero;
try
{
if (twCap.hContainer != IntPtr.Zero) twain.DsmMemFree(ref twCap.hContainer);
TWTY itemType = GetItemType<TValue>();
// Allocate the container (go for worst case, which is TW_STR255)...
if (PlatformTools.GetPlatform() == Platform.MACOSX)
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ARRAY_MACOSX)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
// Set the meta data...
TW_ARRAY_MACOSX twarraymacosx = default;
twarraymacosx.ItemType = (uint)itemType;
twarraymacosx.NumItems = (uint)values.Length;
Marshal.StructureToPtr(twarraymacosx, lockedPtr, false);
// Get the pointer to the ItemList...
lockedPtr += Marshal.SizeOf(twarraymacosx);
}
else
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ARRAY)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
// Set the meta data...
TW_ARRAY twarray = default;
twarray.ItemType = itemType;
twarray.NumItems = (uint)values.Length;
Marshal.StructureToPtr(twarray, lockedPtr, false);
// Get the pointer to the ItemList...
lockedPtr += Marshal.SizeOf(twarray);
}
// Set the ItemList...
for (var i = 0; i < values.Length; i++)
{
WriteContainerData(lockedPtr, itemType, values[i], i);
}
}
finally
{
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(twCap.hContainer);
}
}
public static void WriteRange<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, Range<TValue> value) where TValue : struct
public static void WriteRangeContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, Range<TValue> value) where TValue : struct
{
IntPtr lockedPtr = IntPtr.Zero;
try
{
if (twCap.hContainer != IntPtr.Zero) twain.DsmMemFree(ref twCap.hContainer);
TWTY itemType = GetItemType<TValue>();
var platform = PlatformTools.GetPlatform();
// Allocate the container (go for worst case, which is TW_STR255)...
if (platform == Platform.MACOSX)
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE_MACOSX))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
}
// Windows or the 2.4+ Linux DSM...
else if ((platform == Platform.WINDOWS) ||
(twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
}
// The -2.3 Linux DSM...
else
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_RANGE_LINUX64))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
}
// Set the Item...
WriteRangeValues(lockedPtr, itemType, value);
}
finally
{
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(twCap.hContainer);
}
}
private static void WriteRangeValues<TValue>(IntPtr lockedPtr, TWTY itemType, Range<TValue> value) where TValue : struct
{
throw new NotImplementedException();
}
public static void WriteEnum<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, Enumeration<TValue> value) where TValue : struct
public static void WriteEnumContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, Enumeration<TValue> value) where TValue : struct
{
throw new NotImplementedException();
IntPtr lockedPtr = IntPtr.Zero;
try
{
if (twCap.hContainer != IntPtr.Zero) twain.DsmMemFree(ref twCap.hContainer);
TWTY itemType = GetItemType<TValue>();
var platform = PlatformTools.GetPlatform();
// Allocate the container (go for worst case, which is TW_STR255)...
if (platform == Platform.MACOSX)
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_MACOSX)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
// Set the meta data...
TW_ENUMERATION_MACOSX twenumerationmacosx = default;
twenumerationmacosx.ItemType = (uint)itemType;
twenumerationmacosx.NumItems = (uint)value.Items.Length;
twenumerationmacosx.CurrentIndex = (uint)value.CurrentIndex;
twenumerationmacosx.DefaultIndex = (uint)value.DefaultIndex;
Marshal.StructureToPtr(twenumerationmacosx, lockedPtr, false);
// Get the pointer to the ItemList...
lockedPtr += Marshal.SizeOf(twenumerationmacosx);
}
// Windows or the 2.4+ Linux DSM...
else if ((platform == Platform.WINDOWS) ||
(twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
// Set the meta data...
TW_ENUMERATION twenumeration = default;
twenumeration.ItemType = itemType;
twenumeration.NumItems = (uint)value.Items.Length;
twenumeration.CurrentIndex = (uint)value.CurrentIndex;
twenumeration.DefaultIndex = (uint)value.CurrentIndex;
Marshal.StructureToPtr(twenumeration, lockedPtr, false);
// Get the pointer to the ItemList...
lockedPtr += Marshal.SizeOf(twenumeration);
}
// The -2.3 Linux DSM...
else
{
// Allocate...
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_LINUX64)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
lockedPtr = twain.DsmMemLock(twCap.hContainer);
// Set the meta data...
TW_ENUMERATION_LINUX64 twenumerationlinux64 = default;
twenumerationlinux64.ItemType = itemType;
twenumerationlinux64.NumItems = (ulong)value.Items.Length;
twenumerationlinux64.CurrentIndex = (ulong)value.CurrentIndex;
twenumerationlinux64.DefaultIndex = (ulong)value.CurrentIndex;
Marshal.StructureToPtr(twenumerationlinux64, lockedPtr, false);
// Get the pointer to the ItemList...
lockedPtr += Marshal.SizeOf(twenumerationlinux64);
}
// Set the ItemList...
for (var i = 0; i < value.Items.Length; i++)
{
WriteContainerData(lockedPtr, itemType, value.Items[i], i);
}
}
finally
{
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(twCap.hContainer);
}
}
@ -133,9 +303,12 @@ namespace NTwain
Marshal.StructureToPtr(Convert.ToUInt16(value), intptr, false);
break;
case TWTY.INT32:
intptr += 4 * itemIndex;
Marshal.StructureToPtr(Convert.ToInt32(value), intptr, false);
break;
case TWTY.UINT32:
intptr += 4 * itemIndex;
Marshal.StructureToPtr(value, intptr, false);
Marshal.StructureToPtr(Convert.ToUInt32(value), intptr, false);
break;
case TWTY.FIX32:
intptr += 4 * itemIndex;