mirror of
https://github.com/soukoku/ntwain.git
synced 2025-10-08 00:14:38 +08:00
Some more type reading update.
This commit is contained in:
@@ -166,7 +166,7 @@ namespace NTwain.Data
|
||||
int offset = 0;
|
||||
ItemType = (ItemType)(ushort)Marshal.ReadInt16(baseAddr, offset);
|
||||
offset += 2;
|
||||
OneValue = ReadValue(baseAddr, ref offset, ItemType);
|
||||
OneValue = TypeReader.ReadValue(baseAddr, ref offset, ItemType);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ namespace NTwain.Data
|
||||
CollectionValues = new object[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
CollectionValues[i] = ReadValue(baseAddr, ref offset, ItemType);
|
||||
CollectionValues[i] = TypeReader.ReadValue(baseAddr, ref offset, ItemType);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@@ -204,7 +204,7 @@ namespace NTwain.Data
|
||||
CollectionValues = new object[count];
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
CollectionValues[i] = ReadValue(baseAddr, ref offset, ItemType);
|
||||
CollectionValues[i] = TypeReader.ReadValue(baseAddr, ref offset, ItemType);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
@@ -228,125 +228,6 @@ namespace NTwain.Data
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@@ -691,7 +691,7 @@ namespace NTwain.Data
|
||||
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
|
||||
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));
|
||||
if (_hContainer != IntPtr.Zero)
|
||||
@@ -707,7 +707,7 @@ namespace NTwain.Data
|
||||
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;
|
||||
_hContainer = MemoryManager.Instance.Allocate((uint)valueSize);
|
||||
@@ -733,7 +733,7 @@ namespace NTwain.Data
|
||||
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
|
||||
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));
|
||||
if (_hContainer != IntPtr.Zero)
|
||||
@@ -808,7 +808,7 @@ namespace NTwain.Data
|
||||
// WriteUString(baseAddr, offset, value as string, 512);
|
||||
// break;
|
||||
}
|
||||
offset += CapReadOut.GetItemTypeSize(type);
|
||||
offset += TypeReader.GetItemTypeSize(type);
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes string value.
|
||||
@@ -1325,7 +1325,7 @@ namespace NTwain.Data
|
||||
/// If the Item field contains a handle to data, then the Application is
|
||||
/// responsible for freeing that memory.
|
||||
/// </summary>
|
||||
public UIntPtr Item { get { return _item; } }
|
||||
public UIntPtr Item { get { return _item; } internal set { _item = value; } }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1352,6 +1352,9 @@ namespace NTwain.Data
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
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
|
||||
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);
|
||||
if (sz > UIntPtr.Size || i.ItemType == ItemType.Handle)
|
||||
var sz = it.NumItems * TypeReader.GetItemTypeSize(it.ItemType);
|
||||
if (sz > UIntPtr.Size || it.ItemType == ItemType.Handle)
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
it.Item = UIntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="TWExtImageInfo"/> class.
|
||||
/// </summary>
|
||||
~TWExtImageInfo()
|
||||
{
|
||||
Dispose(false);
|
||||
@@ -2239,6 +2247,9 @@ namespace NTwain.Data
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
@@ -2258,6 +2269,9 @@ namespace NTwain.Data
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="TWStatusUtf8"/> class.
|
||||
/// </summary>
|
||||
~TWStatusUtf8()
|
||||
{
|
||||
Dispose(false);
|
||||
|
@@ -55,6 +55,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="AsyncPump.cs" />
|
||||
<Compile Include="Data\CapReadOut.cs" />
|
||||
<Compile Include="Data\TypeReader.cs" />
|
||||
<Compile Include="Data\TypesExtended.cs" />
|
||||
<Compile Include="DeviceEventArgs.cs" />
|
||||
<Compile Include="Extensions.cs" />
|
||||
|
Reference in New Issue
Block a user