mirror of
https://github.com/soukoku/ntwain.git
synced 2025-11-24 08:47:06 +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"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class Enumeration<TValue> where TValue : struct
|
||||
public class Enumeration<TValue>
|
||||
{
|
||||
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>
|
||||
/// Reads a one value out of a cap. This can only be done once if memory is freed.
|
||||
/// </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
|
||||
{
|
||||
Enumeration<TValue> retVal = new();
|
||||
@@ -202,6 +320,53 @@ namespace NTwain.Data
|
||||
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
|
||||
{
|
||||
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>
|
||||
/// Read the pointer content as a value specified by <see cref="TWTY"/>, except <see cref="TWTY.HANDLE"/>.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user