mirror of
https://github.com/soukoku/ntwain.git
synced 2025-04-05 20:59:23 +08:00
Progress in file xfers.
This commit is contained in:
parent
443419ff64
commit
668066cd2b
@ -3,61 +3,72 @@ using System;
|
|||||||
|
|
||||||
namespace NTwain
|
namespace NTwain
|
||||||
{
|
{
|
||||||
// TODO: a 2-level dispose with end of event method
|
// TODO: maybe a 2-level "dispose" with end of event being 1
|
||||||
// and manual dispose for perf if this is not good enough.
|
// and manual dispose 2 for perf if this is not good enough.
|
||||||
|
|
||||||
public class DataTransferredEventArgs : EventArgs
|
public class DataTransferredEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
readonly TwainAppSession _twain;
|
public DataTransferredEventArgs(TW_AUDIOINFO info, TW_SETUPFILEXFER xfer)
|
||||||
readonly bool _isImage;
|
|
||||||
|
|
||||||
|
|
||||||
internal DataTransferredEventArgs(TwainAppSession twain, bool isImage, TW_SETUPFILEXFER xfer)
|
|
||||||
{
|
{
|
||||||
_twain = twain;
|
AudioInfo = info;
|
||||||
_isImage = isImage;
|
|
||||||
File = xfer;
|
File = xfer;
|
||||||
|
IsFile = true;
|
||||||
}
|
}
|
||||||
|
public DataTransferredEventArgs(TW_AUDIOINFO info, byte[] data)
|
||||||
/// <summary>
|
|
||||||
/// Ctor for array data;
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="twain"></param>
|
|
||||||
/// <param name="isImage"></param>
|
|
||||||
/// <param name="data"></param>
|
|
||||||
internal DataTransferredEventArgs(TwainAppSession twain, bool isImage, byte[] data)
|
|
||||||
{
|
{
|
||||||
_twain = twain;
|
AudioInfo = info;
|
||||||
_isImage = isImage;
|
|
||||||
Data = data;
|
Data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DataTransferredEventArgs(TW_IMAGEINFO info, TW_SETUPFILEXFER xfer)
|
||||||
|
{
|
||||||
|
ImageInfo = info;
|
||||||
|
File = xfer;
|
||||||
|
IsImage = true;
|
||||||
|
IsFile = true;
|
||||||
|
}
|
||||||
|
public DataTransferredEventArgs(TW_IMAGEINFO info, byte[] data)
|
||||||
|
{
|
||||||
|
ImageInfo = info;
|
||||||
|
Data = data;
|
||||||
|
IsImage = true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The complete file data if the transfer was done
|
/// Whether transferred data is an image or audio.
|
||||||
/// through memory. IMPORTANT: The data held
|
/// </summary>
|
||||||
|
public bool IsImage { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether transfer was a file or memory data.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsFile { get; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The complete file data if <see cref="IsFile"/> is false.
|
||||||
|
/// IMPORTANT: The data held
|
||||||
/// in this array will no longer be valid once
|
/// in this array will no longer be valid once
|
||||||
/// the event handler ends.
|
/// the event handler ends.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte[]? Data { get; }
|
public byte[]? Data { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The file info if this was a file transfer.
|
/// The file info if <see cref="IsFile"/> is true.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TW_SETUPFILEXFER? File { get; }
|
public TW_SETUPFILEXFER? File { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the final image information if transfer was an image.
|
/// Gets the final image information if <see cref="IsImage"/> is true.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TW_IMAGEINFO? GetImageInfo()
|
public TW_IMAGEINFO ImageInfo { get; }
|
||||||
{
|
|
||||||
if (_isImage && _twain.GetImageInfo(out TW_IMAGEINFO info).RC == TWRC.SUCCESS)
|
|
||||||
{
|
/// <summary>
|
||||||
return info;
|
/// Gets the final audio information if <see cref="IsImage"/> is false.
|
||||||
}
|
/// </summary>
|
||||||
return null;
|
public TW_AUDIOINFO AudioInfo { get; }
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,6 +32,9 @@ namespace NTwain
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
void EnterTransferRoutine()
|
void EnterTransferRoutine()
|
||||||
{
|
{
|
||||||
|
// TODO: currently implemented routine doesn't quite work for audio as described in spec
|
||||||
|
|
||||||
|
|
||||||
// default options if source doesn't support changing them or whatever
|
// default options if source doesn't support changing them or whatever
|
||||||
bool xferImage = true;
|
bool xferImage = true;
|
||||||
bool xferAudio = false;
|
bool xferAudio = false;
|
||||||
@ -77,7 +80,7 @@ namespace NTwain
|
|||||||
if (readyArgs.Cancel == CancelType.EndNow || _closeDsRequested)
|
if (readyArgs.Cancel == CancelType.EndNow || _closeDsRequested)
|
||||||
{
|
{
|
||||||
sts = WrapInSTS(DGControl.PendingXfers.Reset(ref _appIdentity, ref _currentDS, ref pending));
|
sts = WrapInSTS(DGControl.PendingXfers.Reset(ref _appIdentity, ref _currentDS, ref pending));
|
||||||
if (sts.RC == TWRC.SUCCESS) State = STATE.S5;
|
if (sts.RC == TWRC.SUCCESS && xferImage) State = STATE.S5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (readyArgs.Cancel == CancelType.Graceful)
|
if (readyArgs.Cancel == CancelType.Graceful)
|
||||||
@ -143,24 +146,56 @@ namespace NTwain
|
|||||||
HandleNonSuccessXferCode(sts);
|
HandleNonSuccessXferCode(sts);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (State > STATE.S5)
|
if (State >= STATE.S5)
|
||||||
//{
|
|
||||||
//if (_closeDsRequested)
|
|
||||||
//{
|
|
||||||
_uiThreadMarshaller.BeginInvoke(() =>
|
|
||||||
{
|
{
|
||||||
DisableSource();
|
_uiThreadMarshaller.BeginInvoke(() =>
|
||||||
});
|
{
|
||||||
//}
|
DisableSource();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private STS TransferFileAudio()
|
private STS TransferFileAudio()
|
||||||
{
|
{
|
||||||
return default;
|
STS sts = default;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// assuming user already configured the transfer in transferready event,
|
||||||
|
// get what will be transferred
|
||||||
|
DGControl.SetupFileXfer.Get(ref _appIdentity, ref _currentDS, out TW_SETUPFILEXFER xfer);
|
||||||
|
// and just start it
|
||||||
|
sts = WrapInSTS(DGAudio.AudioFileXfer.Get(ref _appIdentity, ref _currentDS));
|
||||||
|
if (sts.RC == TWRC.XFERDONE)
|
||||||
|
{
|
||||||
|
State = STATE.S7;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DGAudio.AudioInfo.Get(ref _appIdentity, ref _currentDS, out TW_AUDIOINFO info);
|
||||||
|
var args = new DataTransferredEventArgs(info, xfer);
|
||||||
|
DataTransferred?.Invoke(this, args);
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HandleNonSuccessXferCode(sts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TransferError?.Invoke(this, new TransferErrorEventArgs(ex));
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private STS TransferNativeAudio()
|
private STS TransferNativeAudio()
|
||||||
{
|
{
|
||||||
|
DGAudio.AudioInfo.Get(ref _appIdentity, ref _currentDS, out TW_AUDIOINFO info);
|
||||||
|
// ugh don't know how to read wav/aiff from pointer yet
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +214,7 @@ namespace NTwain
|
|||||||
STS sts = default;
|
STS sts = default;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// assuming user already configured the transfer in transferready event
|
// assuming user already configured the transfer in transferready event,
|
||||||
// get what will be transferred
|
// get what will be transferred
|
||||||
DGControl.SetupFileXfer.Get(ref _appIdentity, ref _currentDS, out TW_SETUPFILEXFER xfer);
|
DGControl.SetupFileXfer.Get(ref _appIdentity, ref _currentDS, out TW_SETUPFILEXFER xfer);
|
||||||
// and just start it
|
// and just start it
|
||||||
@ -187,10 +222,10 @@ namespace NTwain
|
|||||||
if (sts.RC == TWRC.XFERDONE)
|
if (sts.RC == TWRC.XFERDONE)
|
||||||
{
|
{
|
||||||
State = STATE.S7;
|
State = STATE.S7;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var args = new DataTransferredEventArgs(this, true, xfer);
|
GetImageInfo(out TW_IMAGEINFO info);
|
||||||
|
var args = new DataTransferredEventArgs(info, xfer);
|
||||||
DataTransferred?.Invoke(this, args);
|
DataTransferred?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@ -236,12 +271,18 @@ namespace NTwain
|
|||||||
{
|
{
|
||||||
data = ImageTools.GetTiffData(XferMemPool, lockedPtr);
|
data = ImageTools.GetTiffData(XferMemPool, lockedPtr);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// PicHandle?
|
||||||
|
// don't support more formats :(
|
||||||
|
}
|
||||||
|
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var args = new DataTransferredEventArgs(this, true, data);
|
GetImageInfo(out TW_IMAGEINFO info);
|
||||||
|
var args = new DataTransferredEventArgs(info, data);
|
||||||
DataTransferred?.Invoke(this, args);
|
DataTransferred?.Invoke(this, args);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
@ -266,13 +307,14 @@ namespace NTwain
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
State = STATE.S6;
|
|
||||||
if (lockedPtr != IntPtr.Zero) Unlock(dataPtr);
|
if (lockedPtr != IntPtr.Zero) Unlock(dataPtr);
|
||||||
if (dataPtr != IntPtr.Zero) Free(dataPtr);
|
if (dataPtr != IntPtr.Zero) Free(dataPtr);
|
||||||
}
|
}
|
||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: this is currently not handled in the right place
|
||||||
private void HandleNonSuccessXferCode(STS sts)
|
private void HandleNonSuccessXferCode(STS sts)
|
||||||
{
|
{
|
||||||
switch (sts.RC)
|
switch (sts.RC)
|
||||||
@ -281,7 +323,7 @@ namespace NTwain
|
|||||||
case TWRC.XFERDONE:
|
case TWRC.XFERDONE:
|
||||||
// ok to keep going
|
// ok to keep going
|
||||||
break;
|
break;
|
||||||
case TWRC.CANCEL:
|
case TWRC.CANCEL:
|
||||||
TW_PENDINGXFERS pending = default;
|
TW_PENDINGXFERS pending = default;
|
||||||
DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
|
DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user