mirror of
https://github.com/soukoku/ntwain.git
synced 2026-02-25 13:04:07 +08:00
Test reading some values boxed.
This commit is contained in:
@@ -258,7 +258,7 @@ namespace NTwain.Data
|
|||||||
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
/// A more dotnet-friendly representation of <see cref="TW_ENUMERATION"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TValue"></typeparam>
|
/// <typeparam name="TValue"></typeparam>
|
||||||
public class Enumeration<TValue> where TValue : struct
|
public class Enumeration<TValue>
|
||||||
{
|
{
|
||||||
public int CurrentIndex;
|
public int CurrentIndex;
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,52 @@ namespace NTwain.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads a boxed one value out of a cap. This can only be done once if memory is freed.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TValue"></typeparam>
|
||||||
|
/// <param name="cap"></param>
|
||||||
|
/// <param name="memMgr"></param>
|
||||||
|
/// <param name="freeMemory"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static object? ReadOneValueBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||||
|
{
|
||||||
|
if (cap.ConType != TWON.ONEVALUE || 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 (TWPlatform.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 ReadTWTYDataBoxed(lockedPtr, itemType, 0);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||||
|
if (freeMemory)
|
||||||
|
{
|
||||||
|
memMgr.Free(cap.hContainer);
|
||||||
|
cap.hContainer = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a one value out of a cap. This can only be done once if memory is freed.
|
/// Reads a one value out of a cap. This can only be done once if memory is freed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -130,6 +176,78 @@ namespace NTwain.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Enumeration<object> ReadEnumerationBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||||
|
{
|
||||||
|
Enumeration<object> retVal = new();
|
||||||
|
|
||||||
|
if (cap.ConType != TWON.ENUMERATION || 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 (TWPlatform.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
|
||||||
|
{
|
||||||
|
// 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 object[count];
|
||||||
|
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
retVal.Items[i] = ReadTWTYDataBoxed(lockedPtr, itemType, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||||
|
if (freeMemory)
|
||||||
|
{
|
||||||
|
memMgr.Free(cap.hContainer);
|
||||||
|
cap.hContainer = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
public static Enumeration<TValue> ReadEnumeration<TValue>(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true) where TValue : struct
|
public static Enumeration<TValue> ReadEnumeration<TValue>(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true) where TValue : struct
|
||||||
{
|
{
|
||||||
Enumeration<TValue> retVal = new();
|
Enumeration<TValue> retVal = new();
|
||||||
@@ -202,6 +320,53 @@ namespace NTwain.Data
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IList<object> ReadArrayBoxed(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
|
||||||
|
{
|
||||||
|
if (cap.ConType != TWON.ARRAY || cap.hContainer == IntPtr.Zero) return Array.Empty<object>();
|
||||||
|
|
||||||
|
var lockedPtr = memMgr.Lock(cap.hContainer);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TWTY itemType;
|
||||||
|
uint count;
|
||||||
|
|
||||||
|
// Mac has a level of indirection and a different structure (ick)...
|
||||||
|
if (TWPlatform.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 object[count];
|
||||||
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
arr[i] = ReadTWTYDataBoxed(lockedPtr, itemType, i);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
|
||||||
|
if (freeMemory)
|
||||||
|
{
|
||||||
|
memMgr.Free(cap.hContainer);
|
||||||
|
cap.hContainer = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static IList<TValue> ReadArray<TValue>(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true) where TValue : struct
|
public static IList<TValue> ReadArray<TValue>(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true) where TValue : struct
|
||||||
{
|
{
|
||||||
if (cap.ConType != TWON.ARRAY || cap.hContainer == IntPtr.Zero) return Array.Empty<TValue>();
|
if (cap.ConType != TWON.ARRAY || cap.hContainer == IntPtr.Zero) return Array.Empty<TValue>();
|
||||||
@@ -373,6 +538,64 @@ namespace NTwain.Data
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Read the pointer content as a boxed value specified by <see cref="TWTY"/>, except <see cref="TWTY.HANDLE"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="intptr">A locked pointer to the 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>
|
||||||
|
public static object ReadTWTYDataBoxed(this IntPtr intptr, TWTY type, int itemIndex)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException($"Unsupported item type {type} for reading.");
|
||||||
|
// TODO: verify if needs to read int32 for small types
|
||||||
|
case TWTY.HANDLE:
|
||||||
|
intptr += IntPtr.Size * itemIndex;
|
||||||
|
return MarshalTo<IntPtr>(intptr);
|
||||||
|
case TWTY.INT8:
|
||||||
|
intptr += 1 * itemIndex;
|
||||||
|
return MarshalTo<sbyte>(intptr);
|
||||||
|
case TWTY.UINT8:
|
||||||
|
intptr += 1 * itemIndex;
|
||||||
|
return MarshalTo<byte>(intptr);
|
||||||
|
case TWTY.INT16:
|
||||||
|
intptr += 2 * itemIndex;
|
||||||
|
return MarshalTo<short>(intptr);
|
||||||
|
case TWTY.BOOL:
|
||||||
|
case TWTY.UINT16:
|
||||||
|
intptr += 2 * itemIndex;
|
||||||
|
return MarshalTo<ushort>(intptr);
|
||||||
|
case TWTY.INT32:
|
||||||
|
intptr += 4 * itemIndex;
|
||||||
|
return MarshalTo<int>(intptr);
|
||||||
|
case TWTY.UINT32:
|
||||||
|
intptr += 4 * itemIndex;
|
||||||
|
return MarshalTo<uint>(intptr);
|
||||||
|
case TWTY.FIX32:
|
||||||
|
intptr += 4 * itemIndex;
|
||||||
|
return MarshalTo<TW_FIX32>(intptr);
|
||||||
|
case TWTY.FRAME:
|
||||||
|
intptr += 16 * itemIndex;
|
||||||
|
return MarshalTo<TW_FRAME>(intptr);
|
||||||
|
case TWTY.STR32:
|
||||||
|
intptr += TW_STR32.Size * itemIndex;
|
||||||
|
return MarshalTo<TW_STR32>(intptr);
|
||||||
|
case TWTY.STR64:
|
||||||
|
intptr += TW_STR64.Size * itemIndex;
|
||||||
|
return MarshalTo<TW_STR64>(intptr);
|
||||||
|
case TWTY.STR128:
|
||||||
|
intptr += TW_STR128.Size * itemIndex;
|
||||||
|
return MarshalTo<TW_STR128>(intptr);
|
||||||
|
case TWTY.STR255:
|
||||||
|
intptr += TW_STR255.Size * itemIndex;
|
||||||
|
return MarshalTo<TW_STR255>(intptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Read the pointer content as a value specified by <see cref="TWTY"/>, except <see cref="TWTY.HANDLE"/>.
|
/// Read the pointer content as a value specified by <see cref="TWTY"/>, except <see cref="TWTY.HANDLE"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user