Added extra buffer when setting size from VanaraMarshaler to prevent errors when they're off due to alignment issues

pull/279/head
dahall 2022-01-22 15:28:48 -07:00
parent 0f6fb75d3d
commit 5a511172ea
1 changed files with 12 additions and 25 deletions

View File

@ -19,7 +19,7 @@ namespace Vanara.InteropServices
private readonly FileAccess access; private readonly FileAccess access;
private readonly long chunkSize = DefaultCapacity; private readonly long chunkSize = DefaultCapacity;
private readonly SafeAllocatedMemoryHandle hmem; private readonly SafeAllocatedMemoryHandle hmem;
private readonly List<Reference> references = new List<Reference>(); private readonly List<Reference> references = new();
private long capacity, length, position, preflushPos; private long capacity, length, position, preflushPos;
/// <summary>Initializes a new instance of the <see cref="NativeMemoryStream"/> class.</summary> /// <summary>Initializes a new instance of the <see cref="NativeMemoryStream"/> class.</summary>
@ -438,7 +438,7 @@ namespace Vanara.InteropServices
{ {
ThrowIfDisposed(); ThrowIfDisposed();
var stSize = GetSize(value); var stSize = GetSize(value);
EnsureCapacity(stSize + Position); EnsureCapacity(stSize + Position + 64); // Added some padding
//ResetIfFlushed(); //ResetIfFlushed();
if (value is IntPtr p) if (value is IntPtr p)
Marshal.WriteIntPtr(PositionPtr, p); Marshal.WriteIntPtr(PositionPtr, p);
@ -478,7 +478,7 @@ namespace Vanara.InteropServices
var sz = GetSize(value); var sz = GetSize(value);
if (sz > 0) if (sz > 0)
{ {
EnsureCapacity(sz + IntPtr.Size + Length); EnsureCapacity(sz + IntPtr.Size + Length + 64);
length += sz; length += sz;
references.Add(new Reference(Position, value)); references.Add(new Reference(Position, value));
} }
@ -502,29 +502,16 @@ namespace Vanara.InteropServices
protected virtual int GetSize(object obj, CharSet charSet = CharSet.None) protected virtual int GetSize(object obj, CharSet charSet = CharSet.None)
{ {
if (charSet == CharSet.None) charSet = CharSet; if (charSet == CharSet.None) charSet = CharSet;
switch (obj) return obj switch
{ {
case null: null => 0,
return 0; string s => s.GetByteCount(true, charSet),
IntPtr p => IntPtr.Size,
case string s: IEnumerable<byte> b => b.Count(),
return s.GetByteCount(true, charSet); IEnumerable<string> es => es.Sum(s => s.GetByteCount(true, charSet)),
IEnumerable<object> eo => eo.Sum(o => o is null ? 0 : InteropExtensions.SizeOf(o)),
case IntPtr p: _ => InteropExtensions.SizeOf(obj),
return IntPtr.Size; };
case IEnumerable<byte> b:
return b.Count();
case IEnumerable<string> es:
return es.Sum(s => s.GetByteCount(true, charSet));
case IEnumerable<object> eo:
return eo.Sum(o => o is null ? 0 : (int)InteropExtensions.SizeOf(o.GetType()));
default:
return (int)InteropExtensions.SizeOf(obj.GetType());
}
} }
private int GetRefSize() => references.Sum(e => GetSize(e.Value)); private int GetRefSize() => references.Sum(e => GetSize(e.Value));