Skip to content

Commit

Permalink
Some more unverified tw_info reads ideas.
Browse files Browse the repository at this point in the history
  • Loading branch information
soukoku committed Apr 11, 2023
1 parent fa88dd4 commit 2fd5f05
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 5 deletions.
11 changes: 6 additions & 5 deletions src/NTwain/Data/TWAINH_EXTRAS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1040,8 +1040,9 @@ public unsafe TValue ReadNonPointerData<TValue>() where TValue : struct
/// </summary>
/// <param name="memMgr"></param>
/// <param name="index">If item is an array specify which string to read</param>
/// <param name="lengthHint">Pass a value if you know how long it should be.</param>
/// <returns></returns>
public unsafe string? ReadHandleString(IMemoryManager memMgr, int index = 0)
public unsafe string? ReadHandleString(IMemoryManager memMgr, int index = 0, int lengthHint = -1)
{
if (index < 0 || index >= NumItems || !IsDataAPointer) return default;

Expand All @@ -1053,7 +1054,7 @@ public unsafe TValue ReadNonPointerData<TValue>() where TValue : struct
if (NumItems == 1)
{
// if 1, item is already the pointer to the string
value = LockAndReadNullTerminatedString(memMgr, itemAsPtr);
value = LockAndReadNullTerminatedString(memMgr, itemAsPtr, lengthHint);
}
else
{
Expand All @@ -1062,17 +1063,17 @@ public unsafe TValue ReadNonPointerData<TValue>() where TValue : struct
lockPtr += (IntPtr.Size * index);
// is this even correct? I hope it is
var subItemPtr = Marshal.PtrToStructure<IntPtr>(lockPtr);
value = LockAndReadNullTerminatedString(memMgr, subItemPtr);
value = LockAndReadNullTerminatedString(memMgr, subItemPtr, lengthHint);
memMgr.Unlock(itemAsPtr);
}
return value;
}

private string? LockAndReadNullTerminatedString(IMemoryManager memMgr, IntPtr data)
private string? LockAndReadNullTerminatedString(IMemoryManager memMgr, IntPtr data, int lengthHint = -1)
{
var lockPtr = memMgr.Lock(data);
// yolo as ansi, should work in most cases
var value = Marshal.PtrToStringAnsi(lockPtr);
var value = lengthHint > 0 ? Marshal.PtrToStringAnsi(lockPtr, lengthHint) : Marshal.PtrToStringAnsi(lockPtr);
memMgr.Unlock(data);
return value;
}
Expand Down
3 changes: 3 additions & 0 deletions src/NTwain/Data/ValueReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,9 @@ public static TValue ReadTWTYData<TValue>(this IntPtr intptr, TWTY type, int ite
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<TValue>(intptr);
case TWTY.INT8:
intptr += 1 * itemIndex;
if (isEnum)
Expand Down
6 changes: 6 additions & 0 deletions src/NTwain/Data/ValueWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ static TWTY GetItemType<TValue>() where TValue : struct
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 == typeof(IntPtr)) return TWTY.HANDLE;
if (type == typeof(UIntPtr)) return TWTY.HANDLE;

if (type.IsEnum)
{
Expand Down Expand Up @@ -579,6 +581,10 @@ static void WriteContainerData<TValue>(IntPtr intptr, TWTY type, TValue value, i
default:
throw new NotSupportedException($"Unsupported item type {type} for writing.");
// TODO: for small types needs to fill whole int32 before writing?
case TWTY.HANDLE:
intptr += IntPtr.Size * itemIndex;
Marshal.StructureToPtr(value, intptr, false);
break;
case TWTY.INT8:
intptr += 1 * itemIndex;
//int intval = Convert.ToSByte(value);
Expand Down

0 comments on commit 2fd5f05

Please sign in to comment.