Skip to content

Commit 29fb877

Browse files
committed
Implemented the base64 helpers
1 parent 608f51d commit 29fb877

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

AngleSharp.Scripting.JavaScript/AngleSharp.Scripting.JavaScript.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
<Compile Include="Dom\Navigator.cs" />
6060
<Compile Include="Dom\RequesterState.cs" />
6161
<Compile Include="Dom\Screen.cs" />
62+
<Compile Include="Dom\WindowBase64.cs" />
6263
<Compile Include="Dom\XmlHttpRequest.cs" />
6364
<Compile Include="Dom\XmlHttpRequestEventTarget.cs" />
6465
<Compile Include="Dom\XmlHttpRequestResponseType.cs" />
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
namespace AngleSharp.Scripting.JavaScript.Dom
2+
{
3+
using AngleSharp.Attributes;
4+
using AngleSharp.Dom;
5+
using System;
6+
7+
/// <summary>
8+
/// Represents the WindowBase64 auxiliary interface implemented by Window.
9+
/// </summary>
10+
[DomName("WindowBase64")]
11+
[DomNoInterfaceObject]
12+
[DomExposed("Window")]
13+
[DomExposed("Worker")]
14+
public sealed class WindowBase64
15+
{
16+
#region Fields
17+
18+
readonly IWindow _window;
19+
20+
#endregion
21+
22+
#region ctor
23+
24+
/// <summary>
25+
/// Creates a new WindowBase64 auxiliary class.
26+
/// </summary>
27+
/// <param name="window">The window to add to.</param>
28+
public WindowBase64(IWindow window)
29+
{
30+
_window = window;
31+
}
32+
33+
#endregion
34+
35+
#region Methods
36+
37+
/// <summary>
38+
/// Takes the input data, in the form of a Unicode string containing
39+
/// only characters in the range U+0000 to U+00FF, each representing a
40+
/// binary byte with values 0x00 to 0xFF respectively, and converts it
41+
/// to its base64 representation, which it returns.
42+
/// </summary>
43+
/// <param name="data">String of bytes.</param>
44+
/// <returns>Base-64 representation.</returns>
45+
[DomName("btoa")]
46+
public String btoa(String data)
47+
{
48+
var content = new Byte[data.Length];
49+
50+
for (int i = 0; i < data.Length; i++)
51+
{
52+
if (data[i] > 255)
53+
throw new DomException(DomError.InvalidCharacter);
54+
55+
content[i] = (Byte)data[i];
56+
}
57+
58+
return Convert.ToBase64String(content);
59+
}
60+
61+
/// <summary>
62+
/// Takes the input data, in the form of a Unicode string containing
63+
/// base64-encoded binary data, decodes it, and returns a string
64+
/// consisting of characters in the range U+0000 to U+00FF, each
65+
/// representing a binary byte with values 0x00 to 0xFF respectively,
66+
/// corresponding to that binary data.
67+
/// </summary>
68+
/// <param name="data">Base-64 representation.</param>
69+
/// <returns>String of bytes.</returns>
70+
[DomName("atob")]
71+
public String atob(String data)
72+
{
73+
var chars = data.ToCharArray();
74+
var length = NormalizeCharacters(ref chars);
75+
var content = Convert.FromBase64CharArray(chars, 0, length);
76+
77+
if (content.Length > chars.Length)
78+
Array.Resize(ref chars, content.Length);
79+
80+
for (int i = 0; i < content.Length; i++)
81+
chars[i] = (Char)content[i];
82+
83+
return new String(chars, 0, content.Length);
84+
}
85+
86+
#endregion
87+
88+
#region Helpers
89+
90+
static Int32 NormalizeCharacters(ref Char[] chars)
91+
{
92+
var length = chars.Length;
93+
ShiftCharacters(chars, ref length);
94+
var rem = length % 4;
95+
96+
if (rem == 0)
97+
{
98+
while (length > 0 && chars[length - 1] == '=')
99+
length--;
100+
101+
rem = length % 4;
102+
}
103+
104+
if (rem == 1)
105+
throw new DomException(DomError.InvalidCharacter);
106+
107+
CheckCharacters(chars, length);
108+
109+
if (rem != 0)
110+
{
111+
if (length + 4 - rem > chars.Length)
112+
Array.Resize(ref chars, length + 4 - rem);
113+
114+
while (rem++ != 4)
115+
chars[length++] = '=';
116+
}
117+
118+
return length;
119+
}
120+
121+
static void CheckCharacters(Char[] chars, Int32 length)
122+
{
123+
for (int i = 0; i < length; i++)
124+
{
125+
if (!IsLegalBase64Char(chars[i]))
126+
throw new DomException(DomError.InvalidCharacter);
127+
}
128+
}
129+
130+
static void ShiftCharacters(Char[] chars, ref Int32 length)
131+
{
132+
var shift = 0;
133+
134+
for (int i = 0; i < length; i++)
135+
{
136+
if (Char.IsWhiteSpace(chars[i]))
137+
{
138+
shift++;
139+
}
140+
else if (shift > 0)
141+
{
142+
var tmp = chars[i];
143+
chars[i] = chars[i - shift];
144+
chars[i - shift] = tmp;
145+
}
146+
}
147+
148+
length -= shift;
149+
}
150+
151+
static Boolean IsLegalBase64Char(Char c)
152+
{
153+
return (c >= 'A' && c <= 'Z') ||
154+
(c >= 'a' && c <= 'z') ||
155+
(c >= '0' && c <= '9') ||
156+
(c == '+' || c == '/');
157+
}
158+
159+
#endregion
160+
}
161+
}

0 commit comments

Comments
 (0)