forked from Taritsyn/JavaScriptEngineSwitcher
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathJsPropertyId.cs
More file actions
201 lines (173 loc) · 4.96 KB
/
JsPropertyId.cs
File metadata and controls
201 lines (173 loc) · 4.96 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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
using System;
#if NET45_OR_GREATER || NETSTANDARD
using System.Buffers;
using System.Runtime.InteropServices;
#endif
using System.Text;
#if NET40
using PolyfillsForOldDotNet.System.Buffers;
using PolyfillsForOldDotNet.System.Runtime.InteropServices;
#endif
using JavaScriptEngineSwitcher.ChakraCore.Helpers;
namespace JavaScriptEngineSwitcher.ChakraCore.JsRt
{
/// <summary>
/// The property identifier
/// </summary>
/// <remarks>
/// Property identifiers are used to refer to properties of JavaScript objects instead of using
/// strings.
/// </remarks>
internal struct JsPropertyId : IEquatable<JsPropertyId>
{
/// <summary>
/// The id
/// </summary>
private readonly IntPtr _id;
/// <summary>
/// Gets a invalid ID
/// </summary>
public static JsPropertyId Invalid
{
get { return new JsPropertyId(IntPtr.Zero); }
}
/// <summary>
/// Gets a name associated with the property ID
/// </summary>
/// <remarks>
/// <para>
/// Requires an active script context.
/// </para>
/// </remarks>
public string Name
{
get
{
byte[] buffer = null;
UIntPtr bufferSize = UIntPtr.Zero;
UIntPtr length;
JsErrorCode errorCode = NativeMethods.JsCopyPropertyId(this, buffer, bufferSize, out length);
JsErrorHelpers.ThrowIfError(errorCode);
var byteArrayPool = ArrayPool<byte>.Shared;
bufferSize = length;
int bufferLength = (int)bufferSize;
buffer = byteArrayPool.Rent(bufferLength + 1);
buffer[bufferLength] = 0;
string name;
try
{
errorCode = NativeMethods.JsCopyPropertyId(this, buffer, bufferSize, out length);
JsErrorHelpers.ThrowIfError(errorCode);
name = Encoding.UTF8.GetString(buffer, 0, bufferLength);
}
finally
{
byteArrayPool.Return(buffer);
}
return name;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="JsPropertyId"/> struct
/// </summary>
/// <param name="id">The ID</param>
internal JsPropertyId(IntPtr id)
{
_id = id;
}
/// <summary>
/// Gets a property ID associated with the name
/// </summary>
/// <remarks>
/// <para>
/// Property IDs are specific to a context and cannot be used across contexts.
/// </para>
/// <para>
/// Requires an active script context.
/// </para>
/// </remarks>
/// <param name="name">The name of the property ID to get or create.
/// The string is expected to be ASCII / utf8 encoded.
/// The name can be any JavaScript property identifier, including all digits.</param>
/// <returns>The property ID in this runtime for the given name</returns>
public static JsPropertyId FromString(string name)
{
string processedName;
int byteCount;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
processedName = EncodingHelpers.UnicodeToAnsi(name, out byteCount);
}
else
{
processedName = name;
byteCount = Encoding.UTF8.GetByteCount(processedName);
}
JsPropertyId id;
UIntPtr length = new UIntPtr((uint)byteCount);
JsErrorCode errorCode = NativeMethods.JsCreatePropertyId(processedName, length, out id);
JsErrorHelpers.ThrowIfError(errorCode);
return id;
}
/// <summary>
/// The equality operator for property IDs
/// </summary>
/// <param name="left">The first property ID to compare</param>
/// <param name="right">The second property ID to compare</param>
/// <returns>Whether the two property IDs are the same</returns>
public static bool operator ==(JsPropertyId left, JsPropertyId right)
{
return left.Equals(right);
}
/// <summary>
/// The inequality operator for property IDs
/// </summary>
/// <param name="left">The first property ID to compare</param>
/// <param name="right">The second property ID to compare</param>
/// <returns>Whether the two property IDs are not the same</returns>
public static bool operator !=(JsPropertyId left, JsPropertyId right)
{
return !left.Equals(right);
}
/// <summary>
/// Checks for equality between property IDs
/// </summary>
/// <param name="obj">The other property ID to compare</param>
/// <returns>Whether the two property IDs are the same</returns>
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is JsPropertyId && Equals((JsPropertyId)obj);
}
/// <summary>
/// The hash code
/// </summary>
/// <returns>The hash code of the property ID</returns>
public override int GetHashCode()
{
return _id.ToInt32();
}
/// <summary>
/// Converts the property ID to a string
/// </summary>
/// <returns>The name of the property ID</returns>
public override string ToString()
{
return Name;
}
#region IEquatable<T> implementation
/// <summary>
/// Checks for equality between property IDs
/// </summary>
/// <param name="other">The other property ID to compare</param>
/// <returns>Whether the two property IDs are the same</returns>
public bool Equals(JsPropertyId other)
{
return _id == other._id;
}
#endregion
}
}