mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Start resurrecting old value reader/writer.
This commit is contained in:
parent
5678fd3e77
commit
9e59e2355d
@ -1,444 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TWAINWorkingGroup;
|
||||
using static TWAINWorkingGroup.TWAIN;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods for reading pointers into various things.
|
||||
/// </summary>
|
||||
public static class ValueReader
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads pointer as UTF8 string.
|
||||
/// </summary>
|
||||
/// <param name="intPtr">Pointer to string.</param>
|
||||
/// <param name="length">Number of bytes to read.</param>
|
||||
/// <returns></returns>
|
||||
public static unsafe string PtrToStringUTF8(IntPtr intPtr, int length)
|
||||
{
|
||||
if (intPtr == IntPtr.Zero) throw new ArgumentNullException(nameof(intPtr));
|
||||
if (length == 0) throw new ArgumentOutOfRangeException(nameof(length), length, "Length must be greater than 0.");
|
||||
|
||||
//// safe method with 2 copies
|
||||
//var bytes = new byte[length];
|
||||
//Marshal.Copy(intPtr, bytes, 0, length);
|
||||
//return Encoding.UTF8.GetString(bytes);
|
||||
|
||||
// unsafe method with 1 copy (does it work?)
|
||||
sbyte* bytes = (sbyte*)intPtr;
|
||||
var str = new string(bytes, 0, length, Encoding.UTF8);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// most of these are modified from the original TWAIN.CapabilityToCsv()
|
||||
|
||||
public static TValue ReadOneValueContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
{
|
||||
if (cap.hContainer == IntPtr.Zero) return default;
|
||||
|
||||
var lockedPtr = twain.DsmMemLock(cap.hContainer);
|
||||
|
||||
try
|
||||
{
|
||||
TWTY itemType;
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
|
||||
itemType = (TWTY)onevalue.ItemType;
|
||||
lockedPtr += Marshal.SizeOf(onevalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Crack the container...
|
||||
var onevalue = MarshalTo<TW_ONEVALUE>(lockedPtr);
|
||||
itemType = onevalue.ItemType;
|
||||
lockedPtr += Marshal.SizeOf(onevalue);
|
||||
}
|
||||
|
||||
return ReadContainerData<TValue>(lockedPtr, itemType, 0);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(cap.hContainer);
|
||||
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
|
||||
}
|
||||
}
|
||||
public static Enumeration<TValue> ReadEnumerationContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
{
|
||||
Enumeration<TValue> retVal = new Enumeration<TValue>();
|
||||
|
||||
if (cap.hContainer == IntPtr.Zero) return retVal;
|
||||
|
||||
var lockedPtr = twain.DsmMemLock(cap.hContainer);
|
||||
|
||||
try
|
||||
{
|
||||
TWTY itemType;
|
||||
int count = 0;
|
||||
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (TWAIN.GetPlatform() == 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 (TWAIN.GetPlatform() == 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
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(cap.hContainer);
|
||||
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
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;
|
||||
|
||||
var lockedPtr = twain.DsmMemLock(cap.hContainer);
|
||||
|
||||
try
|
||||
{
|
||||
TWTY itemType;
|
||||
uint count;
|
||||
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var twarraymacosx = MarshalTo<TW_ARRAY_MACOSX>(lockedPtr);
|
||||
itemType = (TWTY)twarraymacosx.ItemType;
|
||||
count = twarraymacosx.NumItems;
|
||||
lockedPtr += Marshal.SizeOf(twarraymacosx);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Crack the container...
|
||||
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++)
|
||||
{
|
||||
arr[i] = ReadContainerData<TValue>(lockedPtr, itemType, i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(cap.hContainer);
|
||||
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
|
||||
}
|
||||
}
|
||||
public static Range<TValue> ReadRangeContainer<TValue>(TWAIN twain, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
{
|
||||
var retVal = new Range<TValue>();
|
||||
|
||||
if (cap.hContainer == IntPtr.Zero) return retVal;
|
||||
|
||||
var lockedPtr = twain.DsmMemLock(cap.hContainer);
|
||||
|
||||
try
|
||||
{
|
||||
TW_RANGE twrange = default;
|
||||
TW_RANGE_FIX32 twrangefix32 = default;
|
||||
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
var twrangemacosx = MarshalTo<TW_RANGE_MACOSX>(lockedPtr);
|
||||
var twrangefix32macosx = MarshalTo<TW_RANGE_FIX32_MACOSX>(lockedPtr);
|
||||
twrange.ItemType = (TWTY)twrangemacosx.ItemType;
|
||||
twrange.MinValue = twrangemacosx.MinValue;
|
||||
twrange.MaxValue = twrangemacosx.MaxValue;
|
||||
twrange.StepSize = twrangemacosx.StepSize;
|
||||
twrange.DefaultValue = twrangemacosx.DefaultValue;
|
||||
twrange.CurrentValue = twrangemacosx.CurrentValue;
|
||||
twrangefix32.ItemType = (TWTY)twrangefix32macosx.ItemType;
|
||||
twrangefix32.MinValue = twrangefix32macosx.MinValue;
|
||||
twrangefix32.MaxValue = twrangefix32macosx.MaxValue;
|
||||
twrangefix32.StepSize = twrangefix32macosx.StepSize;
|
||||
twrangefix32.DefaultValue = twrangefix32macosx.DefaultValue;
|
||||
twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue;
|
||||
}
|
||||
// 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)))
|
||||
{
|
||||
twrange = MarshalTo<TW_RANGE>(lockedPtr);
|
||||
twrangefix32 = MarshalTo<TW_RANGE_FIX32>(lockedPtr);
|
||||
}
|
||||
// The -2.3 Linux DSM...
|
||||
else
|
||||
{
|
||||
var twrangelinux64 = MarshalTo<TW_RANGE_LINUX64>(lockedPtr);
|
||||
var twrangefix32macosx = MarshalTo<TW_RANGE_FIX32_MACOSX>(lockedPtr);
|
||||
twrange.ItemType = twrangelinux64.ItemType;
|
||||
twrange.MinValue = (uint)twrangelinux64.MinValue;
|
||||
twrange.MaxValue = (uint)twrangelinux64.MaxValue;
|
||||
twrange.StepSize = (uint)twrangelinux64.StepSize;
|
||||
twrange.DefaultValue = (uint)twrangelinux64.DefaultValue;
|
||||
twrange.CurrentValue = (uint)twrangelinux64.CurrentValue;
|
||||
twrangefix32.ItemType = (TWTY)twrangefix32macosx.ItemType;
|
||||
twrangefix32.MinValue = twrangefix32macosx.MinValue;
|
||||
twrangefix32.MaxValue = twrangefix32macosx.MaxValue;
|
||||
twrangefix32.StepSize = twrangefix32macosx.StepSize;
|
||||
twrangefix32.DefaultValue = twrangefix32macosx.DefaultValue;
|
||||
twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue;
|
||||
}
|
||||
|
||||
switch (twrange.ItemType)
|
||||
{
|
||||
// use dynamic since I know they fit the type.
|
||||
case TWTY.FIX32:
|
||||
retVal.MinValue = (dynamic)twrangefix32.MinValue;
|
||||
retVal.MaxValue = (dynamic)twrangefix32.MaxValue;
|
||||
retVal.StepSize = (dynamic)twrangefix32.StepSize;
|
||||
retVal.CurrentValue = (dynamic)twrangefix32.CurrentValue;
|
||||
retVal.DefaultValue = (dynamic)twrangefix32.DefaultValue;
|
||||
break;
|
||||
case TWTY.INT8:
|
||||
case TWTY.UINT8:
|
||||
case TWTY.INT16:
|
||||
case TWTY.BOOL:
|
||||
case TWTY.UINT16:
|
||||
case TWTY.INT32:
|
||||
case TWTY.UINT32:
|
||||
retVal.MinValue = (dynamic)twrange.MinValue;
|
||||
retVal.MaxValue = (dynamic)twrange.MaxValue;
|
||||
retVal.StepSize = (dynamic)twrange.StepSize;
|
||||
retVal.CurrentValue = (dynamic)twrange.CurrentValue;
|
||||
retVal.DefaultValue = (dynamic)twrange.DefaultValue;
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException($"The value type {twrange.ItemType} is not supported as range.");
|
||||
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(cap.hContainer);
|
||||
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read the one value of a cap as string. Only STR* and HANDLE types are supported.
|
||||
/// </summary>
|
||||
/// <param name="twain"></param>
|
||||
/// <param name="cap"></param>
|
||||
/// <param name="freeMemory"></param>
|
||||
/// <returns></returns>
|
||||
public static string ReadOneValueContainerString(TWAIN twain, TW_CAPABILITY cap, bool freeMemory = true)
|
||||
{
|
||||
if (cap.hContainer == IntPtr.Zero) return null;
|
||||
|
||||
var lockedPtr = twain.DsmMemLock(cap.hContainer);
|
||||
|
||||
try
|
||||
{
|
||||
if (cap.ConType == TWON.ONEVALUE)
|
||||
{
|
||||
TWTY itemType;
|
||||
// Mac has a level of indirection and a different structure (ick)...
|
||||
if (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
// Crack the container...
|
||||
var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
|
||||
itemType = (TWTY)onevalue.ItemType;
|
||||
lockedPtr += Marshal.SizeOf(onevalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Crack the container...
|
||||
var onevalue = MarshalTo<TW_ONEVALUE>(lockedPtr);
|
||||
itemType = onevalue.ItemType;
|
||||
lockedPtr += Marshal.SizeOf(onevalue);
|
||||
}
|
||||
|
||||
switch (itemType)
|
||||
{
|
||||
case TWTY.STR32:
|
||||
return MarshalTo<TW_STR32>(lockedPtr).ToString();
|
||||
case TWTY.STR64:
|
||||
return MarshalTo<TW_STR64>(lockedPtr).ToString();
|
||||
case TWTY.STR128:
|
||||
return MarshalTo<TW_STR128>(lockedPtr).ToString();
|
||||
case TWTY.STR255:
|
||||
return MarshalTo<TW_STR255>(lockedPtr).ToString();
|
||||
case TWTY.HANDLE:
|
||||
// null-terminated and encoded string.
|
||||
// good chance this ain't right.
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
byte read = Marshal.ReadByte(lockedPtr);
|
||||
while (read != 0)
|
||||
{
|
||||
stream.WriteByte(read);
|
||||
read = Marshal.ReadByte(lockedPtr);
|
||||
lockedPtr += 1;
|
||||
}
|
||||
// which one?
|
||||
return Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, stream.ToArray()));
|
||||
//return Language.GetEncoding().GetString(stream.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(cap.hContainer);
|
||||
if (freeMemory) twain.DsmMemFree(ref cap.hContainer);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Read the container pointer content.
|
||||
/// </summary>
|
||||
/// <param name="intptr">A locked pointer to the container's data pointer. If data is array this is the 0th item.</param>
|
||||
/// <param name="type">The twain type.</param>
|
||||
/// <param name="itemIndex">Index of the item if pointer is array.</param>
|
||||
/// <returns></returns>
|
||||
static TValue ReadContainerData<TValue>(IntPtr intptr, TWTY type, int itemIndex) where TValue : struct
|
||||
{
|
||||
var isEnum = typeof(TValue).IsEnum;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
default:
|
||||
throw new NotSupportedException($"Unsupported item type {type} for reading.");
|
||||
// TODO: verify if needs to read int32 for small types
|
||||
case TWTY.INT8:
|
||||
intptr += 1 * itemIndex;
|
||||
if (isEnum)
|
||||
{
|
||||
return NumericToEnum<sbyte, TValue>(MarshalTo<sbyte>(intptr));
|
||||
}
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.UINT8:
|
||||
intptr += 1 * itemIndex;
|
||||
if (isEnum)
|
||||
{
|
||||
return NumericToEnum<byte, TValue>(MarshalTo<byte>(intptr));
|
||||
}
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.INT16:
|
||||
intptr += 2 * itemIndex;
|
||||
if (isEnum)
|
||||
{
|
||||
return NumericToEnum<short, TValue>(MarshalTo<short>(intptr));
|
||||
}
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.BOOL:
|
||||
case TWTY.UINT16:
|
||||
intptr += 2 * itemIndex;
|
||||
if (isEnum)
|
||||
{
|
||||
return NumericToEnum<ushort, TValue>(MarshalTo<ushort>(intptr));
|
||||
}
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.INT32:
|
||||
intptr += 4 * itemIndex;
|
||||
if (isEnum)
|
||||
{
|
||||
return NumericToEnum<int, TValue>(MarshalTo<int>(intptr));
|
||||
}
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.UINT32:
|
||||
intptr += 4 * itemIndex;
|
||||
if (isEnum)
|
||||
{
|
||||
return NumericToEnum<uint, TValue>(MarshalTo<uint>(intptr));
|
||||
}
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.FIX32:
|
||||
intptr += 4 * itemIndex;
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.FRAME:
|
||||
intptr += 16 * itemIndex;
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.STR32:
|
||||
intptr += TW_STR32.Size * itemIndex;
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.STR64:
|
||||
intptr += TW_STR64.Size * itemIndex;
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.STR128:
|
||||
intptr += TW_STR128.Size * itemIndex;
|
||||
return MarshalTo<TValue>(intptr);
|
||||
case TWTY.STR255:
|
||||
intptr += TW_STR255.Size * itemIndex;
|
||||
return MarshalTo<TValue>(intptr);
|
||||
}
|
||||
}
|
||||
|
||||
static TEnum NumericToEnum<TNumber, TEnum>(TNumber num) where TEnum : struct
|
||||
{
|
||||
// some caps returns a data type that's not the underlying datatype for the enum
|
||||
// so best way is to ToString() it and parse it as the enum type.
|
||||
var str = num.ToString();
|
||||
|
||||
if (Enum.TryParse(str, out TEnum parsed))
|
||||
{
|
||||
return parsed;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
static T MarshalTo<T>(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||
}
|
||||
}
|
@ -1,617 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using TWAINWorkingGroup;
|
||||
using static TWAINWorkingGroup.TWAIN;
|
||||
|
||||
namespace NTwain
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods for writing vairous things to pointers.
|
||||
/// </summary>
|
||||
public static class ValueWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Allocates and copies the string value into a pointer in UTF8 that's null-terminated.
|
||||
/// </summary>
|
||||
/// <param name="twain"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="length">Actual number of bytes used to encode the string without the null.</param>
|
||||
/// <returns></returns>
|
||||
public static unsafe IntPtr StringToPtrUTF8(TWAIN twain, string value, out int length)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
length = 0;
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var utf8 = Encoding.UTF8;
|
||||
length = utf8.GetByteCount(value);
|
||||
|
||||
var ptr = twain.DsmMemAlloc((uint)length + 1); // +1 for null-terminated
|
||||
|
||||
// TODO: test if this works
|
||||
int written;
|
||||
byte* bytes = (byte*)ptr;
|
||||
try
|
||||
{
|
||||
// fixed for managed pointer
|
||||
fixed (char* firstChar = value)
|
||||
{
|
||||
written = Encoding.UTF8.GetBytes(firstChar, value.Length, bytes, length);
|
||||
}
|
||||
|
||||
bytes[written] = 0;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// just in case
|
||||
if (ptr != IntPtr.Zero) twain.DsmMemFree(ref ptr);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// most of these are modified from the original TWAIN.CsvToCapability()
|
||||
|
||||
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 (TWAIN.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;
|
||||
twonevaluemacosx.ItemType = (uint)itemType;
|
||||
Marshal.StructureToPtr(twonevaluemacosx, lockedPtr, false);
|
||||
|
||||
lockedPtr += Marshal.SizeOf(twonevaluemacosx);
|
||||
}
|
||||
else
|
||||
{
|
||||
twCap.hContainer = twain.DsmMemAlloc((uint)(Marshal.SizeOf(default(TW_ONEVALUE)) + Marshal.SizeOf(default(TW_STR255))));
|
||||
lockedPtr = twain.DsmMemLock(twCap.hContainer);
|
||||
|
||||
TW_ONEVALUE twonevalue = default;
|
||||
twonevalue.ItemType = itemType;
|
||||
Marshal.StructureToPtr(twonevalue, lockedPtr, false);
|
||||
|
||||
lockedPtr += Marshal.SizeOf(twonevalue);
|
||||
}
|
||||
|
||||
WriteContainerData(lockedPtr, itemType, value, 0);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(twCap.hContainer);
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteArrayContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, TValue[] values) 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 (TWAIN.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 WriteEnumContainer<TValue>(TWAIN twain, ref TW_CAPABILITY twCap, Enumeration<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 (TWAIN.GetPlatform() == 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 (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 = 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);
|
||||
}
|
||||
}
|
||||
|
||||
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>();
|
||||
|
||||
// Allocate the container (go for worst case, which is TW_STR255)...
|
||||
if (TWAIN.GetPlatform() == 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 (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 = 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(twain, lockedPtr, itemType, value);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (lockedPtr != IntPtr.Zero) twain.DsmMemUnlock(twCap.hContainer);
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteRangeValues<TValue>(TWAIN twain, IntPtr lockedPtr, TWTY itemType, Range<TValue> value) where TValue : struct
|
||||
{
|
||||
// TODO: reduce this later
|
||||
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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 (TWAIN.GetPlatform() == Platform.MACOSX)
|
||||
{
|
||||
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<TValue>() 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;
|
||||
|
||||
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.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes single piece of value to the container pointer.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="intptr">A locked pointer to the container's data pointer. If data is array this is the 0th item.</param>
|
||||
/// <param name="type">The twain type.</param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="itemIndex">Index of the item if pointer is array.</param>
|
||||
static void WriteContainerData<TValue>(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -710,30 +710,7 @@ namespace NTwain.Data
|
||||
string? val = null;
|
||||
if (UTF8string != IntPtr.Zero && Size > 0)
|
||||
{
|
||||
var locked = mgr.Lock(UTF8string);
|
||||
if (locked != IntPtr.Zero)
|
||||
{
|
||||
// does this work? who knows.
|
||||
try
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
// safe method but with 2 copies (arr and parsed string)
|
||||
var bytes = new byte[Size];
|
||||
Marshal.Copy(locked, bytes, 0, bytes.Length);
|
||||
val = Encoding.UTF8.GetString(bytes);
|
||||
|
||||
//// unsafe method with 1 copy (does it work?)
|
||||
//sbyte* bytes = (sbyte*)locked;
|
||||
//val = new string(bytes, 0, length, Encoding.UTF8);
|
||||
#else
|
||||
val = Marshal.PtrToStringUTF8(locked, (int)Size);
|
||||
#endif
|
||||
}
|
||||
finally
|
||||
{
|
||||
mgr.Unlock(UTF8string);
|
||||
}
|
||||
}
|
||||
val = ValueReader.PtrToStringUTF8(mgr, UTF8string, (int)Size);
|
||||
}
|
||||
if (freeMemory) Free(mgr);
|
||||
return val;
|
||||
|
454
src/NTwain/Data/ValueReader.cs
Normal file
454
src/NTwain/Data/ValueReader.cs
Normal file
@ -0,0 +1,454 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace NTwain.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods for reading pointers into various things.
|
||||
/// </summary>
|
||||
static class ValueReader
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads pointer as UTF8 string.
|
||||
/// </summary>
|
||||
/// <param name="data">Pointer to string.</param>
|
||||
/// <param name="length">Number of bytes to read.</param>
|
||||
/// <returns></returns>
|
||||
public static string? PtrToStringUTF8(IMemoryManager memMgr, IntPtr data, int length)
|
||||
{
|
||||
string? val = null;
|
||||
var locked = memMgr.Lock(data);
|
||||
if (locked != IntPtr.Zero)
|
||||
{
|
||||
// does this work? who knows.
|
||||
try
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
// safe method but with 2 copies (arr and parsed string)
|
||||
var bytes = new byte[length];
|
||||
Marshal.Copy(locked, bytes, 0, bytes.Length);
|
||||
val = Encoding.UTF8.GetString(bytes);
|
||||
|
||||
//// unsafe method with 1 copy (does it work?)
|
||||
//sbyte* bytes = (sbyte*)locked;
|
||||
//val = new string(bytes, 0, length, Encoding.UTF8);
|
||||
#else
|
||||
val = Marshal.PtrToStringUTF8(locked, length);
|
||||
#endif
|
||||
}
|
||||
finally
|
||||
{
|
||||
memMgr.Unlock(data);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// most of these are modified from the original TWAIN.CapabilityToCsv()
|
||||
|
||||
//public static TValue ReadOneValueContainer<TValue>(IMemoryManager memMgr, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
//{
|
||||
// if (cap.hContainer == IntPtr.Zero) return default;
|
||||
|
||||
// var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
// try
|
||||
// {
|
||||
// TWTY itemType;
|
||||
// // Mac has a level of indirection and a different structure (ick)...
|
||||
// if (TwainPlatform.IsMacOSX)
|
||||
// {
|
||||
// // Crack the container...
|
||||
// var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
|
||||
// itemType = (TWTY)onevalue.ItemType;
|
||||
// lockedPtr += Marshal.SizeOf(onevalue);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Crack the container...
|
||||
// var onevalue = MarshalTo<TW_ONEVALUE>(lockedPtr);
|
||||
// itemType = onevalue.ItemType;
|
||||
// lockedPtr += Marshal.SizeOf(onevalue);
|
||||
// }
|
||||
|
||||
// return ReadContainerData<TValue>(lockedPtr, itemType, 0);
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||
// if (freeMemory) memMgr.Free(ref cap.hContainer);
|
||||
// }
|
||||
//}
|
||||
//public static Enumeration<TValue> ReadEnumerationContainer<TValue>(IMemoryManager memMgr, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
//{
|
||||
// Enumeration<TValue> retVal = new Enumeration<TValue>();
|
||||
|
||||
// if (cap.hContainer == IntPtr.Zero) return retVal;
|
||||
|
||||
// var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
// try
|
||||
// {
|
||||
// TWTY itemType;
|
||||
// int count = 0;
|
||||
|
||||
// // Mac has a level of indirection and a different structure (ick)...
|
||||
// if (TwainPlatform.IsMacOSX)
|
||||
// {
|
||||
// // 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 (TWAIN.GetPlatform() == 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
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||
// if (freeMemory) memMgr.Free(ref cap.hContainer);
|
||||
// }
|
||||
// return retVal;
|
||||
//}
|
||||
//public static IList<TValue> ReadArrayContainer<TValue>(IMemoryManager memMgr, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
//{
|
||||
// if (cap.hContainer == IntPtr.Zero) return EmptyArray<TValue>.Value;
|
||||
|
||||
// var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
// try
|
||||
// {
|
||||
// TWTY itemType;
|
||||
// uint count;
|
||||
|
||||
// // Mac has a level of indirection and a different structure (ick)...
|
||||
// if (TwainPlatform.IsMacOSX)
|
||||
// {
|
||||
// // Crack the container...
|
||||
// var twarraymacosx = MarshalTo<TW_ARRAY_MACOSX>(lockedPtr);
|
||||
// itemType = (TWTY)twarraymacosx.ItemType;
|
||||
// count = twarraymacosx.NumItems;
|
||||
// lockedPtr += Marshal.SizeOf(twarraymacosx);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Crack the container...
|
||||
// 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++)
|
||||
// {
|
||||
// arr[i] = ReadContainerData<TValue>(lockedPtr, itemType, i);
|
||||
// }
|
||||
// return arr;
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||
// if (freeMemory) memMgr.Free(ref cap.hContainer);
|
||||
// }
|
||||
//}
|
||||
//public static Range<TValue> ReadRangeContainer<TValue>(IMemoryManager memMgr, ref TW_CAPABILITY cap, bool freeMemory = true) where TValue : struct
|
||||
//{
|
||||
// var retVal = new Range<TValue>();
|
||||
|
||||
// if (cap.hContainer == IntPtr.Zero) return retVal;
|
||||
|
||||
// var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
// try
|
||||
// {
|
||||
// TW_RANGE twrange = default;
|
||||
// TW_RANGE_FIX32 twrangefix32 = default;
|
||||
|
||||
// // Mac has a level of indirection and a different structure (ick)...
|
||||
// if (TwainPlatform.IsMacOSX)
|
||||
// {
|
||||
// var twrangemacosx = MarshalTo<TW_RANGE_MACOSX>(lockedPtr);
|
||||
// var twrangefix32macosx = MarshalTo<TW_RANGE_FIX32_MACOSX>(lockedPtr);
|
||||
// twrange.ItemType = (TWTY)twrangemacosx.ItemType;
|
||||
// twrange.MinValue = twrangemacosx.MinValue;
|
||||
// twrange.MaxValue = twrangemacosx.MaxValue;
|
||||
// twrange.StepSize = twrangemacosx.StepSize;
|
||||
// twrange.DefaultValue = twrangemacosx.DefaultValue;
|
||||
// twrange.CurrentValue = twrangemacosx.CurrentValue;
|
||||
// twrangefix32.ItemType = (TWTY)twrangefix32macosx.ItemType;
|
||||
// twrangefix32.MinValue = twrangefix32macosx.MinValue;
|
||||
// twrangefix32.MaxValue = twrangefix32macosx.MaxValue;
|
||||
// twrangefix32.StepSize = twrangefix32macosx.StepSize;
|
||||
// twrangefix32.DefaultValue = twrangefix32macosx.DefaultValue;
|
||||
// twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue;
|
||||
// }
|
||||
// // 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)))
|
||||
// {
|
||||
// twrange = MarshalTo<TW_RANGE>(lockedPtr);
|
||||
// twrangefix32 = MarshalTo<TW_RANGE_FIX32>(lockedPtr);
|
||||
// }
|
||||
// // The -2.3 Linux DSM...
|
||||
// else
|
||||
// {
|
||||
// var twrangelinux64 = MarshalTo<TW_RANGE_LINUX64>(lockedPtr);
|
||||
// var twrangefix32macosx = MarshalTo<TW_RANGE_FIX32_MACOSX>(lockedPtr);
|
||||
// twrange.ItemType = twrangelinux64.ItemType;
|
||||
// twrange.MinValue = (uint)twrangelinux64.MinValue;
|
||||
// twrange.MaxValue = (uint)twrangelinux64.MaxValue;
|
||||
// twrange.StepSize = (uint)twrangelinux64.StepSize;
|
||||
// twrange.DefaultValue = (uint)twrangelinux64.DefaultValue;
|
||||
// twrange.CurrentValue = (uint)twrangelinux64.CurrentValue;
|
||||
// twrangefix32.ItemType = (TWTY)twrangefix32macosx.ItemType;
|
||||
// twrangefix32.MinValue = twrangefix32macosx.MinValue;
|
||||
// twrangefix32.MaxValue = twrangefix32macosx.MaxValue;
|
||||
// twrangefix32.StepSize = twrangefix32macosx.StepSize;
|
||||
// twrangefix32.DefaultValue = twrangefix32macosx.DefaultValue;
|
||||
// twrangefix32.CurrentValue = twrangefix32macosx.CurrentValue;
|
||||
// }
|
||||
|
||||
// switch (twrange.ItemType)
|
||||
// {
|
||||
// // use dynamic since I know they fit the type.
|
||||
// case TWTY.FIX32:
|
||||
// retVal.MinValue = (dynamic)twrangefix32.MinValue;
|
||||
// retVal.MaxValue = (dynamic)twrangefix32.MaxValue;
|
||||
// retVal.StepSize = (dynamic)twrangefix32.StepSize;
|
||||
// retVal.CurrentValue = (dynamic)twrangefix32.CurrentValue;
|
||||
// retVal.DefaultValue = (dynamic)twrangefix32.DefaultValue;
|
||||
// break;
|
||||
// case TWTY.INT8:
|
||||
// case TWTY.UINT8:
|
||||
// case TWTY.INT16:
|
||||
// case TWTY.BOOL:
|
||||
// case TWTY.UINT16:
|
||||
// case TWTY.INT32:
|
||||
// case TWTY.UINT32:
|
||||
// retVal.MinValue = (dynamic)twrange.MinValue;
|
||||
// retVal.MaxValue = (dynamic)twrange.MaxValue;
|
||||
// retVal.StepSize = (dynamic)twrange.StepSize;
|
||||
// retVal.CurrentValue = (dynamic)twrange.CurrentValue;
|
||||
// retVal.DefaultValue = (dynamic)twrange.DefaultValue;
|
||||
// break;
|
||||
// default:
|
||||
// throw new NotSupportedException($"The value type {twrange.ItemType} is not supported as range.");
|
||||
|
||||
// }
|
||||
// return retVal;
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||
// if (freeMemory) memMgr.Free(ref cap.hContainer);
|
||||
// }
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Read the one value of a cap as string. Only STR* and HANDLE types are supported.
|
||||
///// </summary>
|
||||
///// <param name="twain"></param>
|
||||
///// <param name="cap"></param>
|
||||
///// <param name="freeMemory"></param>
|
||||
///// <returns></returns>
|
||||
//public static string ReadOneValueContainerString(IMemoryManager memMgr, TW_CAPABILITY cap, bool freeMemory = true)
|
||||
//{
|
||||
// if (cap.hContainer == IntPtr.Zero) return null;
|
||||
|
||||
// var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||
|
||||
// try
|
||||
// {
|
||||
// if (cap.ConType == TWON.ONEVALUE)
|
||||
// {
|
||||
// TWTY itemType;
|
||||
// // Mac has a level of indirection and a different structure (ick)...
|
||||
// if (TwainPlatform.IsMacOSX)
|
||||
// {
|
||||
// // Crack the container...
|
||||
// var onevalue = MarshalTo<TW_ONEVALUE_MACOSX>(lockedPtr);
|
||||
// itemType = (TWTY)onevalue.ItemType;
|
||||
// lockedPtr += Marshal.SizeOf(onevalue);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Crack the container...
|
||||
// var onevalue = MarshalTo<TW_ONEVALUE>(lockedPtr);
|
||||
// itemType = onevalue.ItemType;
|
||||
// lockedPtr += Marshal.SizeOf(onevalue);
|
||||
// }
|
||||
|
||||
// switch (itemType)
|
||||
// {
|
||||
// case TWTY.STR32:
|
||||
// return MarshalTo<TW_STR32>(lockedPtr).ToString();
|
||||
// case TWTY.STR64:
|
||||
// return MarshalTo<TW_STR64>(lockedPtr).ToString();
|
||||
// case TWTY.STR128:
|
||||
// return MarshalTo<TW_STR128>(lockedPtr).ToString();
|
||||
// case TWTY.STR255:
|
||||
// return MarshalTo<TW_STR255>(lockedPtr).ToString();
|
||||
// case TWTY.HANDLE:
|
||||
// // null-terminated and encoded string.
|
||||
// // good chance this ain't right.
|
||||
// using (var stream = new MemoryStream())
|
||||
// {
|
||||
// byte read = Marshal.ReadByte(lockedPtr);
|
||||
// while (read != 0)
|
||||
// {
|
||||
// stream.WriteByte(read);
|
||||
// read = Marshal.ReadByte(lockedPtr);
|
||||
// lockedPtr += 1;
|
||||
// }
|
||||
// // which one?
|
||||
// return Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, stream.ToArray()));
|
||||
// //return Language.GetEncoding().GetString(stream.ToArray());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||
// if (freeMemory) memMgr.Free(ref cap.hContainer);
|
||||
// }
|
||||
// return null;
|
||||
//}
|
||||
///// <summary>
|
||||
///// Read the container pointer content.
|
||||
///// </summary>
|
||||
///// <param name="intptr">A locked pointer to the container's data pointer. If data is array this is the 0th item.</param>
|
||||
///// <param name="type">The twain type.</param>
|
||||
///// <param name="itemIndex">Index of the item if pointer is array.</param>
|
||||
///// <returns></returns>
|
||||
//static TValue ReadContainerData<TValue>(IntPtr intptr, TWTY type, int itemIndex) where TValue : struct
|
||||
//{
|
||||
// var isEnum = typeof(TValue).IsEnum;
|
||||
|
||||
// switch (type)
|
||||
// {
|
||||
// default:
|
||||
// throw new NotSupportedException($"Unsupported item type {type} for reading.");
|
||||
// // TODO: verify if needs to read int32 for small types
|
||||
// case TWTY.INT8:
|
||||
// intptr += 1 * itemIndex;
|
||||
// if (isEnum)
|
||||
// {
|
||||
// return NumericToEnum<sbyte, TValue>(MarshalTo<sbyte>(intptr));
|
||||
// }
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.UINT8:
|
||||
// intptr += 1 * itemIndex;
|
||||
// if (isEnum)
|
||||
// {
|
||||
// return NumericToEnum<byte, TValue>(MarshalTo<byte>(intptr));
|
||||
// }
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.INT16:
|
||||
// intptr += 2 * itemIndex;
|
||||
// if (isEnum)
|
||||
// {
|
||||
// return NumericToEnum<short, TValue>(MarshalTo<short>(intptr));
|
||||
// }
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.BOOL:
|
||||
// case TWTY.UINT16:
|
||||
// intptr += 2 * itemIndex;
|
||||
// if (isEnum)
|
||||
// {
|
||||
// return NumericToEnum<ushort, TValue>(MarshalTo<ushort>(intptr));
|
||||
// }
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.INT32:
|
||||
// intptr += 4 * itemIndex;
|
||||
// if (isEnum)
|
||||
// {
|
||||
// return NumericToEnum<int, TValue>(MarshalTo<int>(intptr));
|
||||
// }
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.UINT32:
|
||||
// intptr += 4 * itemIndex;
|
||||
// if (isEnum)
|
||||
// {
|
||||
// return NumericToEnum<uint, TValue>(MarshalTo<uint>(intptr));
|
||||
// }
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.FIX32:
|
||||
// intptr += 4 * itemIndex;
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.FRAME:
|
||||
// intptr += 16 * itemIndex;
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.STR32:
|
||||
// intptr += TW_STR32.Size * itemIndex;
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.STR64:
|
||||
// intptr += TW_STR64.Size * itemIndex;
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.STR128:
|
||||
// intptr += TW_STR128.Size * itemIndex;
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// case TWTY.STR255:
|
||||
// intptr += TW_STR255.Size * itemIndex;
|
||||
// return MarshalTo<TValue>(intptr);
|
||||
// }
|
||||
//}
|
||||
|
||||
//static TEnum NumericToEnum<TNumber, TEnum>(TNumber num) where TEnum : struct
|
||||
//{
|
||||
// // some caps returns a data type that's not the underlying datatype for the enum
|
||||
// // so best way is to ToString() it and parse it as the enum type.
|
||||
// var str = num.ToString();
|
||||
|
||||
// if (Enum.TryParse(str, out TEnum parsed))
|
||||
// {
|
||||
// return parsed;
|
||||
// }
|
||||
// return default;
|
||||
//}
|
||||
|
||||
//static T MarshalTo<T>(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||
}
|
||||
}
|
609
src/NTwain/Data/ValueWriter.cs
Normal file
609
src/NTwain/Data/ValueWriter.cs
Normal file
@ -0,0 +1,609 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace NTwain.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains methods for writing vairous things to pointers.
|
||||
/// </summary>
|
||||
static class ValueWriter
|
||||
{
|
||||
///// <summary>
|
||||
///// Allocates and copies the string value into a pointer in UTF8 that's null-terminated.
|
||||
///// </summary>
|
||||
///// <param name="twain"></param>
|
||||
///// <param name="value"></param>
|
||||
///// <param name="length">Actual number of bytes used to encode the string without the null.</param>
|
||||
///// <returns></returns>
|
||||
//public static unsafe IntPtr StringToPtrUTF8(IMemoryManager memMgr, string value, out int length)
|
||||
//{
|
||||
// if (value == null)
|
||||
// {
|
||||
// length = 0;
|
||||
// return IntPtr.Zero;
|
||||
// }
|
||||
|
||||
// var utf8 = Encoding.UTF8;
|
||||
// length = utf8.GetByteCount(value);
|
||||
|
||||
// var ptr = memMgr.Alloc((uint)length + 1); // +1 for null-terminated
|
||||
|
||||
// // TODO: test if this works
|
||||
// int written;
|
||||
// byte* bytes = (byte*)ptr;
|
||||
// try
|
||||
// {
|
||||
// // fixed for managed pointer
|
||||
// fixed (char* firstChar = value)
|
||||
// {
|
||||
// written = Encoding.UTF8.GetBytes(firstChar, value.Length, bytes, length);
|
||||
// }
|
||||
|
||||
// bytes[written] = 0;
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (ptr != IntPtr.Zero) memMgr.Free(ptr);
|
||||
// }
|
||||
|
||||
// return ptr;
|
||||
//}
|
||||
|
||||
|
||||
|
||||
// most of these are modified from the original TWAIN.CsvToCapability()
|
||||
|
||||
//public static void WriteOneValueContainer<TValue>(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);
|
||||
|
||||
// TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// // 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);
|
||||
|
||||
// TW_ONEVALUE_MACOSX twonevaluemacosx = default;
|
||||
// twonevaluemacosx.ItemType = (uint)itemType;
|
||||
// Marshal.StructureToPtr(twonevaluemacosx, 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);
|
||||
|
||||
// TW_ONEVALUE twonevalue = default;
|
||||
// twonevalue.ItemType = itemType;
|
||||
// Marshal.StructureToPtr(twonevalue, lockedPtr, false);
|
||||
|
||||
// lockedPtr += Marshal.SizeOf(twonevalue);
|
||||
// }
|
||||
|
||||
// WriteContainerData(lockedPtr, itemType, value, 0);
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
|
||||
// }
|
||||
//}
|
||||
|
||||
//public static void WriteArrayContainer<TValue>(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);
|
||||
|
||||
// TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// // 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);
|
||||
|
||||
// // 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 = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ARRAY)) + ((values.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
|
||||
// lockedPtr = memMgr.Lock(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) memMgr.Unlock(twCap.hContainer);
|
||||
// }
|
||||
//}
|
||||
|
||||
//public static void WriteEnumContainer<TValue>(IMemoryManager memMgr, ref TW_CAPABILITY twCap, Enumeration<TValue> value) where TValue : struct
|
||||
//{
|
||||
// IntPtr lockedPtr = IntPtr.Zero;
|
||||
// try
|
||||
// {
|
||||
// if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
|
||||
|
||||
// TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// // 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 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 (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);
|
||||
|
||||
// // 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 = memMgr.Alloc((uint)(Marshal.SizeOf(default(TW_ENUMERATION_LINUX64)) + ((value.Items.Length + 1) * Marshal.SizeOf(default(TW_STR255)))));
|
||||
// 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);
|
||||
|
||||
// // 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) memMgr.Unlock(twCap.hContainer);
|
||||
// }
|
||||
//}
|
||||
|
||||
//public static void WriteRangeContainer<TValue>(IMemoryManager memMgr, ref TW_CAPABILITY twCap, Range<TValue> value) where TValue : struct
|
||||
//{
|
||||
// IntPtr lockedPtr = IntPtr.Zero;
|
||||
// try
|
||||
// {
|
||||
// if (twCap.hContainer != IntPtr.Zero) memMgr.Free(ref twCap.hContainer);
|
||||
|
||||
// TWTY itemType = GetItemType<TValue>();
|
||||
|
||||
// // 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 Item...
|
||||
// WriteRangeValues(twain, lockedPtr, itemType, value);
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
// if (lockedPtr != IntPtr.Zero) memMgr.Unlock(twCap.hContainer);
|
||||
// }
|
||||
//}
|
||||
|
||||
//static void WriteRangeValues<TValue>(IMemoryManager memMgr, IntPtr lockedPtr, TWTY itemType, Range<TValue> value) where TValue : struct
|
||||
//{
|
||||
// // TODO: reduce this later
|
||||
|
||||
// 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<TValue>() 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;
|
||||
|
||||
// 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.");
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Writes single piece of value to the container pointer.
|
||||
///// </summary>
|
||||
///// <typeparam name="TValue"></typeparam>
|
||||
///// <param name="intptr">A locked pointer to the container's data pointer. If data is array this is the 0th item.</param>
|
||||
///// <param name="type">The twain type.</param>
|
||||
///// <param name="value"></param>
|
||||
///// <param name="itemIndex">Index of the item if pointer is array.</param>
|
||||
//static void WriteContainerData<TValue>(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;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user