EncodingHelper.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /* Copyright 2020-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Text;
  17. namespace MongoDB.Bson.IO
  18. {
  19. /// <summary>
  20. /// Represents a class that has some helper methods for <see cref="Encoding"/>.
  21. /// </summary>
  22. internal static class EncodingHelper
  23. {
  24. public readonly struct DisposableSegment : IDisposable
  25. {
  26. private IDisposable DisposableData { get; }
  27. public ArraySegment<byte> Segment { get; }
  28. public DisposableSegment(IDisposable disposableData, ArraySegment<byte> segment)
  29. {
  30. DisposableData = disposableData;
  31. Segment = segment;
  32. }
  33. public void Dispose()
  34. {
  35. DisposableData?.Dispose();
  36. }
  37. }
  38. private static readonly ArraySegment<byte> __emptySegment = new ArraySegment<byte>(new byte[0]);
  39. public static DisposableSegment GetBytesUsingThreadStaticBuffer(this Encoding encoding, string value)
  40. {
  41. if (encoding == null)
  42. {
  43. throw new ArgumentNullException(nameof(encoding));
  44. }
  45. if (value == null)
  46. {
  47. throw new ArgumentNullException(nameof(value));
  48. }
  49. var length = value.Length;
  50. if (length == 0)
  51. {
  52. return new DisposableSegment(null, __emptySegment);
  53. }
  54. var maxSize = encoding.GetMaxByteCount(length);
  55. var rentedBuffer = ThreadStaticBuffer.RentBuffer(maxSize);
  56. var size = encoding.GetBytes(value, 0, length, rentedBuffer.Bytes, 0);
  57. var segment = new ArraySegment<byte>(rentedBuffer.Bytes, 0, size);
  58. return new DisposableSegment(rentedBuffer, segment);
  59. }
  60. }
  61. }