-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathDataUrl.cs
123 lines (78 loc) · 3.32 KB
/
DataUrl.cs
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
using Gsemac.IO;
using Gsemac.Text.Codecs;
using Gsemac.Text.Codecs.Extensions;
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace Gsemac.Net {
public class DataUrl :
IDataUrl {
// Public members
public IMimeType MimeType { get; }
public bool IsBase64Encoded { get; } = false;
public int DataLength => data.Length;
public DataUrl(string mimeType, byte[] data) :
this(new MimeType(mimeType), data) {
}
public DataUrl(IMimeType mimeType, byte[] data) :
this(mimeType, data, false) {
}
public DataUrl(IMimeType mimeType, byte[] data, bool base64Encode) {
if (mimeType is null)
throw new ArgumentNullException(nameof(mimeType));
if (data is null)
throw new ArgumentNullException(nameof(data));
this.data = data;
MimeType = mimeType;
IsBase64Encoded = base64Encode;
}
public Stream GetDataStream() {
return new MemoryStream(data, writable: false);
}
public override string ToString() {
StringBuilder sb = new StringBuilder();
sb.Append("data:");
if (MimeType is object)
sb.Append(MimeType.ToString());
if (IsBase64Encoded)
sb.Append(";base64");
sb.Append(',');
if (IsBase64Encoded)
sb.Append(Base64.EncodeString(data));
else
sb.Append(Uri.EscapeDataString(Encoding.UTF8.GetString(data)));
return sb.ToString();
}
public static DataUrl Parse(string value) {
if (TryParse(value, out DataUrl result))
return result;
throw new ArgumentException(Properties.ExceptionMessages.MalformedDataUrl);
}
public static bool TryParse(string value, out DataUrl dataUrl) {
dataUrl = null;
if (!string.IsNullOrWhiteSpace(value)) {
Match match = new Regex("^data:(?<mimetype>.*?)(?<base64>;base64)?,(?<data>.*?$)")
.Match(value);
if (match.Success) {
string mimeTypeStr = match.Groups["mimetype"].Value;
string dataStr = match.Groups["data"].Value;
bool base64Encoded = !string.IsNullOrWhiteSpace(match.Groups["base64"].Value);
// If the MIME type is omitted, it defaults to "text/plain;charset=US-ASCII".
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
if (string.IsNullOrWhiteSpace(mimeTypeStr))
mimeTypeStr = "text/plain;charset=US-ASCII";
if (IO.MimeType.TryParse(mimeTypeStr, out MimeType mimeType)) {
byte[] data = base64Encoded ?
Base64.GetDecoder().Decode(dataStr) :
Encoding.UTF8.GetBytes(Uri.UnescapeDataString(dataStr));
dataUrl = new DataUrl(mimeType, data, base64Encode: base64Encoded);
}
}
}
return dataUrl is object;
}
// Private members
private readonly byte[] data;
}
}