forked from Taritsyn/JavaScriptEngineSwitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJsPooledArrayBuffer.cs
More file actions
129 lines (109 loc) · 2.91 KB
/
JsPooledArrayBuffer.cs
File metadata and controls
129 lines (109 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
#if NET45 || NET471 || NETSTANDARD || NETCOREAPP2_1
using System.Buffers;
#endif
using System.Text;
#if NET40
using PolyfillsForOldDotNet.System.Buffers;
#endif
namespace JavaScriptEngineSwitcher.ChakraCore.JsRt
{
/// <summary>
/// Wrapper for the Javascript ArrayBuffer object that is created from byte array stored in the pool.
/// When this wrapper is disposed, byte array will be returned to the pool.
/// </summary>
internal sealed class JsPooledArrayBuffer : IDisposable
{
/// <summary>
/// The Javascript ArrayBuffer object
/// </summary>
private readonly JsValue _value;
/// <summary>
/// Byte array returned from the pool
/// </summary>
private byte[] _pooledBytes;
/// <summary>
/// Flag indicating whether this object is disposed
/// </summary>
private bool _disposed;
/// <summary>
/// Gets a Javascript ArrayBuffer object
/// </summary>
public JsValue Value
{
get { return _value; }
}
/// <summary>
/// Constructs an instance of wrapper for the Javascript ArrayBuffer
/// </summary>
/// <param name="value">The Javascript ArrayBuffer object</param>
/// <param name="pooledBytes">Byte array returned from the pool</param>
private JsPooledArrayBuffer(JsValue value, byte[] pooledBytes)
{
_value = value;
_pooledBytes = pooledBytes;
_disposed = false;
}
/// <summary>
/// Creates a new wrapper for the Javascript ArrayBuffer
/// </summary>
/// <param name="value">String value</param>
/// <param name="encoding">Character encoding</param>
/// <returns>Instance of wrapper for the Javascript ArrayBuffer</returns>
public static JsPooledArrayBuffer Create(string value, Encoding encoding)
{
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
if (encoding == null)
{
throw new ArgumentNullException(nameof(encoding));
}
var byteArrayPool = ArrayPool<byte>.Shared;
int bufferLength = encoding.GetByteCount(value);
byte[] buffer = byteArrayPool.Rent(bufferLength);
JsValue bufferValue;
JsErrorCode errorCode;
try
{
unsafe
{
fixed (char* pValue = value)
fixed (byte* pBuffer = buffer)
{
encoding.GetBytes(pValue, value.Length, pBuffer, bufferLength);
errorCode = NativeMethods.JsCreateExternalArrayBuffer((IntPtr)pBuffer, (uint)bufferLength,
null, IntPtr.Zero, out bufferValue);
}
}
JsErrorHelpers.ThrowIfError(errorCode);
bufferValue.AddRef();
}
catch
{
byteArrayPool.Return(buffer);
throw;
}
return new JsPooledArrayBuffer(bufferValue, buffer);
}
#region IDisposable implementation
/// <summary>
/// Returns a rented byte array to the pool
/// </summary>
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
_value.Release();
if (_pooledBytes != null)
{
ArrayPool<byte>.Shared.Return(_pooledBytes);
_pooledBytes = null;
}
}
}
#endregion
}
}