diff --git a/src/Elasticsearch.Net/Extensions/UtilExtensions.cs b/src/Elasticsearch.Net/Extensions/UtilExtensions.cs
index 88206c42fcb..2891a756bd2 100644
--- a/src/Elasticsearch.Net/Extensions/UtilExtensions.cs
+++ b/src/Elasticsearch.Net/Extensions/UtilExtensions.cs
@@ -27,6 +27,16 @@ internal static string Utf8String(this MemoryStream ms)
return Encoding.UTF8.GetString(buffer.Array, buffer.Offset, buffer.Count);
}
+ /// Attempts to return to underlying bytes buffer (no-copy) if possible
+ internal static byte[] ToArrayOrBuffer(this MemoryStream ms)
+ {
+ if (ms is null) return null;
+
+ if (!ms.TryGetBuffer(out var buffer) || buffer.Array is null)
+ return ms.ToArray();
+
+ return buffer.Array;
+ }
internal static byte[] Utf8Bytes(this string s) => s.IsNullOrEmpty() ? null : Encoding.UTF8.GetBytes(s);
diff --git a/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs b/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs
index 1948f5b43a2..4455fcdcd5c 100644
--- a/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs
+++ b/src/Elasticsearch.Net/Serialization/ElasticsearchSerializerExtensions.cs
@@ -1,5 +1,4 @@
using Elasticsearch.Net.Extensions;
-using Elasticsearch.Net.Utf8Json;
namespace Elasticsearch.Net
{
@@ -16,7 +15,7 @@ public static byte[] SerializeToBytes(
using (var ms = memoryStreamFactory.Create())
{
serializer.Serialize(data, ms, formatting);
- return ms.ToArray();
+ return ms.ToArrayOrBuffer();
}
}
diff --git a/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs b/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs
index c3fe2fcc0df..70521e6d61c 100644
--- a/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs
+++ b/src/Elasticsearch.Net/Transport/Pipeline/ResponseBuilder.cs
@@ -174,7 +174,7 @@ private static bool NeedsToEagerReadStream()
private static byte[] SwapStreams(ref Stream responseStream, ref MemoryStream ms)
{
- var bytes = ms.ToArray();
+ var bytes = ms.ToArrayOrBuffer();
responseStream.Dispose();
responseStream = ms;
responseStream.Position = 0;
diff --git a/src/Elasticsearch.Net/Transport/PostData.cs b/src/Elasticsearch.Net/Transport/PostData.cs
index 934d7ad1bbd..2da69af0d8e 100644
--- a/src/Elasticsearch.Net/Transport/PostData.cs
+++ b/src/Elasticsearch.Net/Transport/PostData.cs
@@ -124,7 +124,7 @@ public override void Write(Stream writableStream, IConnectionConfigurationValues
ms.CopyTo(writableStream, BufferSize);
}
if (Type != 0)
- WrittenBytes = ms?.ToArray();
+ WrittenBytes = ms?.ToArrayOrBuffer();
}
public override async Task WriteAsync(Stream writableStream, IConnectionConfigurationValues settings, CancellationToken cancellationToken)
@@ -169,7 +169,7 @@ await settings.RequestResponseSerializer.SerializeAsync(o, stream, Serialization
await ms.CopyToAsync(writableStream, BufferSize, cancellationToken).ConfigureAwait(false);
}
if (Type != 0)
- WrittenBytes = ms?.ToArray();
+ WrittenBytes = ms?.ToArrayOrBuffer();
}
}
}
diff --git a/src/Elasticsearch.Net/Transport/SerializableData.cs b/src/Elasticsearch.Net/Transport/SerializableData.cs
index ac769d01186..5006a386e55 100644
--- a/src/Elasticsearch.Net/Transport/SerializableData.cs
+++ b/src/Elasticsearch.Net/Transport/SerializableData.cs
@@ -1,6 +1,7 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
+using Elasticsearch.Net.Extensions;
namespace Elasticsearch.Net
{
@@ -31,7 +32,7 @@ public override void Write(Stream writableStream, IConnectionConfigurationValues
ms.CopyTo(writableStream, BufferSize);
}
if (Type != 0)
- WrittenBytes = ms?.ToArray();
+ WrittenBytes = ms?.ToArrayOrBuffer();
}
public static implicit operator SerializableData(T serializableData) => new SerializableData(serializableData);
@@ -53,7 +54,7 @@ public override async Task WriteAsync(Stream writableStream, IConnectionConfigur
await ms.CopyToAsync(writableStream, BufferSize, cancellationToken).ConfigureAwait(false);
}
if (Type != 0)
- WrittenBytes = ms?.ToArray();
+ WrittenBytes = ms?.ToArrayOrBuffer();
}
}
}
diff --git a/src/Elasticsearch.Net/Utf8Json/Internal/BinaryUtil.cs b/src/Elasticsearch.Net/Utf8Json/Internal/BinaryUtil.cs
index 1aab9555058..49a9ccb33de 100644
--- a/src/Elasticsearch.Net/Utf8Json/Internal/BinaryUtil.cs
+++ b/src/Elasticsearch.Net/Utf8Json/Internal/BinaryUtil.cs
@@ -112,9 +112,8 @@ public static
byte[] FastCloneWithResize(byte[] src, int newSize)
{
if (newSize < 0) throw new ArgumentOutOfRangeException("newSize");
- if (src.Length < newSize) throw new ArgumentException("length < newSize");
-
if (src == null) return new byte[newSize];
+ if (src.Length < newSize) throw new ArgumentException("length < newSize");
byte[] dst = new byte[newSize];
diff --git a/src/Nest/Cat/CatHelpResponseBuilder.cs b/src/Nest/Cat/CatHelpResponseBuilder.cs
index a985dc94142..909552db5eb 100644
--- a/src/Nest/Cat/CatHelpResponseBuilder.cs
+++ b/src/Nest/Cat/CatHelpResponseBuilder.cs
@@ -3,6 +3,7 @@
using System.Threading;
using System.Threading.Tasks;
using Elasticsearch.Net;
+using Elasticsearch.Net.Extensions;
namespace Nest
{
@@ -20,7 +21,7 @@ public override object DeserializeResponse(IElasticsearchSerializer builtInSeria
using (var ms = response.ConnectionConfiguration.MemoryStreamFactory.Create())
{
stream.CopyTo(ms);
- var body = ms.ToArray().Utf8String();
+ var body = ms.Utf8String();
Parse(catResponse, body);
}
@@ -46,7 +47,7 @@ public override async Task