Created
May 9, 2017 15:58
-
-
Save soeminnminn/dbf84ab4200db357cf88a5e90e659d75 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using System.Collections; | |
using System.Globalization; | |
using System.IO; | |
using System.Runtime.Serialization; | |
using System.Collections.Specialized; | |
namespace S16.Text | |
{ | |
public static class HtmlUtility | |
{ | |
#region Variables | |
private static char[] s_entityEndingChars = new char[] { ';', '&' }; | |
#endregion | |
#region Private Methods | |
private static int HexToInt(char h) | |
{ | |
if ((h >= '0') && (h <= '9')) | |
{ | |
return (h - '0'); | |
} | |
if ((h >= 'a') && (h <= 'f')) | |
{ | |
return ((h - 'a') + 10); | |
} | |
if ((h >= 'A') && (h <= 'F')) | |
{ | |
return ((h - 'A') + 10); | |
} | |
return -1; | |
} | |
private static unsafe int IndexOfHtmlAttributeEncodingChars(string s, int startPos) | |
{ | |
int num = s.Length - startPos; | |
//fixed (char* str = ((char*)s)) | |
fixed (char* str = s.ToCharArray()) | |
{ | |
char* chPtr = str; | |
char* chPtr2 = chPtr + startPos; | |
while (num > 0) | |
{ | |
char ch = chPtr2[0]; | |
if (ch <= '<') | |
{ | |
switch (ch) | |
{ | |
case '"': | |
case '&': | |
case '<': | |
return (s.Length - num); | |
} | |
} | |
chPtr2++; | |
num--; | |
} | |
} | |
return -1; | |
} | |
private static unsafe int IndexOfHtmlEncodingChars(string s, int startPos) | |
{ | |
int num = s.Length - startPos; | |
//fixed (char* str = ((char*)s)) | |
fixed (char* str = s.ToCharArray()) | |
{ | |
char* chPtr = str; | |
char* chPtr2 = chPtr + startPos; | |
while (num > 0) | |
{ | |
char ch = chPtr2[0]; | |
if (ch <= '>') | |
{ | |
switch (ch) | |
{ | |
case '<': | |
case '>': | |
case '"': | |
case '&': | |
return (s.Length - num); | |
case '=': | |
goto Label_007A; | |
} | |
} | |
else if ((ch >= '\x00a0') && (ch < 'Ā')) | |
{ | |
return (s.Length - num); | |
} | |
Label_007A: | |
chPtr2++; | |
num--; | |
} | |
} | |
return -1; | |
} | |
private static bool IsNonAsciiByte(byte b) | |
{ | |
if (b < 0x7f) | |
{ | |
return (b < 0x20); | |
} | |
return true; | |
} | |
private static byte[] UrlDecodeBytesFromBytesInternal(byte[] buf, int offset, int count) | |
{ | |
int length = 0; | |
byte[] sourceArray = new byte[count]; | |
for (int i = 0; i < count; i++) | |
{ | |
int index = offset + i; | |
byte num4 = buf[index]; | |
if (num4 == 0x2b) | |
{ | |
num4 = 0x20; | |
} | |
else if ((num4 == 0x25) && (i < (count - 2))) | |
{ | |
int num5 = HexToInt((char)buf[index + 1]); | |
int num6 = HexToInt((char)buf[index + 2]); | |
if ((num5 >= 0) && (num6 >= 0)) | |
{ | |
num4 = (byte)((num5 << 4) | num6); | |
i += 2; | |
} | |
} | |
sourceArray[length++] = num4; | |
} | |
if (length < sourceArray.Length) | |
{ | |
byte[] destinationArray = new byte[length]; | |
Array.Copy(sourceArray, destinationArray, length); | |
sourceArray = destinationArray; | |
} | |
return sourceArray; | |
} | |
private static string UrlDecodeStringFromBytesInternal(byte[] buf, int offset, int count, Encoding e) | |
{ | |
UrlDecoder decoder = new UrlDecoder(count, e); | |
for (int i = 0; i < count; i++) | |
{ | |
int index = offset + i; | |
byte b = buf[index]; | |
if (b == 0x2b) | |
{ | |
b = 0x20; | |
} | |
else if ((b == 0x25) && (i < (count - 2))) | |
{ | |
if ((buf[index + 1] == 0x75) && (i < (count - 5))) | |
{ | |
int num4 = HexToInt((char)buf[index + 2]); | |
int num5 = HexToInt((char)buf[index + 3]); | |
int num6 = HexToInt((char)buf[index + 4]); | |
int num7 = HexToInt((char)buf[index + 5]); | |
if (((num4 < 0) || (num5 < 0)) || ((num6 < 0) || (num7 < 0))) | |
{ | |
goto Label_00DA; | |
} | |
char ch = (char)((((num4 << 12) | (num5 << 8)) | (num6 << 4)) | num7); | |
i += 5; | |
decoder.AddChar(ch); | |
continue; | |
} | |
int num8 = HexToInt((char)buf[index + 1]); | |
int num9 = HexToInt((char)buf[index + 2]); | |
if ((num8 >= 0) && (num9 >= 0)) | |
{ | |
b = (byte)((num8 << 4) | num9); | |
i += 2; | |
} | |
} | |
Label_00DA: | |
decoder.AddByte(b); | |
} | |
return decoder.GetString(); | |
} | |
private static string UrlDecodeStringFromStringInternal(string s, Encoding e) | |
{ | |
int length = s.Length; | |
UrlDecoder decoder = new UrlDecoder(length, e); | |
for (int i = 0; i < length; i++) | |
{ | |
char ch = s[i]; | |
if (ch == '+') | |
{ | |
ch = ' '; | |
} | |
else if ((ch == '%') && (i < (length - 2))) | |
{ | |
if ((s[i + 1] == 'u') && (i < (length - 5))) | |
{ | |
int num3 = HexToInt(s[i + 2]); | |
int num4 = HexToInt(s[i + 3]); | |
int num5 = HexToInt(s[i + 4]); | |
int num6 = HexToInt(s[i + 5]); | |
if (((num3 < 0) || (num4 < 0)) || ((num5 < 0) || (num6 < 0))) | |
{ | |
goto Label_0106; | |
} | |
ch = (char)((((num3 << 12) | (num4 << 8)) | (num5 << 4)) | num6); | |
i += 5; | |
decoder.AddChar(ch); | |
continue; | |
} | |
int num7 = HexToInt(s[i + 1]); | |
int num8 = HexToInt(s[i + 2]); | |
if ((num7 >= 0) && (num8 >= 0)) | |
{ | |
byte b = (byte)((num7 << 4) | num8); | |
i += 2; | |
decoder.AddByte(b); | |
continue; | |
} | |
} | |
Label_0106: | |
if ((ch & 0xff80) == 0) | |
{ | |
decoder.AddByte((byte)ch); | |
} | |
else | |
{ | |
decoder.AddChar(ch); | |
} | |
} | |
return decoder.GetString(); | |
} | |
private static byte[] UrlEncodeBytesToBytesInternal(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) | |
{ | |
int num = 0; | |
int num2 = 0; | |
for (int i = 0; i < count; i++) | |
{ | |
char ch = (char)bytes[offset + i]; | |
if (ch == ' ') | |
{ | |
num++; | |
} | |
else if (!IsSafe(ch)) | |
{ | |
num2++; | |
} | |
} | |
if ((!alwaysCreateReturnValue && (num == 0)) && (num2 == 0)) | |
{ | |
return bytes; | |
} | |
byte[] buffer = new byte[count + (num2 * 2)]; | |
int num4 = 0; | |
for (int j = 0; j < count; j++) | |
{ | |
byte num6 = bytes[offset + j]; | |
char ch2 = (char)num6; | |
if (IsSafe(ch2)) | |
{ | |
buffer[num4++] = num6; | |
} | |
else if (ch2 == ' ') | |
{ | |
buffer[num4++] = 0x2b; | |
} | |
else | |
{ | |
buffer[num4++] = 0x25; | |
buffer[num4++] = (byte)IntToHex((num6 >> 4) & 15); | |
buffer[num4++] = (byte)IntToHex(num6 & 15); | |
} | |
} | |
return buffer; | |
} | |
private static byte[] UrlEncodeBytesToBytesInternalNonAscii(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue) | |
{ | |
int num = 0; | |
for (int i = 0; i < count; i++) | |
{ | |
if (IsNonAsciiByte(bytes[offset + i])) | |
{ | |
num++; | |
} | |
} | |
if (!alwaysCreateReturnValue && (num == 0)) | |
{ | |
return bytes; | |
} | |
byte[] buffer = new byte[count + (num * 2)]; | |
int num3 = 0; | |
for (int j = 0; j < count; j++) | |
{ | |
byte b = bytes[offset + j]; | |
if (IsNonAsciiByte(b)) | |
{ | |
buffer[num3++] = 0x25; | |
buffer[num3++] = (byte)IntToHex((b >> 4) & 15); | |
buffer[num3++] = (byte)IntToHex(b & 15); | |
} | |
else | |
{ | |
buffer[num3++] = b; | |
} | |
} | |
return buffer; | |
} | |
private static string UrlEncodeUnicodeStringToStringInternal(string s, bool ignoreAscii) | |
{ | |
int length = s.Length; | |
StringBuilder builder = new StringBuilder(length); | |
for (int i = 0; i < length; i++) | |
{ | |
char ch = s[i]; | |
if ((ch & 0xff80) == 0) | |
{ | |
if (ignoreAscii || IsSafe(ch)) | |
{ | |
builder.Append(ch); | |
} | |
else if (ch == ' ') | |
{ | |
builder.Append('+'); | |
} | |
else | |
{ | |
builder.Append('%'); | |
builder.Append(IntToHex((ch >> 4) & '\x000f')); | |
builder.Append(IntToHex(ch & '\x000f')); | |
} | |
} | |
else | |
{ | |
builder.Append("%u"); | |
builder.Append(IntToHex((ch >> 12) & '\x000f')); | |
builder.Append(IntToHex((ch >> 8) & '\x000f')); | |
builder.Append(IntToHex((ch >> 4) & '\x000f')); | |
builder.Append(IntToHex(ch & '\x000f')); | |
} | |
} | |
return builder.ToString(); | |
} | |
private static string UrlEncodeNonAscii(string str, Encoding e) | |
{ | |
if (string.IsNullOrEmpty(str)) | |
{ | |
return str; | |
} | |
if (e == null) | |
{ | |
e = Encoding.UTF8; | |
} | |
byte[] bytes = e.GetBytes(str); | |
bytes = UrlEncodeBytesToBytesInternalNonAscii(bytes, 0, bytes.Length, false); | |
return Encoding.ASCII.GetString(bytes); | |
} | |
private static string UrlEncodeSpaces(string str) | |
{ | |
if ((str != null) && (str.IndexOf(' ') >= 0)) | |
{ | |
str = str.Replace(" ", "%20"); | |
} | |
return str; | |
} | |
private static char IntToHex(int n) | |
{ | |
if (n <= 9) | |
{ | |
return (char)(n + 0x30); | |
} | |
return (char)((n - 10) + 0x61); | |
} | |
private static bool IsSafe(char ch) | |
{ | |
if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9'))) | |
{ | |
return true; | |
} | |
switch (ch) | |
{ | |
case '\'': | |
case '(': | |
case ')': | |
case '*': | |
case '-': | |
case '.': | |
case '_': | |
case '!': | |
return true; | |
} | |
return false; | |
} | |
#endregion | |
#region Public Methods | |
public static string AspCompatUrlEncode(string s) | |
{ | |
s = UrlEncode(s); | |
s = s.Replace("!", "%21"); | |
s = s.Replace("*", "%2A"); | |
s = s.Replace("(", "%28"); | |
s = s.Replace(")", "%29"); | |
s = s.Replace("-", "%2D"); | |
s = s.Replace(".", "%2E"); | |
s = s.Replace("_", "%5F"); | |
s = s.Replace(@"\", "%5C"); | |
return s; | |
} | |
public static string FormatHttpCookieDateTime(DateTime dt) | |
{ | |
if ((dt < DateTime.MaxValue.AddDays(-1.0)) && (dt > DateTime.MinValue.AddDays(1.0))) | |
{ | |
dt = dt.ToUniversalTime(); | |
} | |
return dt.ToString("ddd, dd-MMM-yyyy HH':'mm':'ss 'GMT'", DateTimeFormatInfo.InvariantInfo); | |
} | |
public static string FormatHttpDateTime(DateTime dt) | |
{ | |
if ((dt < DateTime.MaxValue.AddDays(-1.0)) && (dt > DateTime.MinValue.AddDays(1.0))) | |
{ | |
dt = dt.ToUniversalTime(); | |
} | |
return dt.ToString("R", DateTimeFormatInfo.InvariantInfo); | |
} | |
public static string FormatHttpDateTimeUtc(DateTime dt) | |
{ | |
return dt.ToString("R", DateTimeFormatInfo.InvariantInfo); | |
} | |
public static string FormatPlainTextAsHtml(string s) | |
{ | |
if (s == null) | |
{ | |
return null; | |
} | |
StringBuilder sb = new StringBuilder(); | |
StringWriter output = new StringWriter(sb); | |
FormatPlainTextAsHtml(s, output); | |
return sb.ToString(); | |
} | |
public static void FormatPlainTextAsHtml(string s, TextWriter output) | |
{ | |
if (s != null) | |
{ | |
int length = s.Length; | |
char ch = '\0'; | |
for (int i = 0; i < length; i++) | |
{ | |
char ch2 = s[i]; | |
switch (ch2) | |
{ | |
case '\n': | |
output.Write("<br>"); | |
goto Label_0113; | |
case '\r': | |
goto Label_0113; | |
case ' ': | |
if (ch != ' ') | |
{ | |
break; | |
} | |
output.Write(" "); | |
goto Label_0113; | |
case '"': | |
output.Write("""); | |
goto Label_0113; | |
case '&': | |
output.Write("&"); | |
goto Label_0113; | |
case '<': | |
output.Write("<"); | |
goto Label_0113; | |
case '>': | |
output.Write(">"); | |
goto Label_0113; | |
default: | |
if ((ch2 >= '\x00a0') && (ch2 < 'Ā')) | |
{ | |
output.Write("&#"); | |
output.Write(((int)ch2).ToString(NumberFormatInfo.InvariantInfo)); | |
output.Write(';'); | |
} | |
else | |
{ | |
output.Write(ch2); | |
} | |
goto Label_0113; | |
} | |
output.Write(ch2); | |
Label_0113: | |
ch = ch2; | |
} | |
} | |
} | |
public static string FormatPlainTextSpacesAsHtml(string s) | |
{ | |
if (s == null) | |
{ | |
return null; | |
} | |
StringBuilder sb = new StringBuilder(); | |
StringWriter writer = new StringWriter(sb); | |
int length = s.Length; | |
for (int i = 0; i < length; i++) | |
{ | |
char ch = s[i]; | |
if (ch == ' ') | |
{ | |
writer.Write(" "); | |
} | |
else | |
{ | |
writer.Write(ch); | |
} | |
} | |
return sb.ToString(); | |
} | |
public static string HtmlAttributeEncode(string s) | |
{ | |
if (s == null) | |
{ | |
return null; | |
} | |
int num = IndexOfHtmlAttributeEncodingChars(s, 0); | |
if (num == -1) | |
{ | |
return s; | |
} | |
StringBuilder builder = new StringBuilder(s.Length + 5); | |
int length = s.Length; | |
int startIndex = 0; | |
Label_002A: | |
if (num > startIndex) | |
{ | |
builder.Append(s, startIndex, num - startIndex); | |
} | |
switch (s[num]) | |
{ | |
case '"': | |
builder.Append("""); | |
break; | |
case '&': | |
builder.Append("&"); | |
break; | |
case '<': | |
builder.Append("<"); | |
break; | |
} | |
startIndex = num + 1; | |
if (startIndex < length) | |
{ | |
num = IndexOfHtmlAttributeEncodingChars(s, startIndex); | |
if (num != -1) | |
{ | |
goto Label_002A; | |
} | |
builder.Append(s, startIndex, length - startIndex); | |
} | |
return builder.ToString(); | |
} | |
public static unsafe void HtmlAttributeEncode(string s, TextWriter output) | |
{ | |
if (s != null) | |
{ | |
int num = IndexOfHtmlAttributeEncodingChars(s, 0); | |
if (num == -1) | |
{ | |
output.Write(s); | |
} | |
else | |
{ | |
int num2 = s.Length - num; | |
//fixed (char* str = ((char*)s)) | |
fixed (char* str = s.ToCharArray()) | |
{ | |
char* chPtr = str; | |
char* chPtr2 = chPtr; | |
while (num-- > 0) | |
{ | |
chPtr2++; | |
output.Write(chPtr2[0]); | |
} | |
while (num2-- > 0) | |
{ | |
chPtr2++; | |
char ch = chPtr2[0]; | |
if (ch > '<') | |
{ | |
goto Label_00A2; | |
} | |
char ch2 = ch; | |
if (ch2 != '"') | |
{ | |
if (ch2 == '&') | |
{ | |
goto Label_008B; | |
} | |
if (ch2 != '<') | |
{ | |
goto Label_0098; | |
} | |
output.Write("<"); | |
} | |
else | |
{ | |
output.Write("""); | |
} | |
continue; | |
Label_008B: | |
output.Write("&"); | |
continue; | |
Label_0098: | |
output.Write(ch); | |
continue; | |
Label_00A2: | |
output.Write(ch); | |
} | |
} | |
} | |
} | |
} | |
public static string HtmlDecode(string s) | |
{ | |
if (s == null) | |
{ | |
return null; | |
} | |
if (s.IndexOf('&') < 0) | |
{ | |
return s; | |
} | |
StringBuilder sb = new StringBuilder(); | |
StringWriter output = new StringWriter(sb); | |
HtmlDecode(s, output); | |
return sb.ToString(); | |
} | |
public static void HtmlDecode(string s, TextWriter output) | |
{ | |
if (s != null) | |
{ | |
if (s.IndexOf('&') < 0) | |
{ | |
output.Write(s); | |
} | |
else | |
{ | |
int length = s.Length; | |
for (int i = 0; i < length; i++) | |
{ | |
char ch = s[i]; | |
if (ch == '&') | |
{ | |
int num3 = s.IndexOfAny(s_entityEndingChars, i + 1); | |
if ((num3 > 0) && (s[num3] == ';')) | |
{ | |
string entity = s.Substring(i + 1, (num3 - i) - 1); | |
if ((entity.Length > 1) && (entity[0] == '#')) | |
{ | |
try | |
{ | |
if ((entity[1] == 'x') || (entity[1] == 'X')) | |
{ | |
ch = (char)int.Parse(entity.Substring(2), NumberStyles.AllowHexSpecifier); | |
} | |
else | |
{ | |
ch = (char)int.Parse(entity.Substring(1)); | |
} | |
i = num3; | |
} | |
catch (FormatException) | |
{ | |
i++; | |
} | |
catch (ArgumentException) | |
{ | |
i++; | |
} | |
} | |
else | |
{ | |
i = num3; | |
char ch2 = HtmlEntities.Lookup(entity); | |
if (ch2 != '\0') | |
{ | |
ch = ch2; | |
} | |
else | |
{ | |
output.Write('&'); | |
output.Write(entity); | |
output.Write(';'); | |
goto Label_0103; | |
} | |
} | |
} | |
} | |
output.Write(ch); | |
Label_0103: ; | |
} | |
} | |
} | |
} | |
public static string HtmlEncode(string s) | |
{ | |
if (s == null) | |
{ | |
return null; | |
} | |
int num = IndexOfHtmlEncodingChars(s, 0); | |
if (num == -1) | |
{ | |
return s; | |
} | |
StringBuilder builder = new StringBuilder(s.Length + 5); | |
int length = s.Length; | |
int startIndex = 0; | |
Label_002A: | |
if (num > startIndex) | |
{ | |
builder.Append(s, startIndex, num - startIndex); | |
} | |
char ch = s[num]; | |
if (ch > '>') | |
{ | |
builder.Append("&#"); | |
builder.Append(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); | |
builder.Append(';'); | |
} | |
else | |
{ | |
char ch2 = ch; | |
if (ch2 != '"') | |
{ | |
switch (ch2) | |
{ | |
case '<': | |
builder.Append("<"); | |
goto Label_00D5; | |
case '=': | |
goto Label_00D5; | |
case '>': | |
builder.Append(">"); | |
goto Label_00D5; | |
case '&': | |
builder.Append("&"); | |
goto Label_00D5; | |
} | |
} | |
else | |
{ | |
builder.Append("""); | |
} | |
} | |
Label_00D5: | |
startIndex = num + 1; | |
if (startIndex < length) | |
{ | |
num = IndexOfHtmlEncodingChars(s, startIndex); | |
if (num != -1) | |
{ | |
goto Label_002A; | |
} | |
builder.Append(s, startIndex, length - startIndex); | |
} | |
return builder.ToString(); | |
} | |
public static unsafe void HtmlEncode(string s, TextWriter output) | |
{ | |
if (s != null) | |
{ | |
int num = IndexOfHtmlEncodingChars(s, 0); | |
if (num == -1) | |
{ | |
output.Write(s); | |
} | |
else | |
{ | |
int num2 = s.Length - num; | |
//fixed (char* str = ((char*)s)) | |
fixed (char* str = s.ToCharArray()) | |
{ | |
char* chPtr = str; | |
char* chPtr2 = chPtr; | |
while (num-- > 0) | |
{ | |
chPtr2++; | |
output.Write(chPtr2[0]); | |
} | |
while (num2-- > 0) | |
{ | |
chPtr2++; | |
char ch = chPtr2[0]; | |
if (ch > '>') | |
{ | |
goto Label_00C4; | |
} | |
char ch2 = ch; | |
if (ch2 != '"') | |
{ | |
switch (ch2) | |
{ | |
case '<': | |
{ | |
output.Write("<"); | |
continue; | |
} | |
case '=': | |
goto Label_00BA; | |
case '>': | |
{ | |
output.Write(">"); | |
continue; | |
} | |
case '&': | |
goto Label_00AD; | |
} | |
goto Label_00BA; | |
} | |
output.Write("""); | |
continue; | |
Label_00AD: | |
output.Write("&"); | |
continue; | |
Label_00BA: | |
output.Write(ch); | |
continue; | |
Label_00C4: | |
if ((ch >= '\x00a0') && (ch < 'Ā')) | |
{ | |
output.Write("&#"); | |
output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo)); | |
output.Write(';'); | |
} | |
else | |
{ | |
output.Write(ch); | |
} | |
} | |
} | |
} | |
} | |
} | |
public static NameValueCollection ParseQueryString(string query) | |
{ | |
return ParseQueryString(query, Encoding.UTF8); | |
} | |
public static NameValueCollection ParseQueryString(string query, Encoding encoding) | |
{ | |
if (query == null) | |
{ | |
throw new ArgumentNullException("query"); | |
} | |
if (encoding == null) | |
{ | |
throw new ArgumentNullException("encoding"); | |
} | |
if ((query.Length > 0) && (query[0] == '?')) | |
{ | |
query = query.Substring(1); | |
} | |
return new HttpValueCollection(query, false, true, encoding); | |
} | |
public static string UrlDecode(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlDecode(str, Encoding.UTF8); | |
} | |
public static string UrlDecode(byte[] bytes, Encoding e) | |
{ | |
if (bytes == null) | |
{ | |
return null; | |
} | |
return UrlDecode(bytes, 0, bytes.Length, e); | |
} | |
public static string UrlDecode(string str, Encoding e) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlDecodeStringFromStringInternal(str, e); | |
} | |
public static string UrlDecode(byte[] bytes, int offset, int count, Encoding e) | |
{ | |
if ((bytes == null) && (count == 0)) | |
{ | |
return null; | |
} | |
if (bytes == null) | |
{ | |
throw new ArgumentNullException("bytes"); | |
} | |
if ((offset < 0) || (offset > bytes.Length)) | |
{ | |
throw new ArgumentOutOfRangeException("offset"); | |
} | |
if ((count < 0) || ((offset + count) > bytes.Length)) | |
{ | |
throw new ArgumentOutOfRangeException("count"); | |
} | |
return UrlDecodeStringFromBytesInternal(bytes, offset, count, e); | |
} | |
public static byte[] UrlDecodeToBytes(byte[] bytes) | |
{ | |
if (bytes == null) | |
{ | |
return null; | |
} | |
return UrlDecodeToBytes(bytes, 0, (bytes != null) ? bytes.Length : 0); | |
} | |
public static byte[] UrlDecodeToBytes(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlDecodeToBytes(str, Encoding.UTF8); | |
} | |
public static byte[] UrlDecodeToBytes(string str, Encoding e) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlDecodeToBytes(e.GetBytes(str)); | |
} | |
public static byte[] UrlDecodeToBytes(byte[] bytes, int offset, int count) | |
{ | |
if ((bytes == null) && (count == 0)) | |
{ | |
return null; | |
} | |
if (bytes == null) | |
{ | |
throw new ArgumentNullException("bytes"); | |
} | |
if ((offset < 0) || (offset > bytes.Length)) | |
{ | |
throw new ArgumentOutOfRangeException("offset"); | |
} | |
if ((count < 0) || ((offset + count) > bytes.Length)) | |
{ | |
throw new ArgumentOutOfRangeException("count"); | |
} | |
return UrlDecodeBytesFromBytesInternal(bytes, offset, count); | |
} | |
public static string UrlEncode(byte[] bytes) | |
{ | |
if (bytes == null) | |
{ | |
return null; | |
} | |
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes)); | |
} | |
public static string UrlEncode(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlEncode(str, Encoding.UTF8); | |
} | |
public static string UrlEncode(string str, Encoding e) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e)); | |
} | |
public static string UrlEncode(byte[] bytes, int offset, int count) | |
{ | |
if (bytes == null) | |
{ | |
return null; | |
} | |
return Encoding.ASCII.GetString(UrlEncodeToBytes(bytes, offset, count)); | |
} | |
public static byte[] UrlEncodeToBytes(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlEncodeToBytes(str, Encoding.UTF8); | |
} | |
public static byte[] UrlEncodeToBytes(byte[] bytes) | |
{ | |
if (bytes == null) | |
{ | |
return null; | |
} | |
return UrlEncodeToBytes(bytes, 0, bytes.Length); | |
} | |
public static byte[] UrlEncodeToBytes(string str, Encoding e) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
byte[] bytes = e.GetBytes(str); | |
return UrlEncodeBytesToBytesInternal(bytes, 0, bytes.Length, false); | |
} | |
public static byte[] UrlEncodeToBytes(byte[] bytes, int offset, int count) | |
{ | |
if ((bytes == null) && (count == 0)) | |
{ | |
return null; | |
} | |
if (bytes == null) | |
{ | |
throw new ArgumentNullException("bytes"); | |
} | |
if ((offset < 0) || (offset > bytes.Length)) | |
{ | |
throw new ArgumentOutOfRangeException("offset"); | |
} | |
if ((count < 0) || ((offset + count) > bytes.Length)) | |
{ | |
throw new ArgumentOutOfRangeException("count"); | |
} | |
return UrlEncodeBytesToBytesInternal(bytes, offset, count, true); | |
} | |
public static string UrlEncodeUnicode(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return UrlEncodeUnicodeStringToStringInternal(str, false); | |
} | |
public static byte[] UrlEncodeUnicodeToBytes(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
return Encoding.ASCII.GetBytes(UrlEncodeUnicode(str)); | |
} | |
public static string UrlPathEncode(string str) | |
{ | |
if (str == null) | |
{ | |
return null; | |
} | |
int index = str.IndexOf('?'); | |
if (index >= 0) | |
{ | |
return (UrlPathEncode(str.Substring(0, index)) + str.Substring(index)); | |
} | |
return UrlEncodeSpaces(UrlEncodeNonAscii(str, Encoding.UTF8)); | |
} | |
#endregion | |
#region Nested Types | |
#region UrlDecoder Class | |
private class UrlDecoder | |
{ | |
#region Variables | |
private int _bufferSize; | |
private byte[] _byteBuffer; | |
private char[] _charBuffer; | |
private Encoding _encoding; | |
private int _numBytes; | |
private int _numChars; | |
#endregion | |
#region Constructor | |
internal UrlDecoder(int bufferSize, Encoding encoding) | |
{ | |
this._bufferSize = bufferSize; | |
this._encoding = encoding; | |
this._charBuffer = new char[bufferSize]; | |
} | |
#endregion | |
#region Internal Methods | |
internal void AddByte(byte b) | |
{ | |
if (this._byteBuffer == null) | |
{ | |
this._byteBuffer = new byte[this._bufferSize]; | |
} | |
this._byteBuffer[this._numBytes++] = b; | |
} | |
internal void AddChar(char ch) | |
{ | |
if (this._numBytes > 0) | |
{ | |
this.FlushBytes(); | |
} | |
this._charBuffer[this._numChars++] = ch; | |
} | |
internal string GetString() | |
{ | |
if (this._numBytes > 0) | |
{ | |
this.FlushBytes(); | |
} | |
if (this._numChars > 0) | |
{ | |
return new string(this._charBuffer, 0, this._numChars); | |
} | |
return string.Empty; | |
} | |
#endregion | |
#region Private Methods | |
private void FlushBytes() | |
{ | |
if (this._numBytes > 0) | |
{ | |
this._numChars += this._encoding.GetChars(this._byteBuffer, 0, this._numBytes, this._charBuffer, this._numChars); | |
this._numBytes = 0; | |
} | |
} | |
#endregion | |
} | |
#endregion | |
#region HttpValueCollection Class | |
[Serializable] | |
private class HttpValueCollection : NameValueCollection | |
{ | |
#region Constructor | |
internal HttpValueCollection() | |
: base(StringComparer.OrdinalIgnoreCase) | |
{ | |
} | |
internal HttpValueCollection(int capacity) | |
: base(capacity, (IEqualityComparer)StringComparer.OrdinalIgnoreCase) | |
{ | |
} | |
protected HttpValueCollection(SerializationInfo info, StreamingContext context) | |
: base(info, context) | |
{ | |
} | |
internal HttpValueCollection(string str, bool readOnly, bool urlencoded, Encoding encoding) | |
: base(StringComparer.OrdinalIgnoreCase) | |
{ | |
if (!string.IsNullOrEmpty(str)) | |
{ | |
this.FillFromString(str, urlencoded, encoding); | |
} | |
base.IsReadOnly = readOnly; | |
} | |
#endregion | |
#region Override Methods | |
public override string ToString() | |
{ | |
return this.ToString(true); | |
} | |
#endregion | |
#region Internal Methods | |
//internal void Add(HttpCookieCollection c) | |
//{ | |
// int count = c.Count; | |
// for (int i = 0; i < count; i++) | |
// { | |
// HttpCookie cookie = c.Get(i); | |
// base.Add(cookie.Name, cookie.Value); | |
// } | |
//} | |
internal void FillFromEncodedBytes(byte[] bytes, Encoding encoding) | |
{ | |
int num = (bytes != null) ? bytes.Length : 0; | |
for (int i = 0; i < num; i++) | |
{ | |
string str; | |
string str2; | |
int offset = i; | |
int num4 = -1; | |
while (i < num) | |
{ | |
byte num5 = bytes[i]; | |
if (num5 == 0x3d) | |
{ | |
if (num4 < 0) | |
{ | |
num4 = i; | |
} | |
} | |
else if (num5 == 0x26) | |
{ | |
break; | |
} | |
i++; | |
} | |
if (num4 >= 0) | |
{ | |
str = HtmlUtility.UrlDecode(bytes, offset, num4 - offset, encoding); | |
str2 = HtmlUtility.UrlDecode(bytes, num4 + 1, (i - num4) - 1, encoding); | |
} | |
else | |
{ | |
str = null; | |
str2 = HtmlUtility.UrlDecode(bytes, offset, i - offset, encoding); | |
} | |
base.Add(str, str2); | |
if ((i == (num - 1)) && (bytes[i] == 0x26)) | |
{ | |
base.Add(null, string.Empty); | |
} | |
} | |
} | |
internal void FillFromString(string s) | |
{ | |
this.FillFromString(s, false, null); | |
} | |
internal void FillFromString(string s, bool urlencoded, Encoding encoding) | |
{ | |
int num = (s != null) ? s.Length : 0; | |
for (int i = 0; i < num; i++) | |
{ | |
int startIndex = i; | |
int num4 = -1; | |
while (i < num) | |
{ | |
char ch = s[i]; | |
if (ch == '=') | |
{ | |
if (num4 < 0) | |
{ | |
num4 = i; | |
} | |
} | |
else if (ch == '&') | |
{ | |
break; | |
} | |
i++; | |
} | |
string str = null; | |
string str2 = null; | |
if (num4 >= 0) | |
{ | |
str = s.Substring(startIndex, num4 - startIndex); | |
str2 = s.Substring(num4 + 1, (i - num4) - 1); | |
} | |
else | |
{ | |
str2 = s.Substring(startIndex, i - startIndex); | |
} | |
if (urlencoded) | |
{ | |
base.Add(HtmlUtility.UrlDecode(str, encoding), HtmlUtility.UrlDecode(str2, encoding)); | |
} | |
else | |
{ | |
base.Add(str, str2); | |
} | |
if ((i == (num - 1)) && (s[i] == '&')) | |
{ | |
base.Add(null, string.Empty); | |
} | |
} | |
} | |
internal void MakeReadOnly() | |
{ | |
base.IsReadOnly = true; | |
} | |
internal void MakeReadWrite() | |
{ | |
base.IsReadOnly = false; | |
} | |
internal void Reset() | |
{ | |
base.Clear(); | |
} | |
internal virtual string ToString(bool urlencoded) | |
{ | |
return this.ToString(urlencoded, null); | |
} | |
internal virtual string ToString(bool urlencoded, IDictionary excludeKeys) | |
{ | |
int count = this.Count; | |
if (count == 0) | |
{ | |
return string.Empty; | |
} | |
StringBuilder builder = new StringBuilder(); | |
bool flag = (excludeKeys != null) && (excludeKeys["__VIEWSTATE"] != null); | |
for (int i = 0; i < count; i++) | |
{ | |
string key = this.GetKey(i); | |
if (((!flag || (key == null)) || !key.StartsWith("__VIEWSTATE", StringComparison.Ordinal)) && (((excludeKeys == null) || (key == null)) || (excludeKeys[key] == null))) | |
{ | |
string str3; | |
if (urlencoded) | |
{ | |
key = HtmlUtility.UrlEncodeUnicode(key); | |
} | |
string str2 = !string.IsNullOrEmpty(key) ? (key + "=") : string.Empty; | |
ArrayList list = (ArrayList)base.BaseGet(i); | |
int num3 = (list != null) ? list.Count : 0; | |
if (builder.Length > 0) | |
{ | |
builder.Append('&'); | |
} | |
if (num3 == 1) | |
{ | |
builder.Append(str2); | |
str3 = (string)list[0]; | |
if (urlencoded) | |
{ | |
str3 = HtmlUtility.UrlEncodeUnicode(str3); | |
} | |
builder.Append(str3); | |
} | |
else if (num3 == 0) | |
{ | |
builder.Append(str2); | |
} | |
else | |
{ | |
for (int j = 0; j < num3; j++) | |
{ | |
if (j > 0) | |
{ | |
builder.Append('&'); | |
} | |
builder.Append(str2); | |
str3 = (string)list[j]; | |
if (urlencoded) | |
{ | |
str3 = HtmlUtility.UrlEncodeUnicode(str3); | |
} | |
builder.Append(str3); | |
} | |
} | |
} | |
} | |
return builder.ToString(); | |
} | |
#endregion | |
} | |
#endregion | |
#region HtmlEntities Class | |
private class HtmlEntities | |
{ | |
#region Variables | |
private static string[] _entitiesList = new string[] { | |
"\"-quot", "&-amp", "<-lt", ">-gt", "\x00a0-nbsp", "\x00a1-iexcl", "\x00a2-cent", "\x00a3-pound", "\x00a4-curren", "\x00a5-yen", "\x00a6-brvbar", "\x00a7-sect", "\x00a8-uml", "\x00a9-copy", "\x00aa-ordf", "\x00ab-laquo", | |
"\x00ac-not", "\x00ad-shy", "\x00ae-reg", "\x00af-macr", "\x00b0-deg", "\x00b1-plusmn", "\x00b2-sup2", "\x00b3-sup3", "\x00b4-acute", "\x00b5-micro", "\x00b6-para", "\x00b7-middot", "\x00b8-cedil", "\x00b9-sup1", "\x00ba-ordm", "\x00bb-raquo", | |
"\x00bc-frac14", "\x00bd-frac12", "\x00be-frac34", "\x00bf-iquest", "\x00c0-Agrave", "\x00c1-Aacute", "\x00c2-Acirc", "\x00c3-Atilde", "\x00c4-Auml", "\x00c5-Aring", "\x00c6-AElig", "\x00c7-Ccedil", "\x00c8-Egrave", "\x00c9-Eacute", "\x00ca-Ecirc", "\x00cb-Euml", | |
"\x00cc-Igrave", "\x00cd-Iacute", "\x00ce-Icirc", "\x00cf-Iuml", "\x00d0-ETH", "\x00d1-Ntilde", "\x00d2-Ograve", "\x00d3-Oacute", "\x00d4-Ocirc", "\x00d5-Otilde", "\x00d6-Ouml", "\x00d7-times", "\x00d8-Oslash", "\x00d9-Ugrave", "\x00da-Uacute", "\x00db-Ucirc", | |
"\x00dc-Uuml", "\x00dd-Yacute", "\x00de-THORN", "\x00df-szlig", "\x00e0-agrave", "\x00e1-aacute", "\x00e2-acirc", "\x00e3-atilde", "\x00e4-auml", "\x00e5-aring", "\x00e6-aelig", "\x00e7-ccedil", "\x00e8-egrave", "\x00e9-eacute", "\x00ea-ecirc", "\x00eb-euml", | |
"\x00ec-igrave", "\x00ed-iacute", "\x00ee-icirc", "\x00ef-iuml", "\x00f0-eth", "\x00f1-ntilde", "\x00f2-ograve", "\x00f3-oacute", "\x00f4-ocirc", "\x00f5-otilde", "\x00f6-ouml", "\x00f7-divide", "\x00f8-oslash", "\x00f9-ugrave", "\x00fa-uacute", "\x00fb-ucirc", | |
"\x00fc-uuml", "\x00fd-yacute", "\x00fe-thorn", "\x00ff-yuml", "Œ-OElig", "œ-oelig", "Š-Scaron", "š-scaron", "Ÿ-Yuml", "ƒ-fnof", "ˆ-circ", "˜-tilde", "Α-Alpha", "Β-Beta", "Γ-Gamma", "Δ-Delta", | |
"Ε-Epsilon", "Ζ-Zeta", "Η-Eta", "Θ-Theta", "Ι-Iota", "Κ-Kappa", "Λ-Lambda", "Μ-Mu", "Ν-Nu", "Ξ-Xi", "Ο-Omicron", "Π-Pi", "Ρ-Rho", "Σ-Sigma", "Τ-Tau", "Υ-Upsilon", | |
"Φ-Phi", "Χ-Chi", "Ψ-Psi", "Ω-Omega", "α-alpha", "β-beta", "γ-gamma", "δ-delta", "ε-epsilon", "ζ-zeta", "η-eta", "θ-theta", "ι-iota", "κ-kappa", "λ-lambda", "μ-mu", | |
"ν-nu", "ξ-xi", "ο-omicron", "π-pi", "ρ-rho", "ς-sigmaf", "σ-sigma", "τ-tau", "υ-upsilon", "φ-phi", "χ-chi", "ψ-psi", "ω-omega", "ϑ-thetasym", "ϒ-upsih", "ϖ-piv", | |
" -ensp", " -emsp", " -thinsp", "-zwnj", "-zwj", "-lrm", "-rlm", "–-ndash", "—-mdash", "‘-lsquo", "’-rsquo", "‚-sbquo", "“-ldquo", "”-rdquo", "„-bdquo", "†-dagger", | |
"‡-Dagger", "•-bull", "…-hellip", "‰-permil", "′-prime", "″-Prime", "‹-lsaquo", "›-rsaquo", "‾-oline", "⁄-frasl", "€-euro", "ℑ-image", "℘-weierp", "ℜ-real", "™-trade", "ℵ-alefsym", | |
"←-larr", "↑-uarr", "→-rarr", "↓-darr", "↔-harr", "↵-crarr", "⇐-lArr", "⇑-uArr", "⇒-rArr", "⇓-dArr", "⇔-hArr", "∀-forall", "∂-part", "∃-exist", "∅-empty", "∇-nabla", | |
"∈-isin", "∉-notin", "∋-ni", "∏-prod", "∑-sum", "−-minus", "∗-lowast", "√-radic", "∝-prop", "∞-infin", "∠-ang", "∧-and", "∨-or", "∩-cap", "∪-cup", "∫-int", | |
"∴-there4", "∼-sim", "≅-cong", "≈-asymp", "≠-ne", "≡-equiv", "≤-le", "≥-ge", "⊂-sub", "⊃-sup", "⊄-nsub", "⊆-sube", "⊇-supe", "⊕-oplus", "⊗-otimes", "⊥-perp", | |
"⋅-sdot", "⌈-lceil", "⌉-rceil", "⌊-lfloor", "⌋-rfloor", "〈-lang", "〉-rang", "◊-loz", "♠-spades", "♣-clubs", "♥-hearts", "♦-diams" | |
}; | |
private static Hashtable _entitiesLookupTable = null; | |
private static object _lookupLockObject = new object(); | |
#endregion | |
#region Constructor | |
private HtmlEntities() | |
{ | |
} | |
#endregion | |
#region Methods | |
internal static char Lookup(string entity) | |
{ | |
if (_entitiesLookupTable == null) | |
{ | |
lock (_lookupLockObject) | |
{ | |
if (_entitiesLookupTable == null) | |
{ | |
Hashtable hashtable = new Hashtable(); | |
foreach (string str in _entitiesList) | |
{ | |
hashtable[str.Substring(2)] = str[0]; | |
} | |
_entitiesLookupTable = hashtable; | |
} | |
} | |
} | |
object obj2 = _entitiesLookupTable[entity]; | |
if (obj2 != null) | |
{ | |
return (char)obj2; | |
} | |
return '\0'; | |
} | |
#endregion | |
} | |
#endregion | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment