From c29f4944e976b1cd35689f540a917585a4a9fc75 Mon Sep 17 00:00:00 2001
From: Eugene Wang <8755753+soukoku@users.noreply.github.com>
Date: Fri, 7 Apr 2023 20:11:26 -0400
Subject: [PATCH] Resurrected previous cap value writer from twaincs.
---
samples/WinForm32/Form1.cs | 2 +-
src/NTwain/Data/ValueWriter.cs | 1079 +++++++++++++++-------------
src/NTwain/TwainAppSession.Caps.cs | 7 +-
3 files changed, 571 insertions(+), 517 deletions(-)
diff --git a/samples/WinForm32/Form1.cs b/samples/WinForm32/Form1.cs
index 5deb905..bca04eb 100644
--- a/samples/WinForm32/Form1.cs
+++ b/samples/WinForm32/Form1.cs
@@ -20,7 +20,7 @@ namespace WinFormSample
public Form1()
{
InitializeComponent();
- var libVer = FileVersionInfo.GetVersionInfo(typeof(TwainAppSession).Assembly.Location).FileVersion;
+ var libVer = FileVersionInfo.GetVersionInfo(typeof(TwainAppSession).Assembly.Location).ProductVersion;
Text += $"{(TwainPlatform.Is32bit ? " 32bit" : " 64bit")} on NTwain {libVer}";
TwainPlatform.PreferLegacyDSM = false;
diff --git a/src/NTwain/Data/ValueWriter.cs b/src/NTwain/Data/ValueWriter.cs
index 345a061..8e4c358 100644
--- a/src/NTwain/Data/ValueWriter.cs
+++ b/src/NTwain/Data/ValueWriter.cs
@@ -8,7 +8,7 @@ namespace NTwain.Data
///
/// Contains methods for writing vairous things to pointers.
///
- static class ValueWriter
+ public static class ValueWriter
{
///
/// Allocates and copies the string value into a pointer in UTF8 that's null-terminated.
@@ -38,556 +38,605 @@ namespace NTwain.Data
// most of these are modified from the original TWAIN.CsvToCapability()
- //public static void WriteOneValueContainer(IMemoryManager memMgr, ref TW_CAPABILITY twCap, TValue value) where TValue : struct
- //{
- // IntPtr lockedPtr = IntPtr.Zero;
- // try
- // {
- // if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
+ ///
+ /// Creates a with a one-value container.
+ /// Caller will be responsible for ensuring memory is freed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static TW_CAPABILITY CreateOneValueCap(this CAP cap, IMemoryManager memMgr, TValue value) where TValue : struct
+ {
+ TW_CAPABILITY twCap = new() { Cap = cap, ConType = TWON.ONEVALUE };
- // TWTY itemType = GetItemType();
+ IntPtr lockedPtr = IntPtr.Zero;
+ try
+ {
+ //if (twcap.hContainer != IntPtr.Zero) memMgr.Free(ref twcap.hContainer);
- // // Allocate the container (go for worst case, which is TW_STR255)...
- // if (TwainPlatform.IsMacOSX)
- // {
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE_MACOSX)) + Marshal.SizeOf(default(TW_STR255))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ TWTY itemType = GetItemType();
- // TW_ONEVALUE_MACOSX twonevaluemacosx = default;
- // twonevaluemacosx.ItemType = (uint)itemType;
- // Marshal.StructureToPtr(twonevaluemacosx, lockedPtr, false);
+ // Allocate the container (go for worst case, which is TW_STR255)...
+ if (TwainPlatform.IsMacOSX)
+ {
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE_MACOSX)) + Marshal.SizeOf(default(TW_STR255))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
- // lockedPtr += Marshal.SizeOf(twonevaluemacosx);
- // }
- // else
- // {
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE)) + Marshal.SizeOf(default(TW_STR255))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ TW_ONEVALUE_MACOSX twonevaluemacosx = default;
+ twonevaluemacosx.ItemType = (uint)itemType;
+ Marshal.StructureToPtr(twonevaluemacosx, lockedPtr, false);
- // TW_ONEVALUE twonevalue = default;
- // twonevalue.ItemType = itemType;
- // Marshal.StructureToPtr(twonevalue, lockedPtr, false);
+ lockedPtr += Marshal.SizeOf(twonevaluemacosx);
+ }
+ else
+ {
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE)) + Marshal.SizeOf(default(TW_STR255))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
- // lockedPtr += Marshal.SizeOf(twonevalue);
- // }
+ TW_ONEVALUE twonevalue = default;
+ twonevalue.ItemType = itemType;
+ Marshal.StructureToPtr(twonevalue, lockedPtr, false);
- // WriteContainerData(lockedPtr, itemType, value, 0);
- // }
- // finally
- // {
- // if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
- // }
- //}
+ lockedPtr += Marshal.SizeOf(twonevalue);
+ }
- //public static void WriteArrayContainer(IMemoryManager memMgr, ref TW_CAPABILITY twCap, TValue[] values) where TValue : struct
- //{
- // IntPtr lockedPtr = IntPtr.Zero;
- // try
- // {
- // if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
+ WriteContainerData(lockedPtr, itemType, value, 0);
+ }
+ finally
+ {
+ if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
+ }
+ return twCap;
+ }
- // TWTY itemType = GetItemType();
+ ///
+ /// Creates a with multiple values in an array container.
+ /// Caller will be responsible for ensuring memory is freed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static TW_CAPABILITY CreateArrayCap(this CAP cap, IMemoryManager memMgr, params TValue[] values) where TValue : struct
+ {
+ if (values == null) throw new ArgumentNullException(nameof(values));
- // // Allocate the container (go for worst case, which is TW_STR255)...
- // if (TwainPlatform.IsMacOSX)
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ARRAY_MACOSX)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ TW_CAPABILITY twCap = new() { Cap = cap, ConType = TWON.ARRAY };
- // // Set the meta data...
- // TW_ARRAY_MACOSX twarraymacosx = default;
- // twarraymacosx.ItemType = (uint)itemType;
- // twarraymacosx.NumItems = (uint)values.Length;
- // Marshal.StructureToPtr(twarraymacosx, lockedPtr, false);
+ IntPtr lockedPtr = IntPtr.Zero;
+ try
+ {
+ //if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
- // // Get the pointer to the ItemList...
- // lockedPtr += Marshal.SizeOf(twarraymacosx);
- // }
- // else
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ARRAY)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ TWTY itemType = GetItemType();
- // // Set the meta data...
- // TW_ARRAY twarray = default;
- // twarray.ItemType = itemType;
- // twarray.NumItems = (uint)values.Length;
- // Marshal.StructureToPtr(twarray, lockedPtr, false);
+ // Allocate the container (go for worst case, which is TW_STR255)...
+ if (TwainPlatform.IsMacOSX)
+ {
+ // Allocate...
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ARRAY_MACOSX)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
- // // Get the pointer to the ItemList...
- // lockedPtr += Marshal.SizeOf(twarray);
- // }
+ // Set the meta data...
+ TW_ARRAY_MACOSX twarraymacosx = default;
+ twarraymacosx.ItemType = (uint)itemType;
+ twarraymacosx.NumItems = (uint)values.Length;
+ Marshal.StructureToPtr(twarraymacosx, lockedPtr, false);
- // // Set the ItemList...
- // for (var i = 0; i < values.Length; i++)
- // {
- // WriteContainerData(lockedPtr, itemType, values[i], i);
- // }
- // }
- // finally
- // {
- // if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
- // }
- //}
+ // Get the pointer to the ItemList...
+ lockedPtr += Marshal.SizeOf(twarraymacosx);
+ }
+ else
+ {
+ // Allocate...
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ARRAY)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
- //public static void WriteEnumContainer(IMemoryManager memMgr, ref TW_CAPABILITY twCap, Enumeration value) where TValue : struct
- //{
- // IntPtr lockedPtr = IntPtr.Zero;
- // try
- // {
- // if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
+ // Set the meta data...
+ TW_ARRAY twarray = default;
+ twarray.ItemType = itemType;
+ twarray.NumItems = (uint)values.Length;
+ Marshal.StructureToPtr(twarray, lockedPtr, false);
- // TWTY itemType = GetItemType();
+ // Get the pointer to the ItemList...
+ lockedPtr += Marshal.SizeOf(twarray);
+ }
- // // Allocate the container (go for worst case, which is TW_STR255)...
- // if (TwainPlatform.IsMacOSX)
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_MACOSX)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ // Set the ItemList...
+ for (var i = 0; i < values.Length; i++)
+ {
+ WriteContainerData(lockedPtr, itemType, values[i], i);
+ }
+ }
+ finally
+ {
+ if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
+ }
+ return twCap;
+ }
- // // 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);
+ ///
+ /// Creates a with multiple values in an enum container.
+ /// Caller will be responsible for ensuring memory is freed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static TW_CAPABILITY CreateEnumCap(this CAP cap, IMemoryManager memMgr, Enumeration value) where TValue : struct
+ {
+ if (value.Items == null) throw new ArgumentException("No items found in enumeration", nameof(value));
- // // Get the pointer to the ItemList...
- // lockedPtr += Marshal.SizeOf(twenumerationmacosx);
- // }
- // // Windows or the 2.4+ Linux DSM...
- // else if (TWAIN.GetPlatform() == Platform.WINDOWS ||
- // (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
- // ((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ TW_CAPABILITY twCap = new() { Cap = cap, ConType = TWON.ENUMERATION };
- // // 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);
+ IntPtr lockedPtr = IntPtr.Zero;
+ try
+ {
+ //if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
- // // Get the pointer to the ItemList...
- // lockedPtr += Marshal.SizeOf(twenumeration);
- // }
- // // The -2.3 Linux DSM...
- // else
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_LINUX64)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
+ TWTY itemType = GetItemType();
- // // 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);
+ // Allocate the container (go for worst case, which is TW_STR255)...
+ if (TwainPlatform.IsMacOSX)
+ {
+ // Allocate...
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_MACOSX)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
- // // Get the pointer to the ItemList...
- // lockedPtr += Marshal.SizeOf(twenumerationlinux64);
- // }
+ // 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);
- // // Set the ItemList...
- // for (var i = 0; i < value.Items.Length; i++)
- // {
- // WriteContainerData(lockedPtr, itemType, value.Items[i], i);
- // }
- // }
- // finally
- // {
- // if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
- // }
- //}
+ // Get the pointer to the ItemList...
+ lockedPtr += Marshal.SizeOf(twenumerationmacosx);
+ }
+ // Windows or the 2.4+ Linux DSM...
+ else
+ {
+ // Allocate...
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
- //public static void WriteRangeContainer(IMemoryManager memMgr, ref TW_CAPABILITY twCap, Range value) where TValue : struct
- //{
- // IntPtr lockedPtr = IntPtr.Zero;
- // try
- // {
- // if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref 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);
- // TWTY itemType = GetItemType();
+ // Get the pointer to the ItemList...
+ lockedPtr += Marshal.SizeOf(twenumeration);
+ }
+ // The -2.3 Linux DSM...
+ //else
+ //{
+ // // Allocate...
+ // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_LINUX64)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
+ // lockedPtr = memMgr.Lock(twCap.hContainer);
- // // Allocate the container (go for worst case, which is TW_STR255)...
- // if (TwainPlatform.IsMacOSX)
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_RANGE_MACOSX))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
- // }
- // // Windows or the 2.4+ Linux DSM...
- // else if (TWAIN.GetPlatform() == Platform.WINDOWS ||
- // (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm) ||
- // ((twain.m_blFoundLatestDsm || twain.m_blFoundLatestDsm64) && (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm)))
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_RANGE))));
- // lockedPtr = memMgr.Lock(twCap.hContainer);
- // }
- // // The -2.3 Linux DSM...
- // else
- // {
- // // Allocate...
- // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_RANGE_LINUX64))));
- // lockedPtr = memMgr.Lock(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);
- // // Set the Item...
- // WriteRangeValues(twain, lockedPtr, itemType, value);
- // }
- // finally
- // {
- // if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
- // }
- //}
+ // // Get the pointer to the ItemList...
+ // lockedPtr += Marshal.SizeOf(twenumerationlinux64);
+ //}
- //static void WriteRangeValues(IMemoryManager memMgr, IntPtr lockedPtr, TWTY itemType, Range value) where TValue : struct
- //{
- // // TODO: reduce this later
+ // Set the ItemList...
+ for (var i = 0; i < value.Items.Length; i++)
+ {
+ WriteContainerData(lockedPtr, itemType, value.Items[i], i);
+ }
+ }
+ finally
+ {
+ if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
+ }
+ return twCap;
+ }
- // TW_RANGE twrange = default;
- // TW_RANGE_MACOSX twrangemacosx = default;
- // TW_RANGE_LINUX64 twrangelinux64 = default;
+ ///
+ /// Creates a with multiple values in a range container.
+ /// Caller will be responsible for ensuring memory is freed.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static TW_CAPABILITY CreateRangeCap(this CAP cap, IMemoryManager memMgr, Range value) where TValue : struct
+ {
+ TW_CAPABILITY twCap = new() { Cap = cap, ConType = TWON.ENUMERATION };
- // switch (itemType)
- // {
- // default:
- // throw new NotSupportedException($"{itemType} is not supported for range.");
- // case TWTY.INT8:
- // if (TwainPlatform.IsMacOSX)
- // {
- // twrangemacosx.ItemType = (uint)itemType;
- // twrangemacosx.MinValue = (uint)Convert.ToSByte(value.MinValue);
- // twrangemacosx.MaxValue = (uint)Convert.ToSByte(value.MaxValue);
- // twrangemacosx.StepSize = (uint)Convert.ToSByte(value.StepSize);
- // twrangemacosx.DefaultValue = (uint)Convert.ToSByte(value.DefaultValue);
- // twrangemacosx.CurrentValue = (uint)Convert.ToSByte(value.CurrentValue);
- // Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
- // }
- // else if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
- // {
- // twrange.ItemType = itemType;
- // twrange.MinValue = (uint)Convert.ToSByte(value.MinValue);
- // twrange.MaxValue = (uint)Convert.ToSByte(value.MaxValue);
- // twrange.StepSize = (uint)Convert.ToSByte(value.StepSize);
- // twrange.DefaultValue = (uint)Convert.ToSByte(value.DefaultValue);
- // twrange.CurrentValue = (uint)Convert.ToSByte(value.CurrentValue);
- // Marshal.StructureToPtr(twrange, lockedPtr, false);
- // }
- // else
- // {
- // twrangelinux64.ItemType = itemType;
- // twrangelinux64.MinValue = (uint)Convert.ToSByte(value.MinValue);
- // twrangelinux64.MaxValue = (uint)Convert.ToSByte(value.MaxValue);
- // twrangelinux64.StepSize = (uint)Convert.ToSByte(value.StepSize);
- // twrangelinux64.DefaultValue = (uint)Convert.ToSByte(value.DefaultValue);
- // twrangelinux64.CurrentValue = (uint)Convert.ToSByte(value.CurrentValue);
- // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
- // }
- // break;
- // case TWTY.UINT8:
- // if (TwainPlatform.IsMacOSX)
- // {
- // twrangemacosx.ItemType = (uint)itemType;
- // twrangemacosx.MinValue = Convert.ToByte(value.MinValue);
- // twrangemacosx.MaxValue = Convert.ToByte(value.MaxValue);
- // twrangemacosx.StepSize = Convert.ToByte(value.StepSize);
- // twrangemacosx.DefaultValue = Convert.ToByte(value.DefaultValue);
- // twrangemacosx.CurrentValue = Convert.ToByte(value.CurrentValue);
- // Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
- // }
- // else if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
- // {
- // twrange.ItemType = itemType;
- // twrange.MinValue = Convert.ToByte(value.MinValue);
- // twrange.MaxValue = Convert.ToByte(value.MaxValue);
- // twrange.StepSize = Convert.ToByte(value.StepSize);
- // twrange.DefaultValue = Convert.ToByte(value.DefaultValue);
- // twrange.CurrentValue = Convert.ToByte(value.CurrentValue);
- // Marshal.StructureToPtr(twrange, lockedPtr, false);
- // }
- // else
- // {
- // twrangelinux64.ItemType = itemType;
- // twrangelinux64.MinValue = Convert.ToByte(value.MinValue);
- // twrangelinux64.MaxValue = Convert.ToByte(value.MaxValue);
- // twrangelinux64.StepSize = Convert.ToByte(value.StepSize);
- // twrangelinux64.DefaultValue = Convert.ToByte(value.DefaultValue);
- // twrangelinux64.CurrentValue = Convert.ToByte(value.CurrentValue);
- // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
- // }
- // break;
- // case TWTY.INT16:
- // if (TwainPlatform.IsMacOSX)
- // {
- // twrangemacosx.ItemType = (uint)itemType;
- // twrangemacosx.MinValue = (uint)Convert.ToInt16(value.MinValue);
- // twrangemacosx.MaxValue = (uint)Convert.ToInt16(value.MaxValue);
- // twrangemacosx.StepSize = (uint)Convert.ToInt16(value.StepSize);
- // twrangemacosx.DefaultValue = (uint)Convert.ToInt16(value.DefaultValue);
- // twrangemacosx.CurrentValue = (uint)Convert.ToInt16(value.CurrentValue);
- // Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
- // }
- // else if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
- // {
- // twrange.ItemType = itemType;
- // twrange.MinValue = (uint)Convert.ToInt16(value.MinValue);
- // twrange.MaxValue = (uint)Convert.ToInt16(value.MaxValue);
- // twrange.StepSize = (uint)Convert.ToInt16(value.StepSize);
- // twrange.DefaultValue = (uint)Convert.ToInt16(value.DefaultValue);
- // twrange.CurrentValue = (uint)Convert.ToInt16(value.CurrentValue);
- // Marshal.StructureToPtr(twrange, lockedPtr, false);
- // }
- // else
- // {
- // twrangelinux64.ItemType = itemType;
- // twrangelinux64.MinValue = (uint)Convert.ToInt16(value.MinValue);
- // twrangelinux64.MaxValue = (uint)Convert.ToInt16(value.MaxValue);
- // twrangelinux64.StepSize = (uint)Convert.ToInt16(value.StepSize);
- // twrangelinux64.DefaultValue = (uint)Convert.ToInt16(value.DefaultValue);
- // twrangelinux64.CurrentValue = (uint)Convert.ToInt16(value.CurrentValue);
- // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
- // }
- // break;
- // case TWTY.BOOL:
- // case TWTY.UINT16:
- // if (TwainPlatform.IsMacOSX)
- // {
- // twrangemacosx.ItemType = (uint)itemType;
- // twrangemacosx.MinValue = Convert.ToUInt16(value.MinValue);
- // twrangemacosx.MaxValue = Convert.ToUInt16(value.MaxValue);
- // twrangemacosx.StepSize = Convert.ToUInt16(value.StepSize);
- // twrangemacosx.DefaultValue = Convert.ToUInt16(value.DefaultValue);
- // twrangemacosx.CurrentValue = Convert.ToUInt16(value.CurrentValue);
- // Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
- // }
- // else if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
- // {
- // twrange.ItemType = itemType;
- // twrange.MinValue = Convert.ToUInt16(value.MinValue);
- // twrange.MaxValue = Convert.ToUInt16(value.MaxValue);
- // twrange.StepSize = Convert.ToUInt16(value.StepSize);
- // twrange.DefaultValue = Convert.ToUInt16(value.DefaultValue);
- // twrange.CurrentValue = Convert.ToUInt16(value.CurrentValue);
- // Marshal.StructureToPtr(twrange, lockedPtr, false);
- // }
- // else
- // {
- // twrangelinux64.ItemType = itemType;
- // twrangelinux64.MinValue = Convert.ToUInt16(value.MinValue);
- // twrangelinux64.MaxValue = Convert.ToUInt16(value.MaxValue);
- // twrangelinux64.StepSize = Convert.ToUInt16(value.StepSize);
- // twrangelinux64.DefaultValue = Convert.ToUInt16(value.DefaultValue);
- // twrangelinux64.CurrentValue = Convert.ToUInt16(value.CurrentValue);
- // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
- // }
- // break;
- // case TWTY.INT32:
- // if (TwainPlatform.IsMacOSX)
- // {
- // twrangemacosx.ItemType = (uint)itemType;
- // twrangemacosx.MinValue = (uint)Convert.ToInt32(value.MinValue);
- // twrangemacosx.MaxValue = (uint)Convert.ToInt32(value.MaxValue);
- // twrangemacosx.StepSize = (uint)Convert.ToInt32(value.StepSize);
- // twrangemacosx.DefaultValue = (uint)Convert.ToInt32(value.DefaultValue);
- // twrangemacosx.CurrentValue = (uint)Convert.ToInt32(value.CurrentValue);
- // Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
- // }
- // else if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
- // {
- // twrange.ItemType = itemType;
- // twrange.MinValue = (uint)Convert.ToInt32(value.MinValue);
- // twrange.MaxValue = (uint)Convert.ToInt32(value.MaxValue);
- // twrange.StepSize = (uint)Convert.ToInt32(value.StepSize);
- // twrange.DefaultValue = (uint)Convert.ToInt32(value.DefaultValue);
- // twrange.CurrentValue = (uint)Convert.ToInt32(value.CurrentValue);
- // Marshal.StructureToPtr(twrange, lockedPtr, false);
- // }
- // else
- // {
- // twrangelinux64.ItemType = itemType;
- // twrangelinux64.MinValue = (uint)Convert.ToInt32(value.MinValue);
- // twrangelinux64.MaxValue = (uint)Convert.ToInt32(value.MaxValue);
- // twrangelinux64.StepSize = (uint)Convert.ToInt32(value.StepSize);
- // twrangelinux64.DefaultValue = (uint)Convert.ToInt32(value.DefaultValue);
- // twrangelinux64.CurrentValue = (uint)Convert.ToInt32(value.CurrentValue);
- // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
- // }
- // break;
- // case TWTY.UINT32:
- // if (TwainPlatform.IsMacOSX)
- // {
- // twrangemacosx.ItemType = (uint)itemType;
- // twrangemacosx.MinValue = Convert.ToUInt32(value.MinValue);
- // twrangemacosx.MaxValue = Convert.ToUInt32(value.MaxValue);
- // twrangemacosx.StepSize = Convert.ToUInt32(value.StepSize);
- // twrangemacosx.DefaultValue = Convert.ToUInt32(value.DefaultValue);
- // twrangemacosx.CurrentValue = Convert.ToUInt32(value.CurrentValue);
- // Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
- // }
- // else if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
- // {
- // twrange.ItemType = itemType;
- // twrange.MinValue = Convert.ToUInt32(value.MinValue);
- // twrange.MaxValue = Convert.ToUInt32(value.MaxValue);
- // twrange.StepSize = Convert.ToUInt32(value.StepSize);
- // twrange.DefaultValue = Convert.ToUInt32(value.DefaultValue);
- // twrange.CurrentValue = Convert.ToUInt32(value.CurrentValue);
- // Marshal.StructureToPtr(twrange, lockedPtr, false);
- // }
- // else
- // {
- // twrangelinux64.ItemType = itemType;
- // twrangelinux64.MinValue = Convert.ToUInt32(value.MinValue);
- // twrangelinux64.MaxValue = Convert.ToUInt32(value.MaxValue);
- // twrangelinux64.StepSize = Convert.ToUInt32(value.StepSize);
- // twrangelinux64.DefaultValue = Convert.ToUInt32(value.DefaultValue);
- // twrangelinux64.CurrentValue = Convert.ToUInt32(value.CurrentValue);
- // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
- // }
- // break;
- // case TWTY.FIX32:
- // double min = Convert.ToDouble(value.MinValue);
- // double max = Convert.ToDouble(value.MaxValue);
- // double step = Convert.ToDouble(value.StepSize);
- // double def = Convert.ToDouble(value.DefaultValue);
- // double current = Convert.ToDouble(value.CurrentValue);
- // if (TwainPlatform.IsMacOSX)
- // {
- // TW_RANGE_FIX32_MACOSX twrangefix32macosx = default;
- // twrangefix32macosx.ItemType = (uint)itemType;
- // twrangefix32macosx.MinValue = new TW_FIX32(min);
- // twrangefix32macosx.MaxValue = new TW_FIX32(max);
- // twrangefix32macosx.StepSize = new TW_FIX32(step);
- // twrangefix32macosx.DefaultValue = new TW_FIX32(def);
- // twrangefix32macosx.CurrentValue = new TW_FIX32(current);
- // Marshal.StructureToPtr(twrangefix32macosx, lockedPtr, false);
- // }
- // else
- // {
- // TW_RANGE_FIX32 twrangefix32 = default;
- // twrangefix32.ItemType = itemType;
- // twrangefix32.MinValue = new TW_FIX32(min);
- // twrangefix32.MaxValue = new TW_FIX32(max);
- // twrangefix32.StepSize = new TW_FIX32(step);
- // twrangefix32.DefaultValue = new TW_FIX32(def);
- // twrangefix32.CurrentValue = new TW_FIX32(current);
- // Marshal.StructureToPtr(twrangefix32, lockedPtr, false);
- // }
- // break;
- // }
- //}
+ IntPtr lockedPtr = IntPtr.Zero;
+ try
+ {
+ //if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
- //static TWTY GetItemType() where TValue : struct
- //{
- // var type = typeof(TValue);
- // if (type == typeof(BoolType)) return TWTY.BOOL;
- // if (type == typeof(TW_FIX32)) return TWTY.FIX32;
- // if (type == typeof(TW_STR32)) return TWTY.STR32;
- // if (type == typeof(TW_STR64)) return TWTY.STR64;
- // if (type == typeof(TW_STR128)) return TWTY.STR128;
- // if (type == typeof(TW_STR255)) return TWTY.STR255;
- // if (type == typeof(TW_FRAME)) return TWTY.FRAME;
+ TWTY itemType = GetItemType();
- // if (type.IsEnum)
- // {
- // type = type.GetEnumUnderlyingType();
- // }
+ // Allocate the container (go for worst case, which is TW_STR255)...
+ if (TwainPlatform.IsMacOSX)
+ {
+ // Allocate...
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_RANGE_MACOSX))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
+ }
+ // Windows or the 2.4+ Linux DSM...
+ else
+ {
+ // Allocate...
+ twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_RANGE))));
+ lockedPtr = memMgr.Lock(twCap.hContainer);
+ }
+ //// The -2.3 Linux DSM...
+ //else
+ //{
+ // // Allocate...
+ // twCap.hContainer = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_RANGE_LINUX64))));
+ // lockedPtr = memMgr.Lock(twCap.hContainer);
+ //}
- // if (type == typeof(ushort)) return TWTY.UINT16;
- // if (type == typeof(short)) return TWTY.INT16;
- // if (type == typeof(uint)) return TWTY.UINT32;
- // if (type == typeof(int)) return TWTY.INT32;
- // if (type == typeof(byte)) return TWTY.UINT8;
- // if (type == typeof(sbyte)) return TWTY.INT8;
+ // Set the Item...
+ WriteRangeValues(memMgr, lockedPtr, itemType, value);
+ }
+ finally
+ {
+ if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
+ }
+ return twCap;
+ }
- // throw new NotSupportedException($"{type.Name} is not supported for writing.");
- //}
+ static void WriteRangeValues(IMemoryManager memMgr, IntPtr lockedPtr, TWTY itemType, Range value) where TValue : struct
+ {
+ // TODO: reduce this later
- /////
- ///// Writes single piece of value to the container pointer.
- /////
- /////
- ///// A locked pointer to the container's data pointer. If data is array this is the 0th item.
- ///// The twain type.
- /////
- ///// Index of the item if pointer is array.
- //static void WriteContainerData(IntPtr intptr, TWTY type, TValue value, int itemIndex) where TValue : struct
- //{
- // switch (type)
- // {
- // default:
- // throw new NotSupportedException($"Unsupported item type {type} for writing.");
- // // TODO: for small types needs to fill whole int32 before writing?
- // case TWTY.INT8:
- // intptr += 1 * itemIndex;
- // //int intval = Convert.ToSByte(value);
- // //Marshal.StructureToPtr(intval, intptr, false);
- // Marshal.StructureToPtr(Convert.ToSByte(value), intptr, false);
- // break;
- // case TWTY.UINT8:
- // intptr += 1 * itemIndex;
- // //uint uintval = Convert.ToByte(value);
- // //Marshal.StructureToPtr(uintval, intptr, false);
- // Marshal.StructureToPtr(Convert.ToByte(value), intptr, false);
- // break;
- // case TWTY.INT16:
- // intptr += 2 * itemIndex;
- // //intval = Convert.ToInt16(value);
- // //Marshal.StructureToPtr(intval, intptr, false);
- // Marshal.StructureToPtr(Convert.ToInt16(value), intptr, false);
- // break;
- // case TWTY.BOOL:
- // case TWTY.UINT16:
- // intptr += 2 * itemIndex;
- // //uintval = Convert.ToUInt16(value);
- // //Marshal.StructureToPtr(uintval, intptr, false);
- // 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(Convert.ToUInt32(value), intptr, false);
- // break;
- // case TWTY.FIX32:
- // intptr += 4 * itemIndex;
- // Marshal.StructureToPtr(value, intptr, false);
- // break;
- // case TWTY.FRAME:
- // intptr += 16 * itemIndex;
- // Marshal.StructureToPtr(value, intptr, false);
- // break;
- // case TWTY.STR32:
- // intptr += TW_STR32.Size * itemIndex;
- // Marshal.StructureToPtr(value, intptr, false);
- // break;
- // case TWTY.STR64:
- // intptr += TW_STR64.Size * itemIndex;
- // Marshal.StructureToPtr(value, intptr, false);
- // break;
- // case TWTY.STR128:
- // intptr += TW_STR128.Size * itemIndex;
- // Marshal.StructureToPtr(value, intptr, false);
- // break;
- // case TWTY.STR255:
- // intptr += TW_STR255.Size * itemIndex;
- // Marshal.StructureToPtr(value, intptr, false);
- // break;
- // }
- //}
+ TW_RANGE twrange = default;
+ TW_RANGE_MACOSX twrangemacosx = default;
+ //TW_RANGE_LINUX64 twrangelinux64 = default;
+
+ switch (itemType)
+ {
+ default:
+ throw new NotSupportedException($"{itemType} is not supported for range.");
+ case TWTY.INT8:
+ if (TwainPlatform.IsMacOSX)
+ {
+ twrangemacosx.ItemType = (uint)itemType;
+ twrangemacosx.MinValue = (uint)Convert.ToSByte(value.MinValue);
+ twrangemacosx.MaxValue = (uint)Convert.ToSByte(value.MaxValue);
+ twrangemacosx.StepSize = (uint)Convert.ToSByte(value.StepSize);
+ twrangemacosx.DefaultValue = (uint)Convert.ToSByte(value.DefaultValue);
+ twrangemacosx.CurrentValue = (uint)Convert.ToSByte(value.CurrentValue);
+ Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
+ }
+ else //if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
+ {
+ twrange.ItemType = itemType;
+ twrange.MinValue = (uint)Convert.ToSByte(value.MinValue);
+ twrange.MaxValue = (uint)Convert.ToSByte(value.MaxValue);
+ twrange.StepSize = (uint)Convert.ToSByte(value.StepSize);
+ twrange.DefaultValue = (uint)Convert.ToSByte(value.DefaultValue);
+ twrange.CurrentValue = (uint)Convert.ToSByte(value.CurrentValue);
+ Marshal.StructureToPtr(twrange, lockedPtr, false);
+ }
+ //else
+ //{
+ // twrangelinux64.ItemType = itemType;
+ // twrangelinux64.MinValue = (uint)Convert.ToSByte(value.MinValue);
+ // twrangelinux64.MaxValue = (uint)Convert.ToSByte(value.MaxValue);
+ // twrangelinux64.StepSize = (uint)Convert.ToSByte(value.StepSize);
+ // twrangelinux64.DefaultValue = (uint)Convert.ToSByte(value.DefaultValue);
+ // twrangelinux64.CurrentValue = (uint)Convert.ToSByte(value.CurrentValue);
+ // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
+ //}
+ break;
+ case TWTY.UINT8:
+ if (TwainPlatform.IsMacOSX)
+ {
+ twrangemacosx.ItemType = (uint)itemType;
+ twrangemacosx.MinValue = Convert.ToByte(value.MinValue);
+ twrangemacosx.MaxValue = Convert.ToByte(value.MaxValue);
+ twrangemacosx.StepSize = Convert.ToByte(value.StepSize);
+ twrangemacosx.DefaultValue = Convert.ToByte(value.DefaultValue);
+ twrangemacosx.CurrentValue = Convert.ToByte(value.CurrentValue);
+ Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
+ }
+ else //if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
+ {
+ twrange.ItemType = itemType;
+ twrange.MinValue = Convert.ToByte(value.MinValue);
+ twrange.MaxValue = Convert.ToByte(value.MaxValue);
+ twrange.StepSize = Convert.ToByte(value.StepSize);
+ twrange.DefaultValue = Convert.ToByte(value.DefaultValue);
+ twrange.CurrentValue = Convert.ToByte(value.CurrentValue);
+ Marshal.StructureToPtr(twrange, lockedPtr, false);
+ }
+ //else
+ //{
+ // twrangelinux64.ItemType = itemType;
+ // twrangelinux64.MinValue = Convert.ToByte(value.MinValue);
+ // twrangelinux64.MaxValue = Convert.ToByte(value.MaxValue);
+ // twrangelinux64.StepSize = Convert.ToByte(value.StepSize);
+ // twrangelinux64.DefaultValue = Convert.ToByte(value.DefaultValue);
+ // twrangelinux64.CurrentValue = Convert.ToByte(value.CurrentValue);
+ // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
+ //}
+ break;
+ case TWTY.INT16:
+ if (TwainPlatform.IsMacOSX)
+ {
+ twrangemacosx.ItemType = (uint)itemType;
+ twrangemacosx.MinValue = (uint)Convert.ToInt16(value.MinValue);
+ twrangemacosx.MaxValue = (uint)Convert.ToInt16(value.MaxValue);
+ twrangemacosx.StepSize = (uint)Convert.ToInt16(value.StepSize);
+ twrangemacosx.DefaultValue = (uint)Convert.ToInt16(value.DefaultValue);
+ twrangemacosx.CurrentValue = (uint)Convert.ToInt16(value.CurrentValue);
+ Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
+ }
+ else // if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
+ {
+ twrange.ItemType = itemType;
+ twrange.MinValue = (uint)Convert.ToInt16(value.MinValue);
+ twrange.MaxValue = (uint)Convert.ToInt16(value.MaxValue);
+ twrange.StepSize = (uint)Convert.ToInt16(value.StepSize);
+ twrange.DefaultValue = (uint)Convert.ToInt16(value.DefaultValue);
+ twrange.CurrentValue = (uint)Convert.ToInt16(value.CurrentValue);
+ Marshal.StructureToPtr(twrange, lockedPtr, false);
+ }
+ //else
+ //{
+ // twrangelinux64.ItemType = itemType;
+ // twrangelinux64.MinValue = (uint)Convert.ToInt16(value.MinValue);
+ // twrangelinux64.MaxValue = (uint)Convert.ToInt16(value.MaxValue);
+ // twrangelinux64.StepSize = (uint)Convert.ToInt16(value.StepSize);
+ // twrangelinux64.DefaultValue = (uint)Convert.ToInt16(value.DefaultValue);
+ // twrangelinux64.CurrentValue = (uint)Convert.ToInt16(value.CurrentValue);
+ // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
+ //}
+ break;
+ case TWTY.BOOL:
+ case TWTY.UINT16:
+ if (TwainPlatform.IsMacOSX)
+ {
+ twrangemacosx.ItemType = (uint)itemType;
+ twrangemacosx.MinValue = Convert.ToUInt16(value.MinValue);
+ twrangemacosx.MaxValue = Convert.ToUInt16(value.MaxValue);
+ twrangemacosx.StepSize = Convert.ToUInt16(value.StepSize);
+ twrangemacosx.DefaultValue = Convert.ToUInt16(value.DefaultValue);
+ twrangemacosx.CurrentValue = Convert.ToUInt16(value.CurrentValue);
+ Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
+ }
+ else //if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
+ {
+ twrange.ItemType = itemType;
+ twrange.MinValue = Convert.ToUInt16(value.MinValue);
+ twrange.MaxValue = Convert.ToUInt16(value.MaxValue);
+ twrange.StepSize = Convert.ToUInt16(value.StepSize);
+ twrange.DefaultValue = Convert.ToUInt16(value.DefaultValue);
+ twrange.CurrentValue = Convert.ToUInt16(value.CurrentValue);
+ Marshal.StructureToPtr(twrange, lockedPtr, false);
+ }
+ //else
+ //{
+ // twrangelinux64.ItemType = itemType;
+ // twrangelinux64.MinValue = Convert.ToUInt16(value.MinValue);
+ // twrangelinux64.MaxValue = Convert.ToUInt16(value.MaxValue);
+ // twrangelinux64.StepSize = Convert.ToUInt16(value.StepSize);
+ // twrangelinux64.DefaultValue = Convert.ToUInt16(value.DefaultValue);
+ // twrangelinux64.CurrentValue = Convert.ToUInt16(value.CurrentValue);
+ // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
+ //}
+ break;
+ case TWTY.INT32:
+ if (TwainPlatform.IsMacOSX)
+ {
+ twrangemacosx.ItemType = (uint)itemType;
+ twrangemacosx.MinValue = (uint)Convert.ToInt32(value.MinValue);
+ twrangemacosx.MaxValue = (uint)Convert.ToInt32(value.MaxValue);
+ twrangemacosx.StepSize = (uint)Convert.ToInt32(value.StepSize);
+ twrangemacosx.DefaultValue = (uint)Convert.ToInt32(value.DefaultValue);
+ twrangemacosx.CurrentValue = (uint)Convert.ToInt32(value.CurrentValue);
+ Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
+ }
+ else //if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
+ {
+ twrange.ItemType = itemType;
+ twrange.MinValue = (uint)Convert.ToInt32(value.MinValue);
+ twrange.MaxValue = (uint)Convert.ToInt32(value.MaxValue);
+ twrange.StepSize = (uint)Convert.ToInt32(value.StepSize);
+ twrange.DefaultValue = (uint)Convert.ToInt32(value.DefaultValue);
+ twrange.CurrentValue = (uint)Convert.ToInt32(value.CurrentValue);
+ Marshal.StructureToPtr(twrange, lockedPtr, false);
+ }
+ //else
+ //{
+ // twrangelinux64.ItemType = itemType;
+ // twrangelinux64.MinValue = (uint)Convert.ToInt32(value.MinValue);
+ // twrangelinux64.MaxValue = (uint)Convert.ToInt32(value.MaxValue);
+ // twrangelinux64.StepSize = (uint)Convert.ToInt32(value.StepSize);
+ // twrangelinux64.DefaultValue = (uint)Convert.ToInt32(value.DefaultValue);
+ // twrangelinux64.CurrentValue = (uint)Convert.ToInt32(value.CurrentValue);
+ // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
+ //}
+ break;
+ case TWTY.UINT32:
+ if (TwainPlatform.IsMacOSX)
+ {
+ twrangemacosx.ItemType = (uint)itemType;
+ twrangemacosx.MinValue = Convert.ToUInt32(value.MinValue);
+ twrangemacosx.MaxValue = Convert.ToUInt32(value.MaxValue);
+ twrangemacosx.StepSize = Convert.ToUInt32(value.StepSize);
+ twrangemacosx.DefaultValue = Convert.ToUInt32(value.DefaultValue);
+ twrangemacosx.CurrentValue = Convert.ToUInt32(value.CurrentValue);
+ Marshal.StructureToPtr(twrangemacosx, lockedPtr, false);
+ }
+ else //if ((twain.m_linuxdsm == TWAIN.LinuxDsm.Unknown) || (twain.m_linuxdsm == TWAIN.LinuxDsm.IsLatestDsm))
+ {
+ twrange.ItemType = itemType;
+ twrange.MinValue = Convert.ToUInt32(value.MinValue);
+ twrange.MaxValue = Convert.ToUInt32(value.MaxValue);
+ twrange.StepSize = Convert.ToUInt32(value.StepSize);
+ twrange.DefaultValue = Convert.ToUInt32(value.DefaultValue);
+ twrange.CurrentValue = Convert.ToUInt32(value.CurrentValue);
+ Marshal.StructureToPtr(twrange, lockedPtr, false);
+ }
+ //else
+ //{
+ // twrangelinux64.ItemType = itemType;
+ // twrangelinux64.MinValue = Convert.ToUInt32(value.MinValue);
+ // twrangelinux64.MaxValue = Convert.ToUInt32(value.MaxValue);
+ // twrangelinux64.StepSize = Convert.ToUInt32(value.StepSize);
+ // twrangelinux64.DefaultValue = Convert.ToUInt32(value.DefaultValue);
+ // twrangelinux64.CurrentValue = Convert.ToUInt32(value.CurrentValue);
+ // Marshal.StructureToPtr(twrangelinux64, lockedPtr, false);
+ //}
+ break;
+ case TWTY.FIX32:
+ double min = Convert.ToDouble(value.MinValue);
+ double max = Convert.ToDouble(value.MaxValue);
+ double step = Convert.ToDouble(value.StepSize);
+ double def = Convert.ToDouble(value.DefaultValue);
+ double current = Convert.ToDouble(value.CurrentValue);
+ if (TwainPlatform.IsMacOSX)
+ {
+ TW_RANGE_FIX32_MACOSX twrangefix32macosx = default;
+ twrangefix32macosx.ItemType = (uint)itemType;
+ twrangefix32macosx.MinValue = new TW_FIX32(min);
+ twrangefix32macosx.MaxValue = new TW_FIX32(max);
+ twrangefix32macosx.StepSize = new TW_FIX32(step);
+ twrangefix32macosx.DefaultValue = new TW_FIX32(def);
+ twrangefix32macosx.CurrentValue = new TW_FIX32(current);
+ Marshal.StructureToPtr(twrangefix32macosx, lockedPtr, false);
+ }
+ else
+ {
+ TW_RANGE_FIX32 twrangefix32 = default;
+ twrangefix32.ItemType = itemType;
+ twrangefix32.MinValue = new TW_FIX32(min);
+ twrangefix32.MaxValue = new TW_FIX32(max);
+ twrangefix32.StepSize = new TW_FIX32(step);
+ twrangefix32.DefaultValue = new TW_FIX32(def);
+ twrangefix32.CurrentValue = new TW_FIX32(current);
+ Marshal.StructureToPtr(twrangefix32, lockedPtr, false);
+ }
+ break;
+ }
+ }
+
+ static TWTY GetItemType() where TValue : struct
+ {
+ var type = typeof(TValue);
+ if (type == typeof(TW_BOOL)) return TWTY.BOOL;
+ if (type == typeof(TW_FIX32)) return TWTY.FIX32;
+ if (type == typeof(TW_STR32)) return TWTY.STR32;
+ if (type == typeof(TW_STR64)) return TWTY.STR64;
+ if (type == typeof(TW_STR128)) return TWTY.STR128;
+ if (type == typeof(TW_STR255)) return TWTY.STR255;
+ if (type == typeof(TW_FRAME)) return TWTY.FRAME;
+
+ if (type.IsEnum)
+ {
+ type = type.GetEnumUnderlyingType();
+ }
+
+ if (type == typeof(ushort)) return TWTY.UINT16;
+ if (type == typeof(short)) return TWTY.INT16;
+ if (type == typeof(uint)) return TWTY.UINT32;
+ if (type == typeof(int)) return TWTY.INT32;
+ if (type == typeof(byte)) return TWTY.UINT8;
+ if (type == typeof(sbyte)) return TWTY.INT8;
+
+ throw new NotSupportedException($"{type.Name} is not supported for writing.");
+ }
+
+ ///
+ /// Writes single piece of value to the container pointer.
+ ///
+ ///
+ /// A locked pointer to the container's data pointer. If data is array this is the 0th item.
+ /// The twain type.
+ ///
+ /// Index of the item if pointer is array.
+ static void WriteContainerData(IntPtr intptr, TWTY type, TValue value, int itemIndex) where TValue : struct
+ {
+ switch (type)
+ {
+ default:
+ throw new NotSupportedException($"Unsupported item type {type} for writing.");
+ // TODO: for small types needs to fill whole int32 before writing?
+ case TWTY.INT8:
+ intptr += 1 * itemIndex;
+ //int intval = Convert.ToSByte(value);
+ //Marshal.StructureToPtr(intval, intptr, false);
+ Marshal.StructureToPtr(Convert.ToSByte(value), intptr, false);
+ break;
+ case TWTY.UINT8:
+ intptr += 1 * itemIndex;
+ //uint uintval = Convert.ToByte(value);
+ //Marshal.StructureToPtr(uintval, intptr, false);
+ Marshal.StructureToPtr(Convert.ToByte(value), intptr, false);
+ break;
+ case TWTY.INT16:
+ intptr += 2 * itemIndex;
+ //intval = Convert.ToInt16(value);
+ //Marshal.StructureToPtr(intval, intptr, false);
+ Marshal.StructureToPtr(Convert.ToInt16(value), intptr, false);
+ break;
+ case TWTY.BOOL:
+ case TWTY.UINT16:
+ intptr += 2 * itemIndex;
+ //uintval = Convert.ToUInt16(value);
+ //Marshal.StructureToPtr(uintval, intptr, false);
+ 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(Convert.ToUInt32(value), intptr, false);
+ break;
+ case TWTY.FIX32:
+ intptr += 4 * itemIndex;
+ Marshal.StructureToPtr(value, intptr, false);
+ break;
+ case TWTY.FRAME:
+ intptr += 16 * itemIndex;
+ Marshal.StructureToPtr(value, intptr, false);
+ break;
+ case TWTY.STR32:
+ intptr += TW_STR32.Size * itemIndex;
+ Marshal.StructureToPtr(value, intptr, false);
+ break;
+ case TWTY.STR64:
+ intptr += TW_STR64.Size * itemIndex;
+ Marshal.StructureToPtr(value, intptr, false);
+ break;
+ case TWTY.STR128:
+ intptr += TW_STR128.Size * itemIndex;
+ Marshal.StructureToPtr(value, intptr, false);
+ break;
+ case TWTY.STR255:
+ intptr += TW_STR255.Size * itemIndex;
+ Marshal.StructureToPtr(value, intptr, false);
+ break;
+ }
+ }
}
}
diff --git a/src/NTwain/TwainAppSession.Caps.cs b/src/NTwain/TwainAppSession.Caps.cs
index 0bb6227..1153509 100644
--- a/src/NTwain/TwainAppSession.Caps.cs
+++ b/src/NTwain/TwainAppSession.Caps.cs
@@ -1,6 +1,5 @@
using NTwain.Data;
using NTwain.Triplets;
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -268,6 +267,9 @@ namespace NTwain
///
/// Sets a CAP's current value.
+ /// An easy way to create a value is to use the
+ ///
+ /// extension method (or the other container variants).
/// Memory of the value will be freed afterwards.
///
///
@@ -287,6 +289,9 @@ namespace NTwain
///
/// Sets a CAP's constraint values.
+ /// An easy way to create a value is to use the
+ ///
+ /// extension method (or the other container variants).
/// Memory of the value will be freed afterwards.
///
///