Some more type reading update.

This commit is contained in:
soukoku
2014-04-12 09:14:50 -04:00
parent 0d70bcc5cc
commit 6a54b2a136
3 changed files with 28 additions and 132 deletions

View File

@@ -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
}
}

View File

@@ -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);

View File

@@ -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" />