mirror of
https://github.com/soukoku/ntwain.git
synced 2025-12-01 19:04:09 +08:00
Some more type reading update.
This commit is contained in:
@@ -166,7 +166,7 @@ namespace NTwain.Data
|
|||||||
int offset = 0;
|
int offset = 0;
|
||||||
ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset);
|
ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
OneValue = ReadValue(baseAddr, ref offset, ItemType);
|
OneValue = TypeReader.ReadValue(baseAddr, ref offset, ItemType);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,7 +182,7 @@ namespace NTwain.Data
|
|||||||
CollectionValues = new object[count];
|
CollectionValues = new object[count];
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
CollectionValues[i] = ReadValue(baseAddr, ref offset, ItemType);
|
CollectionValues[i] = TypeReader.ReadValue(baseAddr, ref offset, ItemType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -204,7 +204,7 @@ namespace NTwain.Data
|
|||||||
CollectionValues = new object[count];
|
CollectionValues = new object[count];
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
CollectionValues[i] = ReadValue(baseAddr, ref offset, ItemType);
|
CollectionValues[i] = TypeReader.ReadValue(baseAddr, ref offset, ItemType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -228,125 +228,6 @@ namespace NTwain.Data
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static object ReadValue(IntPtr baseAddr, ref int offset, ItemType type)
|
|
||||||
{
|
|
||||||
object val = null;
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case ItemType.Int8:
|
|
||||||
val = (sbyte)Marshal.ReadByte(baseAddr, offset);
|
|
||||||
break;
|
|
||||||
case ItemType.UInt8:
|
|
||||||
val = Marshal.ReadByte(baseAddr, offset);
|
|
||||||
break;
|
|
||||||
case ItemType.Bool:
|
|
||||||
case ItemType.UInt16:
|
|
||||||
val = (ushort)Marshal.ReadInt16(baseAddr, offset);
|
|
||||||
break;
|
|
||||||
case ItemType.Int16:
|
|
||||||
val = Marshal.ReadInt16(baseAddr, offset);
|
|
||||||
break;
|
|
||||||
case ItemType.UInt32:
|
|
||||||
val = (uint)Marshal.ReadInt32(baseAddr, offset);
|
|
||||||
break;
|
|
||||||
case ItemType.Int32:
|
|
||||||
val = Marshal.ReadInt32(baseAddr, offset);
|
|
||||||
break;
|
|
||||||
case ItemType.Fix32:
|
|
||||||
TWFix32 f32 = new TWFix32();
|
|
||||||
f32.Whole = Marshal.ReadInt16(baseAddr, offset);
|
|
||||||
f32.Fraction = (ushort)Marshal.ReadInt16(baseAddr, offset + 2);
|
|
||||||
val = f32;
|
|
||||||
break;
|
|
||||||
case ItemType.Frame:
|
|
||||||
TWFrame frame = new TWFrame();
|
|
||||||
frame.Left = (TWFix32)ReadValue(baseAddr, ref offset, ItemType.Fix32);
|
|
||||||
frame.Top = (TWFix32)ReadValue(baseAddr, ref offset, ItemType.Fix32);
|
|
||||||
frame.Right = (TWFix32)ReadValue(baseAddr, ref offset, ItemType.Fix32);
|
|
||||||
frame.Bottom = (TWFix32)ReadValue(baseAddr, ref offset, ItemType.Fix32);
|
|
||||||
return frame; // no need to update offset again after reading fix32
|
|
||||||
case ItemType.String128:
|
|
||||||
val = ReadString(baseAddr, offset, TwainConst.String128 - 2);
|
|
||||||
break;
|
|
||||||
case ItemType.String255:
|
|
||||||
val = ReadString(baseAddr, offset, TwainConst.String255 - 1);
|
|
||||||
break;
|
|
||||||
case ItemType.String32:
|
|
||||||
val = ReadString(baseAddr, offset, TwainConst.String32 - 2);
|
|
||||||
break;
|
|
||||||
case ItemType.String64:
|
|
||||||
val = ReadString(baseAddr, offset, TwainConst.String64 - 2);
|
|
||||||
break;
|
|
||||||
case ItemType.Handle:
|
|
||||||
val = new IntPtr(baseAddr.ToInt64() + offset);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
offset += GetItemTypeSize(type);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Read string value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="baseAddr"></param>
|
|
||||||
/// <param name="offset"></param>
|
|
||||||
/// <param name="maxLength"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
static string ReadString(IntPtr baseAddr, int offset, int maxLength)
|
|
||||||
{
|
|
||||||
// does this work cross-platform?
|
|
||||||
var val = Marshal.PtrToStringAnsi(new IntPtr(baseAddr.ToInt64() + offset));
|
|
||||||
if (val.Length > maxLength)
|
|
||||||
{
|
|
||||||
// bad source, whatever
|
|
||||||
}
|
|
||||||
return val;
|
|
||||||
//var sb = new StringBuilder(maxLength);
|
|
||||||
//byte bt;
|
|
||||||
//while (sb.Length < maxLength &&
|
|
||||||
// (bt = Marshal.ReadByte(baseAddr, offset++)) != 0)
|
|
||||||
//{
|
|
||||||
// sb.Append((char)bt);
|
|
||||||
//}
|
|
||||||
//return sb.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the byte size of the item type.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="type"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
internal static int GetItemTypeSize(ItemType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case ItemType.Int8:
|
|
||||||
case ItemType.UInt8:
|
|
||||||
return 1;
|
|
||||||
case ItemType.UInt16:
|
|
||||||
case ItemType.Int16:
|
|
||||||
case ItemType.Bool:
|
|
||||||
return 2;
|
|
||||||
case ItemType.Int32:
|
|
||||||
case ItemType.UInt32:
|
|
||||||
case ItemType.Fix32:
|
|
||||||
return 4;
|
|
||||||
case ItemType.Frame:
|
|
||||||
return 16;
|
|
||||||
case ItemType.String32:
|
|
||||||
return TwainConst.String32;
|
|
||||||
case ItemType.String64:
|
|
||||||
return TwainConst.String64;
|
|
||||||
case ItemType.String128:
|
|
||||||
return TwainConst.String128;
|
|
||||||
case ItemType.String255:
|
|
||||||
return TwainConst.String255;
|
|
||||||
case ItemType.Handle:
|
|
||||||
return IntPtr.Size;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -691,7 +691,7 @@ namespace NTwain.Data
|
|||||||
if (ContainerType != Values.ContainerType.OneValue) { throw new ArgumentException(Resources.BadContainerType, "value"); }
|
if (ContainerType != Values.ContainerType.OneValue) { throw new ArgumentException(Resources.BadContainerType, "value"); }
|
||||||
|
|
||||||
// since one value can only house UInt32 we will not allow type size > 4
|
// since one value can only house UInt32 we will not allow type size > 4
|
||||||
if (CapReadOut.GetItemTypeSize(value.ItemType) > 4) { throw new ArgumentException("Invalid one value type"); }
|
if (TypeReader.GetItemTypeSize(value.ItemType) > 4) { throw new ArgumentException("Invalid one value type"); }
|
||||||
|
|
||||||
_hContainer = MemoryManager.Instance.Allocate((uint)Marshal.SizeOf(value));
|
_hContainer = MemoryManager.Instance.Allocate((uint)Marshal.SizeOf(value));
|
||||||
if (_hContainer != IntPtr.Zero)
|
if (_hContainer != IntPtr.Zero)
|
||||||
@@ -707,7 +707,7 @@ namespace NTwain.Data
|
|||||||
if (ContainerType != Values.ContainerType.Enum) { throw new ArgumentException(Resources.BadContainerType, "value"); }
|
if (ContainerType != Values.ContainerType.Enum) { throw new ArgumentException(Resources.BadContainerType, "value"); }
|
||||||
|
|
||||||
|
|
||||||
Int32 valueSize = value.ItemOffset + value.ItemList.Length * CapReadOut.GetItemTypeSize(value.ItemType);
|
Int32 valueSize = value.ItemOffset + value.ItemList.Length * TypeReader.GetItemTypeSize(value.ItemType);
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
_hContainer = MemoryManager.Instance.Allocate((uint)valueSize);
|
_hContainer = MemoryManager.Instance.Allocate((uint)valueSize);
|
||||||
@@ -733,7 +733,7 @@ namespace NTwain.Data
|
|||||||
if (ContainerType != Values.ContainerType.Range) { throw new ArgumentException(Resources.BadContainerType, "value"); }
|
if (ContainerType != Values.ContainerType.Range) { throw new ArgumentException(Resources.BadContainerType, "value"); }
|
||||||
|
|
||||||
// since range value can only house UInt32 we will not allow type size > 4
|
// since range value can only house UInt32 we will not allow type size > 4
|
||||||
if (CapReadOut.GetItemTypeSize(value.ItemType) > 4) { throw new ArgumentException("Invalid range value type"); }
|
if (TypeReader.GetItemTypeSize(value.ItemType) > 4) { throw new ArgumentException("Invalid range value type"); }
|
||||||
|
|
||||||
_hContainer = MemoryManager.Instance.Allocate((uint)Marshal.SizeOf(value));
|
_hContainer = MemoryManager.Instance.Allocate((uint)Marshal.SizeOf(value));
|
||||||
if (_hContainer != IntPtr.Zero)
|
if (_hContainer != IntPtr.Zero)
|
||||||
@@ -808,7 +808,7 @@ namespace NTwain.Data
|
|||||||
// WriteUString(baseAddr, offset, value as string, 512);
|
// WriteUString(baseAddr, offset, value as string, 512);
|
||||||
// break;
|
// break;
|
||||||
}
|
}
|
||||||
offset += CapReadOut.GetItemTypeSize(type);
|
offset += TypeReader.GetItemTypeSize(type);
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes string value.
|
/// Writes string value.
|
||||||
@@ -1325,7 +1325,7 @@ namespace NTwain.Data
|
|||||||
/// If the Item field contains a handle to data, then the Application is
|
/// If the Item field contains a handle to data, then the Application is
|
||||||
/// responsible for freeing that memory.
|
/// responsible for freeing that memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UIntPtr Item { get { return _item; } }
|
public UIntPtr Item { get { return _item; } internal set { _item = value; } }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -1352,6 +1352,9 @@ namespace NTwain.Data
|
|||||||
|
|
||||||
#region IDisposable Members
|
#region IDisposable Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
@@ -1364,22 +1367,27 @@ namespace NTwain.Data
|
|||||||
// this is iffy & may have to flatten info array as individual fields in this class to work
|
// this is iffy & may have to flatten info array as individual fields in this class to work
|
||||||
if (_info != null)
|
if (_info != null)
|
||||||
{
|
{
|
||||||
foreach (var i in _info)
|
for (int i = 0; i < _info.Length; i++)
|
||||||
{
|
{
|
||||||
if (i.Item != UIntPtr.Zero)
|
var it = _info[i];
|
||||||
|
if (it.Item != UIntPtr.Zero)
|
||||||
{
|
{
|
||||||
var sz = i.NumItems * CapReadOut.GetItemTypeSize(i.ItemType);
|
var sz = it.NumItems * TypeReader.GetItemTypeSize(it.ItemType);
|
||||||
if (sz > UIntPtr.Size || i.ItemType == ItemType.Handle)
|
if (sz > UIntPtr.Size || it.ItemType == ItemType.Handle)
|
||||||
{
|
{
|
||||||
// uintptr to intptr could be bad
|
// uintptr to intptr could be bad
|
||||||
var ptr = new IntPtr(BitConverter.ToInt64(BitConverter.GetBytes(i.Item.ToUInt64()), 0));
|
var ptr = new IntPtr(BitConverter.ToInt64(BitConverter.GetBytes(it.Item.ToUInt64()), 0));
|
||||||
MemoryManager.Instance.Free(ptr);
|
MemoryManager.Instance.Free(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
it.Item = UIntPtr.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes an instance of the <see cref="TWExtImageInfo"/> class.
|
||||||
|
/// </summary>
|
||||||
~TWExtImageInfo()
|
~TWExtImageInfo()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
@@ -2239,6 +2247,9 @@ namespace NTwain.Data
|
|||||||
|
|
||||||
#region IDisposable Members
|
#region IDisposable Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||||
|
/// </summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
@@ -2258,6 +2269,9 @@ namespace NTwain.Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes an instance of the <see cref="TWStatusUtf8"/> class.
|
||||||
|
/// </summary>
|
||||||
~TWStatusUtf8()
|
~TWStatusUtf8()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="AsyncPump.cs" />
|
<Compile Include="AsyncPump.cs" />
|
||||||
<Compile Include="Data\CapReadOut.cs" />
|
<Compile Include="Data\CapReadOut.cs" />
|
||||||
|
<Compile Include="Data\TypeReader.cs" />
|
||||||
<Compile Include="Data\TypesExtended.cs" />
|
<Compile Include="Data\TypesExtended.cs" />
|
||||||
<Compile Include="DeviceEventArgs.cs" />
|
<Compile Include="DeviceEventArgs.cs" />
|
||||||
<Compile Include="Extensions.cs" />
|
<Compile Include="Extensions.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user