Updated mem file xfer with right buffer size and osx calls.

This commit is contained in:
Eugene Wang 2023-04-08 12:07:30 -04:00
parent 558dad90a1
commit 830dc8cd9b

View File

@ -275,17 +275,29 @@ namespace NTwain
rc = DGControl.SetupMemXfer.Get(ref _appIdentity, ref _currentDS, out TW_SETUPMEMXFER memSetup); rc = DGControl.SetupMemXfer.Get(ref _appIdentity, ref _currentDS, out TW_SETUPMEMXFER memSetup);
if (rc == TWRC.SUCCESS) if (rc == TWRC.SUCCESS)
{ {
// TODO: mac version uint buffSize = DetermineBufferSize(memSetup);
var buffSize = Math.Max(memSetup.Preferred, 4096); var memPtr = Alloc(buffSize);
TW_IMAGEMEMXFER memXfer = new() TW_IMAGEMEMXFER memXfer = new()
{ {
Memory = new TW_MEMORY Memory = new TW_MEMORY
{ {
Flags = (uint)(TWMF.APPOWNS | TWMF.POINTER), Flags = (uint)(TWMF.APPOWNS | TWMF.POINTER),
Length = buffSize, Length = buffSize,
TheMem = Alloc(buffSize) TheMem = memPtr
} }
}; };
TW_IMAGEMEMXFER_MACOSX memXferOSX = new()
{
Memory = new TW_MEMORY
{
Flags = (uint)(TWMF.APPOWNS | TWMF.POINTER),
Length = buffSize,
TheMem = memPtr
}
};
// TODO: how to get actual file size before hand? // TODO: how to get actual file size before hand?
// otherwise will just write to stream with lots of copies // otherwise will just write to stream with lots of copies
byte[] dotnetBuff = XferMemPool.Rent((int)buffSize); byte[] dotnetBuff = XferMemPool.Rent((int)buffSize);
@ -294,25 +306,31 @@ namespace NTwain
{ {
do do
{ {
rc = DGImage.ImageMemFileXfer.Get(ref _appIdentity, ref _currentDS, ref memXfer); rc = TwainPlatform.IsMacOSX ?
DGImage.ImageMemFileXfer.Get(ref _appIdentity, ref _currentDS, ref memXferOSX) :
DGImage.ImageMemFileXfer.Get(ref _appIdentity, ref _currentDS, ref memXfer);
if (rc == TWRC.SUCCESS || rc == TWRC.XFERDONE) if (rc == TWRC.SUCCESS || rc == TWRC.XFERDONE)
{ {
try try
{ {
IntPtr lockedPtr = Lock(memXfer.Memory.TheMem); var written = TwainPlatform.IsMacOSX ?
Marshal.Copy(lockedPtr, dotnetBuff, 0, (int)memXfer.BytesWritten); memXferOSX.BytesWritten : memXfer.BytesWritten;
outStream.Write(dotnetBuff, 0, (int)memXfer.BytesWritten);
IntPtr lockedPtr = Lock(memPtr);
Marshal.Copy(lockedPtr, dotnetBuff, 0, (int)written);
outStream.Write(dotnetBuff, 0, (int)written);
} }
finally finally
{ {
Unlock(memXfer.Memory.TheMem); Unlock(memPtr);
} }
} }
} while (rc == TWRC.SUCCESS); } while (rc == TWRC.SUCCESS);
} }
finally finally
{ {
if (memXfer.Memory.TheMem != IntPtr.Zero) Free(memXfer.Memory.TheMem); if (memPtr != IntPtr.Zero) Free(memPtr);
XferMemPool.Return(dotnetBuff); XferMemPool.Return(dotnetBuff);
} }
@ -339,6 +357,21 @@ namespace NTwain
return WrapInSTS(rc); return WrapInSTS(rc);
} }
private static uint DetermineBufferSize(TW_SETUPMEMXFER memSetup)
{
// default to 16 kb if source doesn't really want to say what it needs
var buffSize = memSetup.Preferred;
if (buffSize != TwainConst.TWON_DONTCARE32) return buffSize;
buffSize = memSetup.MaxBufSize;
if (buffSize != TwainConst.TWON_DONTCARE32) return buffSize;
buffSize = memSetup.MinBufSize;
if (buffSize != TwainConst.TWON_DONTCARE32) return buffSize;
return 1024 * 16;
}
private STS TransferFileImage(ref TW_PENDINGXFERS pending) private STS TransferFileImage(ref TW_PENDINGXFERS pending)
{ {
// assuming user already configured the transfer in transferready event, // assuming user already configured the transfer in transferready event,