A game framework written with osu! in mind.
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2// See the LICENCE file in the repository root for full licence text.
3
4using System.Text;
5
6namespace osu.Framework.IO.Network
7{
8 public static class UrlEncoding
9 {
10 public static string UrlEncode(string str)
11 {
12 if (str == null)
13 {
14 return null;
15 }
16
17 return UrlEncode(str, Encoding.UTF8, false);
18 }
19
20 public static string UrlEncodeParam(string str)
21 {
22 if (str == null)
23 {
24 return null;
25 }
26
27 return UrlEncode(str, Encoding.UTF8, true);
28 }
29
30 public static string UrlEncode(string str, Encoding e, bool paramEncode)
31 {
32 if (str == null)
33 {
34 return null;
35 }
36
37 return Encoding.ASCII.GetString(UrlEncodeToBytes(str, e, paramEncode));
38 }
39
40 public static byte[] UrlEncodeToBytes(string str, Encoding e, bool paramEncode)
41 {
42 if (str == null)
43 {
44 return null;
45 }
46
47 byte[] bytes = e.GetBytes(str);
48 return urlEncodeBytesToBytesPublic(bytes, 0, bytes.Length, false, paramEncode);
49 }
50
51 private static byte[] urlEncodeBytesToBytesPublic(byte[] bytes, int offset, int count, bool alwaysCreateReturnValue, bool paramEncode)
52 {
53 int num = 0;
54 int num2 = 0;
55
56 for (int i = 0; i < count; i++)
57 {
58 char ch = (char)bytes[offset + i];
59
60 if (paramEncode && ch == ' ')
61 {
62 num++;
63 }
64 else if (!IsSafe(ch))
65 {
66 num2++;
67 }
68 }
69
70 if (!alwaysCreateReturnValue && num == 0 && num2 == 0)
71 {
72 return bytes;
73 }
74
75 byte[] buffer = new byte[count + num2 * 2];
76 int num4 = 0;
77
78 for (int j = 0; j < count; j++)
79 {
80 byte num6 = bytes[offset + j];
81 char ch2 = (char)num6;
82
83 if (IsSafe(ch2))
84 {
85 buffer[num4++] = num6;
86 }
87 else if (paramEncode && ch2 == ' ')
88 {
89 buffer[num4++] = 0x2b;
90 }
91 else
92 {
93 buffer[num4++] = 0x25;
94 buffer[num4++] = (byte)IntToHex((num6 >> 4) & 15);
95 buffer[num4++] = (byte)IntToHex(num6 & 15);
96 }
97 }
98
99 return buffer;
100 }
101
102 public static bool IsSafe(char ch)
103 {
104 if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z' || ch >= '0' && ch <= '9')
105 {
106 return true;
107 }
108
109 switch (ch)
110 {
111 case '\'':
112 case '(':
113 case ')':
114 case '*':
115 case '-':
116 case '.':
117 case '_':
118 case '!':
119 return true;
120 }
121
122 return false;
123 }
124
125 public static char IntToHex(int n)
126 {
127 if (n <= 9)
128 {
129 return (char)(n + 0x30);
130 }
131
132 return (char)(n - 10 + 0x61);
133 }
134 }
135}