diff --git a/src/NTwain/Data/ValueReader.cs b/src/NTwain/Data/ValueReader.cs
index b4fb2dd..c5a1703 100644
--- a/src/NTwain/Data/ValueReader.cs
+++ b/src/NTwain/Data/ValueReader.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
+using System.IO;
using System.Runtime.InteropServices;
using System.Text;
@@ -9,7 +10,7 @@ namespace NTwain.Data
///
/// Contains methods for reading pointers into various things.
///
- public static class ValueReader
+ static class ValueReader
{
///
/// Reads pointer as UTF8 string.
@@ -312,76 +313,84 @@ namespace NTwain.Data
}
}
- /////
- ///// Read the one value of a cap as string. Only STR* and HANDLE types are supported.
- /////
- /////
- /////
- /////
- /////
- //public static string ReadOneValueContainerString(IMemoryManager memMgr, TW_CAPABILITY cap, bool freeMemory = true)
- //{
- // if (cap.hContainer == IntPtr.Zero) return null;
+ ///
+ /// Read the pointer as string. This is for cap's one value string pointer
+ /// that
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string? ReadString(this ref TW_CAPABILITY cap, IMemoryManager memMgr, bool freeMemory = true)
+ {
+ if (cap.hContainer == IntPtr.Zero) return null;
- // var lockedPtr = memMgr.Lock(cap.hContainer);
+ var lockedPtr = memMgr.Lock(cap.hContainer);
+
+ try
+ {
+ if (cap.ConType == TWON.ONEVALUE)
+ {
+ TWTY itemType;
+ // Mac has a level of indirection and a different structure (ick)...
+ if (TwainPlatform.IsMacOSX)
+ {
+ // Crack the container...
+ var onevalue = MarshalTo(lockedPtr);
+ itemType = (TWTY)onevalue.ItemType;
+ lockedPtr += Marshal.SizeOf(onevalue);
+ }
+ else
+ {
+ // Crack the container...
+ var onevalue = MarshalTo(lockedPtr);
+ itemType = onevalue.ItemType;
+ lockedPtr += Marshal.SizeOf(onevalue);
+ }
+
+ switch (itemType)
+ {
+ case TWTY.STR32:
+ return MarshalTo(lockedPtr).ToString();
+ case TWTY.STR64:
+ return MarshalTo(lockedPtr).ToString();
+ case TWTY.STR128:
+ return MarshalTo(lockedPtr).ToString();
+ case TWTY.STR255:
+ return MarshalTo(lockedPtr).ToString();
+ case TWTY.HANDLE:
+ // TODO: how to determine the length of this thing???
+ // null-terminated and encoded string?
+ // good chance this ain't right.
+ using (var stream = new MemoryStream())
+ {
+ byte read = Marshal.ReadByte(lockedPtr);
+ while (read != 0)
+ {
+ stream.WriteByte(read);
+ read = Marshal.ReadByte(lockedPtr);
+ lockedPtr += 1;
+ }
+ // which one?
+ //return Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, stream.ToArray()));
+ return Language.GetEncoding().GetString(stream.ToArray());
+ }
+ }
+ }
+ }
+ finally
+ {
+ if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
+ if (freeMemory)
+ {
+ memMgr.Free(cap.hContainer);
+ cap.hContainer = IntPtr.Zero;
+ }
+ }
+ return null;
+ }
- // try
- // {
- // if (cap.ConType == TWON.ONEVALUE)
- // {
- // TWTY itemType;
- // // Mac has a level of indirection and a different structure (ick)...
- // if (TwainPlatform.IsMacOSX)
- // {
- // // Crack the container...
- // var onevalue = MarshalTo(lockedPtr);
- // itemType = (TWTY)onevalue.ItemType;
- // lockedPtr += Marshal.SizeOf(onevalue);
- // }
- // else
- // {
- // // Crack the container...
- // var onevalue = MarshalTo(lockedPtr);
- // itemType = onevalue.ItemType;
- // lockedPtr += Marshal.SizeOf(onevalue);
- // }
- // switch (itemType)
- // {
- // case TWTY.STR32:
- // return MarshalTo(lockedPtr).ToString();
- // case TWTY.STR64:
- // return MarshalTo(lockedPtr).ToString();
- // case TWTY.STR128:
- // return MarshalTo(lockedPtr).ToString();
- // case TWTY.STR255:
- // return MarshalTo(lockedPtr).ToString();
- // case TWTY.HANDLE:
- // // null-terminated and encoded string.
- // // good chance this ain't right.
- // using (var stream = new MemoryStream())
- // {
- // byte read = Marshal.ReadByte(lockedPtr);
- // while (read != 0)
- // {
- // stream.WriteByte(read);
- // read = Marshal.ReadByte(lockedPtr);
- // lockedPtr += 1;
- // }
- // // which one?
- // return Encoding.Unicode.GetString(Encoding.Convert(Language.GetEncoding(), Encoding.Unicode, stream.ToArray()));
- // //return Language.GetEncoding().GetString(stream.ToArray());
- // }
- // }
- // }
- // }
- // finally
- // {
- // if (lockedPtr != IntPtr.Zero) memMgr.Unlock(cap.hContainer);
- // if (freeMemory) memMgr.Free(ref cap.hContainer);
- // }
- // return null;
- //}
///
/// Read the container pointer content.
///
diff --git a/src/NTwain/TwainAppSession.Caps.cs b/src/NTwain/TwainAppSession.Caps.cs
index 789ea38..0bb6227 100644
--- a/src/NTwain/TwainAppSession.Caps.cs
+++ b/src/NTwain/TwainAppSession.Caps.cs
@@ -171,7 +171,7 @@ namespace NTwain
///
///
///
- ///
+ ///
///
public STS GetCapValues(CAP cap, out IList values) where TValue : struct
{
@@ -208,7 +208,7 @@ namespace NTwain
///
/// Gets a CAP's help text (description).
- /// This is not implemented due to unclear spec.
+ /// This may not work due to unclear spec.
///
///
///
@@ -220,8 +220,7 @@ namespace NTwain
var rc = DGControl.Capability.GetHelp(ref _appIdentity, ref _currentDS, ref value);
if (rc == TWRC.SUCCESS)
{
- // TODO: how to determine the length of this thing???
- var data = value.ReadOneValue(this, false);
+ help = value.ReadString(this, false);
}
value.Free(this);
return WrapInSTS(rc);
@@ -229,7 +228,7 @@ namespace NTwain
///
/// Gets a CAP's text name label.
- /// This is not implemented due to unclear spec.
+ /// This may not work due to unclear spec.
///
///
///
@@ -241,8 +240,7 @@ namespace NTwain
var rc = DGControl.Capability.GetLabel(ref _appIdentity, ref _currentDS, ref value);
if (rc == TWRC.SUCCESS)
{
- // TODO: how to determine the length of this thing???
- var data = value.ReadOneValue(this, false);
+ label = value.ReadString(this, false);
}
value.Free(this);
return WrapInSTS(rc);