From 668066cd2b4061a013ae89d7896481f14da5ec85 Mon Sep 17 00:00:00 2001
From: Eugene Wang <8755753+soukoku@users.noreply.github.com>
Date: Sat, 8 Apr 2023 07:03:30 -0400
Subject: [PATCH] Progress in file xfers.
---
src/NTwain/DataTransferredEventArgs.cs | 73 ++++++++++++++-----------
src/NTwain/TwainAppSession.Xfers.cs | 74 ++++++++++++++++++++------
2 files changed, 100 insertions(+), 47 deletions(-)
diff --git a/src/NTwain/DataTransferredEventArgs.cs b/src/NTwain/DataTransferredEventArgs.cs
index bf2da74..a80cd05 100644
--- a/src/NTwain/DataTransferredEventArgs.cs
+++ b/src/NTwain/DataTransferredEventArgs.cs
@@ -3,61 +3,72 @@ using System;
namespace NTwain
{
- // TODO: a 2-level dispose with end of event method
- // and manual dispose for perf if this is not good enough.
+ // TODO: maybe a 2-level "dispose" with end of event being 1
+ // and manual dispose 2 for perf if this is not good enough.
public class DataTransferredEventArgs : EventArgs
{
- readonly TwainAppSession _twain;
- readonly bool _isImage;
-
-
- internal DataTransferredEventArgs(TwainAppSession twain, bool isImage, TW_SETUPFILEXFER xfer)
+ public DataTransferredEventArgs(TW_AUDIOINFO info, TW_SETUPFILEXFER xfer)
{
- _twain = twain;
- _isImage = isImage;
+ AudioInfo = info;
File = xfer;
+ IsFile = true;
}
-
- ///
- /// Ctor for array data;
- ///
- ///
- ///
- ///
- internal DataTransferredEventArgs(TwainAppSession twain, bool isImage, byte[] data)
+ public DataTransferredEventArgs(TW_AUDIOINFO info, byte[] data)
{
- _twain = twain;
- _isImage = isImage;
+ AudioInfo = info;
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;
+ }
///
- /// The complete file data if the transfer was done
- /// through memory. IMPORTANT: The data held
+ /// Whether transferred data is an image or audio.
+ ///
+ public bool IsImage { get; }
+
+ ///
+ /// Whether transfer was a file or memory data.
+ ///
+ public bool IsFile { get; }
+
+
+ ///
+ /// The complete file data if is false.
+ /// IMPORTANT: The data held
/// in this array will no longer be valid once
/// the event handler ends.
///
public byte[]? Data { get; }
///
- /// The file info if this was a file transfer.
+ /// The file info if is true.
///
public TW_SETUPFILEXFER? File { get; }
///
- /// Gets the final image information if transfer was an image.
+ /// Gets the final image information if is true.
///
- public TW_IMAGEINFO? GetImageInfo()
- {
- if (_isImage && _twain.GetImageInfo(out TW_IMAGEINFO info).RC == TWRC.SUCCESS)
- {
- return info;
- }
- return null;
+ public TW_IMAGEINFO ImageInfo { get; }
+
+
+ ///
+ /// Gets the final audio information if is false.
+ ///
+ public TW_AUDIOINFO AudioInfo { get; }
- }
}
}
\ No newline at end of file
diff --git a/src/NTwain/TwainAppSession.Xfers.cs b/src/NTwain/TwainAppSession.Xfers.cs
index 75e2804..7efa6f7 100644
--- a/src/NTwain/TwainAppSession.Xfers.cs
+++ b/src/NTwain/TwainAppSession.Xfers.cs
@@ -32,6 +32,9 @@ namespace NTwain
///
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
bool xferImage = true;
bool xferAudio = false;
@@ -77,7 +80,7 @@ namespace NTwain
if (readyArgs.Cancel == CancelType.EndNow || _closeDsRequested)
{
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;
}
if (readyArgs.Cancel == CancelType.Graceful)
@@ -143,24 +146,56 @@ namespace NTwain
HandleNonSuccessXferCode(sts);
}
- //if (State > STATE.S5)
- //{
- //if (_closeDsRequested)
- //{
- _uiThreadMarshaller.BeginInvoke(() =>
+ if (State >= STATE.S5)
{
- DisableSource();
- });
- //}
+ _uiThreadMarshaller.BeginInvoke(() =>
+ {
+ DisableSource();
+ });
+ }
}
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()
{
+ 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;
}
@@ -179,7 +214,7 @@ namespace NTwain
STS sts = default;
try
{
- // assuming user already configured the transfer in transferready event
+ // 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
@@ -187,10 +222,10 @@ namespace NTwain
if (sts.RC == TWRC.XFERDONE)
{
State = STATE.S7;
-
try
{
- var args = new DataTransferredEventArgs(this, true, xfer);
+ GetImageInfo(out TW_IMAGEINFO info);
+ var args = new DataTransferredEventArgs(info, xfer);
DataTransferred?.Invoke(this, args);
}
catch { }
@@ -236,12 +271,18 @@ namespace NTwain
{
data = ImageTools.GetTiffData(XferMemPool, lockedPtr);
}
+ else
+ {
+ // PicHandle?
+ // don't support more formats :(
+ }
if (data != null)
{
try
{
- var args = new DataTransferredEventArgs(this, true, data);
+ GetImageInfo(out TW_IMAGEINFO info);
+ var args = new DataTransferredEventArgs(info, data);
DataTransferred?.Invoke(this, args);
}
catch { }
@@ -266,13 +307,14 @@ namespace NTwain
}
finally
{
- State = STATE.S6;
if (lockedPtr != IntPtr.Zero) Unlock(dataPtr);
if (dataPtr != IntPtr.Zero) Free(dataPtr);
}
return sts;
}
+
+ // TODO: this is currently not handled in the right place
private void HandleNonSuccessXferCode(STS sts)
{
switch (sts.RC)
@@ -281,7 +323,7 @@ namespace NTwain
case TWRC.XFERDONE:
// ok to keep going
break;
- case TWRC.CANCEL:
+ case TWRC.CANCEL:
TW_PENDINGXFERS pending = default;
DGControl.PendingXfers.EndXfer(ref _appIdentity, ref _currentDS, ref pending);
break;