From 3cf8f7159c298045c1f2bc595d68662cc0252d8c Mon Sep 17 00:00:00 2001 From: smichtch Date: Tue, 12 Oct 2021 08:46:29 -0700 Subject: [PATCH] [c#] Add OutputBuffer virtual resize buffer method `OutputBuffer` always uses `new byte[]` to create/resize its internal buffer. Implementing a custom `IOutputBuffer` that uses a different allocation scheme requires duplicating a lot of code in `OutputBuffer` and `IntegerHelper`. Add a virtual method `OutputBuffer.ResizeBuffer` that can be overridden to use buffer allocators other than `new byte[]` (e.g. `ArrayPool.Rent()`) --- CHANGELOG.md | 9 +++++++- cs/src/core/io/safe/OutputBuffer.cs | 36 +++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94e4a02473..ac9b31f9c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ different versioning scheme, following the Haskell community's * IDL core version: TBD * C++ version: TBD (minor version bump needed) -* C# NuGet version: TBD +* C# NuGet version: (minor version bump needed) * `gbc` & compiler library: TBD ### C++ ### @@ -34,6 +34,13 @@ different versioning scheme, following the Haskell community's * Added an ability to apply transform to a schema. * Added `noexcept` to `bond::blob`'s non-throwing functions. +### C# ### + +* Added virtual method `OutputBuffer.ResizeBuffer` that can be overridden to + use buffer allocators other than `new byte[]` (e.g. + `ArrayPool.Rent()`). ([Pull request + \#1128](https://github.com/microsoft/bond/pull/1128)) + ## 9.0.5: 2021-04-14 ## * IDL core version: 3.0 diff --git a/cs/src/core/io/safe/OutputBuffer.cs b/cs/src/core/io/safe/OutputBuffer.cs index 1fd83138c7..48e172970a 100644 --- a/cs/src/core/io/safe/OutputBuffer.cs +++ b/cs/src/core/io/safe/OutputBuffer.cs @@ -36,14 +36,22 @@ public virtual long Position } public OutputBuffer(int length = 64 * 1024) - : this(new byte[length]) - {} + : this() + { + buffer = ResizeBuffer(null, length); + this.length = buffer.Length; + } public OutputBuffer(byte[] buffer) + : this() { - Debug.Assert(BitConverter.IsLittleEndian); this.buffer = buffer; length = buffer.Length; + } + + private OutputBuffer() + { + Debug.Assert(BitConverter.IsLittleEndian); position = 0; } @@ -233,7 +241,27 @@ internal virtual void Grow(int count) length = minLength; } - Array.Resize(ref buffer, length); + buffer = ResizeBuffer(buffer, length); + length = buffer.Length; + } + + /// + /// Resize the internal buffer. + /// + /// Existing buffer. + /// New buffer size. + /// The new buffer. + /// + /// + /// Implementations are responsible for ensuring that the new buffer + /// is at least bytes large and that the + /// bytes in are copied to the new buffer. + /// + /// + protected virtual byte[] ResizeBuffer(byte[] buffer, int newSize) + { + Array.Resize(ref buffer, newSize); + return buffer; } #region layouts