mirror of
https://github.com/soukoku/ntwain.git
synced 2026-02-25 13:04:07 +08:00
Reorged source tree.
This commit is contained in:
519
src/NTwain/Data/TwainTypes.cs
Normal file
519
src/NTwain/Data/TwainTypes.cs
Normal file
@@ -0,0 +1,519 @@
|
||||
// This file contains all the structs defined in the twain.h file.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// The following TWAIN basic types are mapped with "using"
|
||||
// to aid in mapping against the twain.h file using copy-paste.
|
||||
// Consumers will not see those names.
|
||||
|
||||
using TW_BOOL = System.UInt16; // unsigned short
|
||||
|
||||
// use HandleRef instead?
|
||||
using TW_HANDLE = System.IntPtr; // HANDLE, todo: should really be uintptr?
|
||||
using TW_MEMREF = System.IntPtr; // LPVOID
|
||||
using TW_UINTPTR = System.UIntPtr; // UINT_PTR
|
||||
|
||||
using TW_INT16 = System.Int16; // short
|
||||
using TW_INT32 = System.Int32; // long
|
||||
using TW_INT8 = System.SByte; // char
|
||||
|
||||
using TW_UINT16 = System.UInt16; // unsigned short
|
||||
using TW_UINT32 = System.UInt32; // unsigned long
|
||||
using TW_UINT8 = System.Byte; // unsigned char
|
||||
|
||||
|
||||
// This mono doc is awesome. An interop must-read
|
||||
// http://www.mono-project.com/Interop_with_Native_Libraries (old)
|
||||
// http://www.mono-project.com/docs/advanced/pinvoke/ (new url)
|
||||
|
||||
//////////////////////////////////
|
||||
// Data structures that
|
||||
// are passed to the TWAIN method
|
||||
// are defined as classes to reduce
|
||||
// ref/out in the low-level calls.
|
||||
// Others continue to be structs.
|
||||
//////////////////////////////////
|
||||
|
||||
|
||||
namespace NTwain.Data
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWFix32
|
||||
{
|
||||
TW_INT16 _whole;
|
||||
TW_UINT16 _frac;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWFrame
|
||||
{
|
||||
TWFix32 _left;
|
||||
TWFix32 _top;
|
||||
TWFix32 _right;
|
||||
TWFix32 _bottom;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWDecodeFunction
|
||||
{
|
||||
TWFix32 _startIn;
|
||||
TWFix32 _breakIn;
|
||||
TWFix32 _endIn;
|
||||
TWFix32 _startOut;
|
||||
TWFix32 _breakOut;
|
||||
TWFix32 _endOut;
|
||||
TWFix32 _gamma;
|
||||
TWFix32 _sampleCount;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWTransformStage
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
|
||||
TWDecodeFunction[] _decode;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
|
||||
TWFix32[] _mix;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWArray
|
||||
{
|
||||
TW_UINT16 _itemType;
|
||||
TW_UINT32 _numItems;
|
||||
object[] _itemList;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2),
|
||||
BestFitMapping(false, ThrowOnUnmappableChar = true)]
|
||||
partial class TWAudioInfo
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String255)]
|
||||
string _name;
|
||||
|
||||
TW_UINT32 _reserved;
|
||||
}
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWCallback
|
||||
{
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
CallbackDelegate _callBackProc;
|
||||
TW_UINT32 _refCon;
|
||||
TW_INT16 _message;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWCallback2
|
||||
{
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
CallbackDelegate _callBackProc;
|
||||
TW_UINTPTR _refCon;
|
||||
TW_INT16 _message;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWCapability
|
||||
{
|
||||
TW_UINT16 _cap;
|
||||
TW_UINT16 _conType;
|
||||
TW_HANDLE _hContainer;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWCiePoint
|
||||
{
|
||||
TWFix32 _x;
|
||||
TWFix32 _y;
|
||||
TWFix32 _z;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWCieColor
|
||||
{
|
||||
TW_UINT16 _colorSpace;
|
||||
TW_INT16 _lowEndian;
|
||||
TW_INT16 _deviceDependent;
|
||||
TW_INT32 _versionNumber;
|
||||
TWTransformStage _stageABC;
|
||||
TWTransformStage _stageLMN;
|
||||
TWCiePoint _whitePoint;
|
||||
TWCiePoint _blackPoint;
|
||||
TWCiePoint _whitePaper;
|
||||
TWCiePoint _blackInk;
|
||||
|
||||
// TODO: may be totally wrong
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
TWFix32[] _samples;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWCustomDSData
|
||||
{
|
||||
TW_UINT32 _infoLength;
|
||||
TW_HANDLE _hData;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2),
|
||||
BestFitMapping(false, ThrowOnUnmappableChar = true)]
|
||||
partial class TWDeviceEvent
|
||||
{
|
||||
TW_UINT32 _event;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String255)]
|
||||
string _deviceName;
|
||||
|
||||
TW_UINT32 _batteryMinutes;
|
||||
TW_INT16 _batteryPercentage;
|
||||
TW_INT32 _powerSupply;
|
||||
TWFix32 _xResolution;
|
||||
TWFix32 _yResolution;
|
||||
TW_UINT32 _flashUsed2;
|
||||
TW_UINT32 _automaticCapture;
|
||||
TW_UINT32 _timeBeforeFirstCapture;
|
||||
TW_UINT32 _timeBetweenCaptures;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWElement8
|
||||
{
|
||||
TW_UINT8 _index;
|
||||
TW_UINT8 _channel1;
|
||||
TW_UINT8 _channel2;
|
||||
TW_UINT8 _channel3;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWEnumeration
|
||||
{
|
||||
TW_UINT16 _itemType;
|
||||
TW_UINT32 _numItems;
|
||||
TW_UINT32 _currentIndex;
|
||||
TW_UINT32 _defaultIndex;
|
||||
object[] _itemList;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWEvent
|
||||
{
|
||||
TW_MEMREF _pEvent;
|
||||
TW_UINT16 _tWMessage;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWInfo
|
||||
{
|
||||
TW_UINT16 _infoID;
|
||||
TW_UINT16 _itemType;
|
||||
TW_UINT16 _numItems;
|
||||
TW_UINT16 _returnCode;
|
||||
//TW_UINTPTR _item;
|
||||
TW_HANDLE _item; // easier to work with intptr
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWExtImageInfo
|
||||
{
|
||||
TW_UINT32 _numInfos;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)]
|
||||
TWInfo[] _info;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2),
|
||||
BestFitMapping(false, ThrowOnUnmappableChar = true)]
|
||||
partial class TWFileSystem
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String255)]
|
||||
string _inputName;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String255)]
|
||||
string _outputName;
|
||||
|
||||
TW_MEMREF _context;
|
||||
TW_BOOL _subdirectories;
|
||||
TW_INT32 _fileType;
|
||||
TW_UINT32 _size;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String32)]
|
||||
string _createTimeDate;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String32)]
|
||||
string _modifiedTimeDate;
|
||||
|
||||
TW_UINT32 _freeSpace;
|
||||
TW_INT32 _newImageSize;
|
||||
TW_UINT32 _numberOfFiles;
|
||||
TW_UINT32 _numberOfSnippets;
|
||||
TW_UINT32 _deviceGroupMask;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 508)]
|
||||
TW_INT8[] _reserved;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWGrayResponse
|
||||
{
|
||||
// TODO: may be totally wrong
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
TWElement8[] _response;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2),
|
||||
BestFitMapping(false, ThrowOnUnmappableChar = true)]
|
||||
partial struct TWVersion
|
||||
{
|
||||
TW_UINT16 _majorNum;
|
||||
TW_UINT16 _minorNum;
|
||||
TW_UINT16 _language;
|
||||
TW_UINT16 _country;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String32)]
|
||||
string _info;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2),
|
||||
BestFitMapping(false, ThrowOnUnmappableChar = true)]
|
||||
partial class TWIdentity
|
||||
{
|
||||
TW_UINT32 _id;
|
||||
TWVersion _version;
|
||||
TW_UINT16 _protocolMajor;
|
||||
TW_UINT16 _protocolMinor;
|
||||
TW_UINT32 _supportedGroups;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String32)]
|
||||
string _manufacturer;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String32)]
|
||||
string _productFamily;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String32)]
|
||||
string _productName;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWImageInfo
|
||||
{
|
||||
TWFix32 _xResolution;
|
||||
TWFix32 _yResolution;
|
||||
TW_INT32 _imageWidth;
|
||||
TW_INT32 _imageLength;
|
||||
TW_INT16 _samplesPerPixel;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||
TW_INT16[] _bitsPerSample;
|
||||
|
||||
TW_INT16 _bitsPerPixel;
|
||||
TW_BOOL _planar;
|
||||
TW_INT16 _pixelType;
|
||||
TW_UINT16 _compression;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWImageLayout
|
||||
{
|
||||
TWFrame _frame;
|
||||
TW_UINT32 _documentNumber;
|
||||
TW_UINT32 _pageNumber;
|
||||
TW_UINT32 _frameNumber;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial struct TWMemory
|
||||
{
|
||||
// this is not a class due to being embedded by other classes
|
||||
|
||||
TW_UINT32 _flags;
|
||||
TW_UINT32 _length;
|
||||
TW_MEMREF _theMem;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWImageMemXfer
|
||||
{
|
||||
TW_UINT16 _compression;
|
||||
TW_UINT32 _bytesPerRow;
|
||||
TW_UINT32 _columns;
|
||||
TW_UINT32 _rows;
|
||||
TW_UINT32 _xOffset;
|
||||
TW_UINT32 _yOffset;
|
||||
TW_UINT32 _bytesWritten;
|
||||
TWMemory _memory;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWJpegCompression
|
||||
{
|
||||
TW_UINT16 _colorSpace;
|
||||
TW_UINT32 _subSampling;
|
||||
TW_UINT16 _numComponents;
|
||||
TW_UINT16 _restartFrequency;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
TW_UINT16[] _quantMap;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
TWMemory[] _quantTable;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
|
||||
TW_UINT16[] _huffmanMap;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
TWMemory[] _huffmanDC;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||
TWMemory[] _huffmanAC;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWOneValue
|
||||
{
|
||||
TW_UINT16 _itemType;
|
||||
TW_UINT32 _item;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWPalette8
|
||||
{
|
||||
TW_UINT16 _numColors;
|
||||
TW_UINT16 _paletteType;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
|
||||
TWElement8[] _colors;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWPassThru
|
||||
{
|
||||
TW_MEMREF _pCommand;
|
||||
TW_UINT32 _commandBytes;
|
||||
TW_INT32 _direction;
|
||||
TW_MEMREF _pData;
|
||||
TW_UINT32 _dataBytes;
|
||||
TW_UINT32 _dataBytesXfered;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWPendingXfers
|
||||
{
|
||||
TW_UINT16 _count;
|
||||
TW_UINT32 _eOJ;
|
||||
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWRange
|
||||
{
|
||||
TW_UINT16 _itemType;
|
||||
TW_UINT32 _minValue;
|
||||
TW_UINT32 _maxValue;
|
||||
TW_UINT32 _stepSize;
|
||||
TW_UINT32 _defaultValue;
|
||||
TW_UINT32 _currentValue;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWRgbResponse
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
|
||||
TWElement8[] _response;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2),
|
||||
BestFitMapping(false, ThrowOnUnmappableChar = true)]
|
||||
partial class TWSetupFileXfer
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = TwainConst.String255)]
|
||||
string _fileName;
|
||||
|
||||
TW_UINT16 _format;
|
||||
TW_INT16 _vRefNum = -1;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWSetupMemXfer
|
||||
{
|
||||
TW_UINT32 _minBufSize;
|
||||
TW_UINT32 _maxBufSize;
|
||||
TW_UINT32 _preferred;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWStatus
|
||||
{
|
||||
TW_UINT16 _conditionCode;
|
||||
TW_UINT16 _data;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWStatusUtf8
|
||||
{
|
||||
// NOTE: rather than embedding the TWStatus directly I'm using its fields instead
|
||||
// so the TWStatus could become a class object. If TWStatus changes
|
||||
// definition remember to change it here
|
||||
TW_UINT16 _conditionCode;
|
||||
TW_UINT16 _data;
|
||||
TW_UINT32 _size;
|
||||
TW_HANDLE _uTF8string;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWUserInterface
|
||||
{
|
||||
TW_BOOL _showUI;
|
||||
TW_BOOL _modalUI;
|
||||
TW_HANDLE _hParent;
|
||||
}
|
||||
|
||||
delegate ReturnCode CallbackDelegate(TWIdentity origin, TWIdentity destination,
|
||||
DataGroups dg, DataArgumentType dat, Message msg, TW_MEMREF data);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWEntryPoint
|
||||
{
|
||||
TW_UINT32 _size;
|
||||
// this is not a delegate cuz it's not used by the app
|
||||
IntPtr _dSM_Entry;
|
||||
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
MemAllocateDelegate _dSM_MemAllocate;
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
MemFreeDelegate _dSM_MemFree;
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
MemLockDelegate _dSM_MemLock;
|
||||
[MarshalAs(UnmanagedType.FunctionPtr)]
|
||||
MemUnlockDelegate _dSM_MemUnlock;
|
||||
|
||||
public delegate TW_HANDLE MemAllocateDelegate(TW_UINT32 size);
|
||||
public delegate void MemFreeDelegate(TW_HANDLE handle);
|
||||
public delegate TW_MEMREF MemLockDelegate(TW_HANDLE handle);
|
||||
public delegate void MemUnlockDelegate(TW_HANDLE handle);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWFilterDescriptor
|
||||
{
|
||||
TW_UINT32 _size;
|
||||
TW_UINT32 _hueStart;
|
||||
TW_UINT32 _hueEnd;
|
||||
TW_UINT32 _saturationStart;
|
||||
TW_UINT32 _saturationEnd;
|
||||
TW_UINT32 _valueStart;
|
||||
TW_UINT32 _valueEnd;
|
||||
TW_UINT32 _replacement;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
partial class TWFilter
|
||||
{
|
||||
TW_UINT32 _size;
|
||||
TW_UINT32 _descriptorCount;
|
||||
TW_UINT32 _maxDescriptorCount;
|
||||
TW_UINT32 _condition;
|
||||
TW_HANDLE _hDescriptors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
2525
src/NTwain/Data/TwainTypesExtended.cs
Normal file
2525
src/NTwain/Data/TwainTypesExtended.cs
Normal file
File diff suppressed because it is too large
Load Diff
2152
src/NTwain/Data/TwainValues.cs
Normal file
2152
src/NTwain/Data/TwainValues.cs
Normal file
File diff suppressed because it is too large
Load Diff
249
src/NTwain/Data/TypeExtensions.cs
Normal file
249
src/NTwain/Data/TypeExtensions.cs
Normal file
@@ -0,0 +1,249 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace NTwain.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extensions for reading/writing TWAIN types from/to pointer.
|
||||
/// </summary>
|
||||
public static class TypeExtensions
|
||||
{
|
||||
static readonly IDictionary<ItemType, int> __sizes = new Dictionary<ItemType, int>
|
||||
{
|
||||
{ItemType.Int8, 1},
|
||||
{ItemType.UInt8, 1},
|
||||
{ItemType.Int16, 2},
|
||||
{ItemType.UInt16, 2},
|
||||
{ItemType.Bool, 2},
|
||||
{ItemType.Int32, 4},
|
||||
{ItemType.UInt32, 4},
|
||||
{ItemType.Fix32, 4},
|
||||
{ItemType.Frame, 16},
|
||||
{ItemType.String32, TwainConst.String32},
|
||||
{ItemType.String64, TwainConst.String64},
|
||||
{ItemType.String128, TwainConst.String128},
|
||||
{ItemType.String255, TwainConst.String255},
|
||||
// TODO: find out if it should be fixed 4 bytes or intptr size
|
||||
{ItemType.Handle, IntPtr.Size},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets the byte size of the item type.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static int GetItemTypeSize(this ItemType type)
|
||||
{
|
||||
if (__sizes.ContainsKey(type))
|
||||
{
|
||||
return __sizes[type];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads a TWAIN value.
|
||||
/// </summary>
|
||||
/// <param name="baseAddress">The base address.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="type">The TWAIN type.</param>
|
||||
/// <returns></returns>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#")]
|
||||
public static object ReadValue(this IntPtr baseAddress, ref int offset, ItemType type)
|
||||
{
|
||||
object val = null;
|
||||
switch (type)
|
||||
{
|
||||
case ItemType.Int8:
|
||||
val = (sbyte)Marshal.ReadByte(baseAddress, offset);
|
||||
break;
|
||||
case ItemType.UInt8:
|
||||
val = Marshal.ReadByte(baseAddress, offset);
|
||||
break;
|
||||
case ItemType.Bool:
|
||||
case ItemType.UInt16:
|
||||
val = (ushort)Marshal.ReadInt16(baseAddress, offset);
|
||||
break;
|
||||
case ItemType.Int16:
|
||||
val = Marshal.ReadInt16(baseAddress, offset);
|
||||
break;
|
||||
case ItemType.UInt32:
|
||||
val = (uint)Marshal.ReadInt32(baseAddress, offset);
|
||||
break;
|
||||
case ItemType.Int32:
|
||||
val = Marshal.ReadInt32(baseAddress, offset);
|
||||
break;
|
||||
case ItemType.Fix32:
|
||||
TWFix32 f32 = new TWFix32();
|
||||
f32.Whole = Marshal.ReadInt16(baseAddress, offset);
|
||||
f32.Fraction = (ushort)Marshal.ReadInt16(baseAddress, offset + 2);
|
||||
val = f32;
|
||||
break;
|
||||
case ItemType.Frame:
|
||||
TWFrame frame = new TWFrame();
|
||||
frame.Left = (TWFix32)ReadValue(baseAddress, ref offset, ItemType.Fix32);
|
||||
frame.Top = (TWFix32)ReadValue(baseAddress, ref offset, ItemType.Fix32);
|
||||
frame.Right = (TWFix32)ReadValue(baseAddress, ref offset, ItemType.Fix32);
|
||||
frame.Bottom = (TWFix32)ReadValue(baseAddress, ref offset, ItemType.Fix32);
|
||||
return frame; // no need to update offset again after reading fix32
|
||||
case ItemType.String128:
|
||||
case ItemType.String255:
|
||||
case ItemType.String32:
|
||||
case ItemType.String64:
|
||||
val = Marshal.PtrToStringAnsi(new IntPtr(baseAddress.ToInt64() + offset));
|
||||
break;
|
||||
case ItemType.Handle:
|
||||
val = Marshal.ReadIntPtr(baseAddress, offset);
|
||||
break;
|
||||
}
|
||||
offset += GetItemTypeSize(type);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region writes
|
||||
|
||||
/// <summary>
|
||||
/// Writes a TWAIN value.
|
||||
/// </summary>
|
||||
/// <param name="baseAddr">The base addr.</param>
|
||||
/// <param name="offset">The offset.</param>
|
||||
/// <param name="type">The TWAIN type.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference", MessageId = "1#"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
|
||||
public static void WriteValue(this IntPtr baseAddr, ref int offset, ItemType type, object value)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ItemType.Int8:
|
||||
case ItemType.UInt8:
|
||||
Marshal.WriteByte(baseAddr, offset, Convert.ToByte(value, CultureInfo.InvariantCulture));// (byte)value);
|
||||
break;
|
||||
case ItemType.Bool:
|
||||
case ItemType.Int16:
|
||||
case ItemType.UInt16:
|
||||
Marshal.WriteInt16(baseAddr, offset, Convert.ToInt16(value, CultureInfo.InvariantCulture));//(short)value);
|
||||
break;
|
||||
case ItemType.UInt32:
|
||||
case ItemType.Int32:
|
||||
Marshal.WriteInt32(baseAddr, offset, Convert.ToInt32(value, CultureInfo.InvariantCulture));//(int)value);
|
||||
break;
|
||||
case ItemType.Fix32:
|
||||
TWFix32 f32 = (TWFix32)value;
|
||||
Marshal.WriteInt16(baseAddr, offset, f32.Whole);
|
||||
if (f32.Fraction > Int16.MaxValue)
|
||||
{
|
||||
Marshal.WriteInt16(baseAddr, offset + 2, (Int16)(f32.Fraction - 32768));
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.WriteInt16(baseAddr, offset + 2, (Int16)f32.Fraction);
|
||||
}
|
||||
break;
|
||||
case ItemType.Frame:
|
||||
TWFrame frame = (TWFrame)value;
|
||||
WriteValue(baseAddr, ref offset, ItemType.Fix32, (TWFix32)frame.Left);
|
||||
WriteValue(baseAddr, ref offset, ItemType.Fix32, (TWFix32)frame.Top);
|
||||
WriteValue(baseAddr, ref offset, ItemType.Fix32, (TWFix32)frame.Right);
|
||||
WriteValue(baseAddr, ref offset, ItemType.Fix32, (TWFix32)frame.Bottom);
|
||||
return; // no need to update offset for this
|
||||
//case ItemType.String1024:
|
||||
// WriteString(baseAddr, offset, value as string, 1024);
|
||||
// break;
|
||||
case ItemType.String128:
|
||||
WriteString(baseAddr, offset, (string)value, 128);
|
||||
break;
|
||||
case ItemType.String255:
|
||||
WriteString(baseAddr, offset, (string)value, 255);
|
||||
break;
|
||||
case ItemType.String32:
|
||||
WriteString(baseAddr, offset, (string)value, 32);
|
||||
break;
|
||||
case ItemType.String64:
|
||||
WriteString(baseAddr, offset, (string)value, 64);
|
||||
break;
|
||||
//case ItemType.Unicode512:
|
||||
// WriteUString(baseAddr, offset, value as string, 512);
|
||||
// break;
|
||||
}
|
||||
offset += TypeExtensions.GetItemTypeSize(type);
|
||||
}
|
||||
/// <summary>
|
||||
/// Writes string value. THIS MAY BE WRONG.
|
||||
/// </summary>
|
||||
/// <param name="baseAddr"></param>
|
||||
/// <param name="offset"></param>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="maxLength"></param>
|
||||
static void WriteString(IntPtr baseAddr, int offset, string item, int maxLength)
|
||||
{
|
||||
if (string.IsNullOrEmpty(item))
|
||||
{
|
||||
// write zero
|
||||
Marshal.WriteByte(baseAddr, offset, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < maxLength; i++)
|
||||
{
|
||||
if (i == item.Length)
|
||||
{
|
||||
// string end reached, so write \0 and quit
|
||||
Marshal.WriteByte(baseAddr, offset, 0);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Marshal.WriteByte(baseAddr, offset, (byte)item[i]);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
// when ended normally also write \0
|
||||
Marshal.WriteByte(baseAddr, offset, 0);
|
||||
}
|
||||
}
|
||||
///// <summary>
|
||||
///// Writes unicode string value.
|
||||
///// </summary>
|
||||
///// <param name="baseAddr"></param>
|
||||
///// <param name="offset"></param>
|
||||
///// <param name="item"></param>
|
||||
///// <param name="maxLength"></param>
|
||||
//[EnvironmentPermissionAttribute(SecurityAction.LinkDemand)]
|
||||
//private void WriteUString(IntPtr baseAddr, int offset, string item, int maxLength)
|
||||
//{
|
||||
// if (string.IsNullOrEmpty(item))
|
||||
// {
|
||||
// // write zero
|
||||
// Marshal.WriteInt16(baseAddr, offset, (char)0);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // use 2 bytes per char
|
||||
// for (int i = 0; i < maxLength; i++)
|
||||
// {
|
||||
// if (i == item.Length)
|
||||
// {
|
||||
// // string end reached, so write \0 and quit
|
||||
// Marshal.WriteInt16(baseAddr, offset, (char)0);
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Marshal.WriteInt16(baseAddr, offset, item[i]);
|
||||
// offset += 2;
|
||||
// }
|
||||
// }
|
||||
// // when ended normally also write \0
|
||||
// Marshal.WriteByte(baseAddr, offset, 0);
|
||||
// }
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
175
src/NTwain/Data/ValueExtensions.cs
Normal file
175
src/NTwain/Data/ValueExtensions.cs
Normal file
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace NTwain.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains extension methods for converting (possibly bad) integer values to enum values.
|
||||
/// </summary>
|
||||
public static class ValueExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Casts a list of objects to a list of specified enum.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
||||
/// <param name="list">The list.</param>
|
||||
/// <returns></returns>
|
||||
public static IList<TEnum> CastToEnum<TEnum>(this IEnumerable<object> list) where TEnum : struct,IConvertible
|
||||
{
|
||||
return list.CastToEnum<TEnum>(true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Casts a list of objects to a list of specified enum.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
||||
/// <param name="list">The list.</param>
|
||||
/// <param name="tryUpperWord">set to <c>true</c> for working with bad values.</param>
|
||||
/// <returns></returns>
|
||||
public static IList<TEnum> CastToEnum<TEnum>(this IEnumerable<object> list, bool tryUpperWord) where TEnum : struct,IConvertible
|
||||
{
|
||||
return list.Select(o => o.ConvertToEnum<TEnum>(tryUpperWord)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Casts an objects to the specified enum.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns></returns>
|
||||
public static TEnum ConvertToEnum<TEnum>(this object value) where TEnum : struct,IConvertible
|
||||
{
|
||||
return ConvertToEnum<TEnum>(value, true);
|
||||
}
|
||||
/// <summary>
|
||||
/// Casts an objects to the specified enum.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">The type of the enum.</typeparam>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="tryUpperWord">if set to <c>true</c> [try upper word].</param>
|
||||
/// <returns></returns>
|
||||
public static TEnum ConvertToEnum<TEnum>(this object value, bool tryUpperWord) where TEnum : struct,IConvertible
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
var returnType = typeof(TEnum);
|
||||
|
||||
// standard int values
|
||||
if (returnType.IsEnum)
|
||||
{
|
||||
var rawType = Enum.GetUnderlyingType(returnType);
|
||||
|
||||
if (tryUpperWord)
|
||||
{
|
||||
// small routine to work with bad sources that may put
|
||||
// 16bit value in the upper word instead of lower word (as per the twain spec).
|
||||
if (typeof(ushort).IsAssignableFrom(rawType))
|
||||
{
|
||||
var intVal = Convert.ToUInt32(value, CultureInfo.InvariantCulture);
|
||||
var enumVal = GetLowerWord(intVal);
|
||||
if (!Enum.IsDefined(returnType, enumVal))
|
||||
{
|
||||
return (TEnum)Enum.ToObject(returnType, GetUpperWord(intVal));
|
||||
}
|
||||
}
|
||||
}
|
||||
// old method:
|
||||
// return (TEnum)Enum.ToObject(returnType, value);
|
||||
|
||||
// new method:
|
||||
// try to convert to enum's underlying type first then cast to the enum
|
||||
return (TEnum)Convert.ChangeType(value, rawType, CultureInfo.InvariantCulture);
|
||||
}
|
||||
else if (typeof(IConvertible).IsAssignableFrom(returnType))
|
||||
{
|
||||
// for regular integers and whatnot
|
||||
return (TEnum)Convert.ChangeType(value, returnType, CultureInfo.InvariantCulture);
|
||||
}
|
||||
// return as-is from cap. if caller made a mistake then there should be exceptions
|
||||
return (TEnum)value;
|
||||
}
|
||||
return default(TEnum);
|
||||
}
|
||||
|
||||
static ushort GetLowerWord(uint value)
|
||||
{
|
||||
return (ushort)(value & 0xffff);
|
||||
}
|
||||
static uint GetUpperWord(uint value)
|
||||
{
|
||||
return (ushort)(value >> 16);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to convert a value to <see cref="TWFix32"/> if possible.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns></returns>
|
||||
public static TWFix32 ConvertToFix32(this object value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (value is TWFix32)
|
||||
{
|
||||
return (TWFix32)value;
|
||||
}
|
||||
return (TWFix32)Convert.ToSingle(value, CultureInfo.InvariantCulture);
|
||||
}
|
||||
return default(TWFix32);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to cast a value to <see cref="TWFrame"/> if possible.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns></returns>
|
||||
public static TWFrame ConvertToFrame(this object value)
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
if (value is TWFrame)
|
||||
{
|
||||
return (TWFrame)value;
|
||||
}
|
||||
}
|
||||
return default(TWFrame);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts object to string.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns></returns>
|
||||
public static string ConvertToString(this object value)
|
||||
{
|
||||
if (value == null) { return null; }
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
|
||||
///// <summary>
|
||||
///// Routine that does nothing.
|
||||
///// </summary>
|
||||
///// <param name="value">The value.</param>
|
||||
///// <returns></returns>
|
||||
//public static object NoConvertRoutine(object value)
|
||||
//{
|
||||
// return value;
|
||||
//}
|
||||
|
||||
///// <summary>
|
||||
///// Predefined routine for <see cref="string"/>
|
||||
///// </summary>
|
||||
///// <param name="value">The value.</param>
|
||||
///// <returns></returns>
|
||||
//public static string ConvertToString(object value)
|
||||
//{
|
||||
// if (value != null)
|
||||
// {
|
||||
// return value.ToString();
|
||||
// }
|
||||
// return default(string);
|
||||
//}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user