// CAS - no InheritanceDemand here as the class is sealed
[AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public sealed class HttpUtility {
-
#region Fields
static Hashtable entities;
if (null == s)
return null;
- if (s.IndexOf ('&') == -1 && s.IndexOf ('"') == -1)
+ bool needEncode = false;
+ for (int i = 0; i < s.Length; i++) {
+ if (s [i] == '&' || s [i] == '"' || s [i] == '<') {
+ needEncode = true;
+ break;
+ }
+ }
+
+ if (!needEncode)
return s;
StringBuilder output = new StringBuilder ();
- foreach (char c in s)
- switch (c) {
+ int len = s.Length;
+ for (int i = 0; i < len; i++)
+ switch (s [i]) {
case '&' :
output.Append ("&");
break;
case '"' :
output.Append (""");
break;
+ case '<':
+ output.Append ("<");
+ break;
default:
- output.Append (c);
+ output.Append (s [i]);
break;
}
if (s == "")
return "";
- byte [] bytes = Enc.GetBytes (s);
- return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, bytes.Length));
+ bool needEncode = false;
+ int len = s.Length;
+ for (int i = 0; i < len; i++) {
+ char c = s [i];
+ if ((c < '0') || (c < 'A' && c > '9') || (c > 'Z' && c < 'a') || (c > 'z')) {
+ if (NotEncoded (c))
+ continue;
+
+ needEncode = true;
+ break;
+ }
+ }
+
+ if (!needEncode)
+ return s;
+
+ // avoided GetByteCount call
+ byte [] bytes = new byte[Enc.GetMaxByteCount(s.Length)];
+ int realLen = Enc.GetBytes (s, 0, s.Length, bytes, 0);
+ return Encoding.ASCII.GetString (UrlEncodeToBytes (bytes, 0, realLen));
}
public static string UrlEncode (byte [] bytes)
}
static char [] hexChars = "0123456789abcdef".ToCharArray ();
- const string notEncoded = "!'()*-._";
+
+ static bool NotEncoded (char c)
+ {
+ return (c == '!' || c == '\'' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_');
+ }
static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
if (c > 255) {
return;
}
- if (c>' ' && notEncoded.IndexOf (c)!=-1) {
+ if (c > ' ' && NotEncoded (c)) {
result.WriteByte ((byte)c);
return;
}
if (s == null)
return null;
+ bool needEncode = false;
+ for (int i = 0; i < s.Length; i++) {
+ char c = s [i];
+ if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159) {
+ needEncode = true;
+ break;
+ }
+ }
+
+ if (!needEncode)
+ return s;
+
StringBuilder output = new StringBuilder ();
- foreach (char c in s)
- switch (c) {
+ int len = s.Length;
+ for (int i = 0; i < len; i++)
+ switch (s [i]) {
case '&' :
output.Append ("&");
break;
// MS starts encoding with &# from 160 and stops at 255.
// We don't do that. One reason is the 65308/65310 unicode
// characters that look like '<' and '>'.
- if (c > 159) {
+ if (s [i] > 159) {
output.Append ("&#");
- output.Append (((int) c).ToString (CultureInfo.InvariantCulture));
+ output.Append (((int) s [i]).ToString (CultureInfo.InvariantCulture));
output.Append (";");
} else {
- output.Append (c);
+ output.Append (s [i]);
}
break;
}
return;
int namePos = 0;
+ bool first = true;
while (namePos <= query.Length) {
int valuePos = -1, valueEnd = -1;
for (int q = namePos; q < query.Length; q++) {
}
}
+ if (first) {
+ first = false;
+ if (query [namePos] == '?')
+ namePos++;
+ }
+
string name, value;
if (valuePos == -1) {
name = null;
value = UrlDecode (query.Substring (valuePos, valueEnd - valuePos), encoding);
result.Add (name, value);
- if (namePos == -1) break;
+ if (namePos == -1)
+ break;
}
}
#endregion // Methods