do not check order sequence if option /order was not used
[mono.git] / mcs / class / System.Web / System.Web.Util / HttpEncoder.cs
1 //
2 // Authors:
3 //   Patrik Torstensson (Patrik.Torstensson@labs2.com)
4 //   Wictor WilĂ©n (decode/encode functions) (wictor@ibizkit.se)
5 //   Tim Coleman (tim@timcoleman.com)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7
8 //   Marek Habersack <mhabersack@novell.com>
9 //
10 // (C) 2005-2010 Novell, Inc (http://novell.com/)
11 //
12
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 // 
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 // 
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 using System;
34 using System.Collections.Generic;
35 using System.Configuration;
36 using System.IO;
37 using System.Text;
38 #if NET_4_0
39 using System.Web.Configuration;
40 #endif
41
42 namespace System.Web.Util
43 {
44 #if NET_4_0
45         public
46 #endif
47         class HttpEncoder
48         {
49                 static char [] hexChars = "0123456789abcdef".ToCharArray ();
50                 static object entitiesLock = new object ();
51                 static SortedDictionary <string, char> entities;
52 #if NET_4_0
53                 static Lazy <HttpEncoder> defaultEncoder;
54                 static Lazy <HttpEncoder> currentEncoderLazy;
55 #else
56                 static HttpEncoder defaultEncoder;
57 #endif
58                 static HttpEncoder currentEncoder;
59
60                 static IDictionary <string, char> Entities {
61                         get {
62                                 lock (entitiesLock) {
63                                         if (entities == null)
64                                                 InitEntities ();
65
66                                         return entities;
67                                 }
68                         }
69                 }
70                 
71                 public static HttpEncoder Current {
72                         get {
73 #if NET_4_0
74                                 if (currentEncoder == null)
75                                         currentEncoder = currentEncoderLazy.Value;
76 #endif
77                                 return currentEncoder;
78                         }
79 #if NET_4_0
80                         set {
81                                 if (value == null)
82                                         throw new ArgumentNullException ("value");
83                                 currentEncoder = value;
84                         }
85 #endif
86                 }
87
88                 public static HttpEncoder Default {
89                         get {
90 #if NET_4_0
91                                 return defaultEncoder.Value;
92 #else
93                                 return defaultEncoder;
94 #endif
95                         }
96                 }
97
98                 static HttpEncoder ()
99                 {
100 #if NET_4_0
101                         defaultEncoder = new Lazy <HttpEncoder> (() => new HttpEncoder ());
102                         currentEncoderLazy = new Lazy <HttpEncoder> (new Func <HttpEncoder> (GetCustomEncoderFromConfig));
103 #else
104                         defaultEncoder = new HttpEncoder ();
105                         currentEncoder = defaultEncoder;
106 #endif
107                 }
108                 
109                 public HttpEncoder ()
110                 {
111                 }
112 #if NET_4_0     
113                 protected internal virtual
114 #else
115                 internal static
116 #endif
117                 void HeaderNameValueEncode (string headerName, string headerValue, out string encodedHeaderName, out string encodedHeaderValue)
118                 {
119                         if (String.IsNullOrEmpty (headerName))
120                                 encodedHeaderName = headerName;
121                         else
122                                 encodedHeaderName = EncodeHeaderString (headerName);
123
124                         if (String.IsNullOrEmpty (headerValue))
125                                 encodedHeaderValue = headerValue;
126                         else
127                                 encodedHeaderValue = EncodeHeaderString (headerValue);
128                 }
129
130                 static void StringBuilderAppend (string s, ref StringBuilder sb)
131                 {
132                         if (sb == null)
133                                 sb = new StringBuilder (s);
134                         else
135                                 sb.Append (s);
136                 }
137                 
138                 static string EncodeHeaderString (string input)
139                 {
140                         StringBuilder sb = null;
141                         char ch;
142                         
143                         for (int i = 0; i < input.Length; i++) {
144                                 ch = input [i];
145
146                                 if ((ch < 32 && ch != 9) || ch == 127)
147                                         StringBuilderAppend (String.Format ("%{0:x2}", (int)ch), ref sb);
148                         }
149
150                         if (sb != null)
151                                 return sb.ToString ();
152
153                         return input;
154                 }
155 #if NET_4_0             
156                 protected internal virtual void HtmlAttributeEncode (string value, TextWriter output)
157                 {
158
159                         if (output == null)
160                                 throw new ArgumentNullException ("output");
161
162                         if (String.IsNullOrEmpty (value))
163                                 return;
164
165                         output.Write (HtmlAttributeEncode (value));
166                 }
167
168                 protected internal virtual void HtmlDecode (string value, TextWriter output)
169                 {
170                         if (output == null)
171                                 throw new ArgumentNullException ("output");
172
173                         output.Write (HtmlDecode (value));
174                 }
175
176                 protected internal virtual void HtmlEncode (string value, TextWriter output)
177                 {
178                         if (output == null)
179                                 throw new ArgumentNullException ("output");
180
181                         output.Write (HtmlEncode (value));
182                 }
183
184                 protected internal virtual byte[] UrlEncode (byte[] bytes, int offset, int count)
185                 {
186                         return UrlEncodeToBytes (bytes, offset, count);
187                 }
188
189                 static HttpEncoder GetCustomEncoderFromConfig ()
190                 {
191                         var cfg = HttpRuntime.Section;
192                         string typeName = cfg.EncoderType;
193
194                         if (String.Compare (typeName, "System.Web.Util.HttpEncoder", StringComparison.OrdinalIgnoreCase) == 0)
195                                 return Default;
196                         
197                         Type t = Type.GetType (typeName, false);
198                         if (t == null)
199                                 throw new ConfigurationErrorsException (String.Format ("Could not load type '{0}'.", typeName));
200                         
201                         if (!typeof (HttpEncoder).IsAssignableFrom (t))
202                                 throw new ConfigurationErrorsException (
203                                         String.Format ("'{0}' is not allowed here because it does not extend class 'System.Web.Util.HttpEncoder'.", typeName)
204                                 );
205
206                         return Activator.CreateInstance (t, false) as HttpEncoder;
207                 }
208 #endif
209 #if NET_4_0
210                 protected internal virtual
211 #else
212                 internal static
213 #endif
214                 string UrlPathEncode (string value)
215                 {
216                         if (String.IsNullOrEmpty (value))
217                                 return value;
218
219                         MemoryStream result = new MemoryStream ();
220                         int length = value.Length;
221                         for (int i = 0; i < length; i++)
222                                 UrlPathEncodeChar (value [i], result);
223                         
224                         return Encoding.ASCII.GetString (result.ToArray ());
225                 }
226                 
227                 internal static byte[] UrlEncodeToBytes (byte[] bytes, int offset, int count)
228                 {
229                         if (bytes == null)
230                                 throw new ArgumentNullException ("bytes");
231                         
232                         int blen = bytes.Length;
233                         if (blen == 0)
234                                 return new byte [0];
235                         
236                         if (offset < 0 || offset >= blen)
237                                 throw new ArgumentOutOfRangeException("offset");
238
239                         if (count < 0 || count > blen - offset)
240                                 throw new ArgumentOutOfRangeException("count");
241
242                         MemoryStream result = new MemoryStream (count);
243                         int end = offset + count;
244                         for (int i = offset; i < end; i++)
245                                 UrlEncodeChar ((char)bytes [i], result, false);
246
247                         return result.ToArray();
248                 }
249                 
250                 internal static string HtmlEncode (string s) 
251                 {
252                         if (s == null)
253                                 return null;
254
255                         if (s.Length == 0)
256                                 return String.Empty;
257                         
258                         bool needEncode = false;
259                         for (int i = 0; i < s.Length; i++) {
260                                 char c = s [i];
261                                 if (c == '&' || c == '"' || c == '<' || c == '>' || c > 159
262 #if NET_4_0
263                                     || c == '\''
264 #endif
265                                 ) {
266                                         needEncode = true;
267                                         break;
268                                 }
269                         }
270
271                         if (!needEncode)
272                                 return s;
273
274                         StringBuilder output = new StringBuilder ();
275                         char ch;
276                         int len = s.Length;
277                         
278                         for (int i = 0; i < len; i++) {
279                                 switch (s [i]) {
280                                         case '&' :
281                                                 output.Append ("&amp;");
282                                                 break;
283                                         case '>' : 
284                                                 output.Append ("&gt;");
285                                                 break;
286                                         case '<' :
287                                                 output.Append ("&lt;");
288                                                 break;
289                                         case '"' :
290                                                 output.Append ("&quot;");
291                                                 break;
292 #if NET_4_0
293                                         case '\'':
294                                                 output.Append ("&#39;");
295                                                 break;
296 #endif
297                                         case '\uff1c':
298                                                 output.Append ("&#65308;");
299                                                 break;
300
301                                         case '\uff1e':
302                                                 output.Append ("&#65310;");
303                                                 break;
304                                                 
305                                         default:
306                                                 ch = s [i];
307                                                 if (ch > 159 && ch < 256) {
308                                                         output.Append ("&#");
309                                                         output.Append (((int) ch).ToString (Helpers.InvariantCulture));
310                                                         output.Append (";");
311                                                 } else
312                                                         output.Append (ch);
313                                                 break;
314                                 }       
315                         }
316                         
317                         return output.ToString ();                      
318                 }
319                 
320                 internal static string HtmlAttributeEncode (string s) 
321                 {
322 #if NET_4_0
323                         if (String.IsNullOrEmpty (s))
324                                 return String.Empty;
325 #else
326                         if (s == null) 
327                                 return null;
328                         
329                         if (s.Length == 0)
330                                 return String.Empty;
331 #endif                  
332                         bool needEncode = false;
333                         for (int i = 0; i < s.Length; i++) {
334                                 char c = s [i];
335                                 if (c == '&' || c == '"' || c == '<'
336 #if NET_4_0
337                                     || c == '\''
338 #endif
339                                 ) {
340                                         needEncode = true;
341                                         break;
342                                 }
343                         }
344
345                         if (!needEncode)
346                                 return s;
347
348                         StringBuilder output = new StringBuilder ();
349                         int len = s.Length;
350                         for (int i = 0; i < len; i++)
351                                 switch (s [i]) {
352                                 case '&' : 
353                                         output.Append ("&amp;");
354                                         break;
355                                 case '"' :
356                                         output.Append ("&quot;");
357                                         break;
358                                 case '<':
359                                         output.Append ("&lt;");
360                                         break;
361 #if NET_4_0
362                                 case '\'':
363                                         output.Append ("&#39;");
364                                         break;
365 #endif
366                                 default:
367                                         output.Append (s [i]);
368                                         break;
369                                 }
370         
371                         return output.ToString();
372                 }
373                 
374                 internal static string HtmlDecode (string s)
375                 {
376                         if (s == null)
377                                 return null;
378
379                         if (s.Length == 0)
380                                 return String.Empty;
381                         
382                         if (s.IndexOf ('&') == -1)
383                                 return s;
384 #if NET_4_0
385                         StringBuilder rawEntity = new StringBuilder ();
386 #endif
387                         StringBuilder entity = new StringBuilder ();
388                         StringBuilder output = new StringBuilder ();
389                         int len = s.Length;
390                         // 0 -> nothing,
391                         // 1 -> right after '&'
392                         // 2 -> between '&' and ';' but no '#'
393                         // 3 -> '#' found after '&' and getting numbers
394                         int state = 0;
395                         int number = 0;
396                         bool is_hex_value = false;
397                         bool have_trailing_digits = false;
398         
399                         for (int i = 0; i < len; i++) {
400                                 char c = s [i];
401                                 if (state == 0) {
402                                         if (c == '&') {
403                                                 entity.Append (c);
404 #if NET_4_0
405                                                 rawEntity.Append (c);
406 #endif
407                                                 state = 1;
408                                         } else {
409                                                 output.Append (c);
410                                         }
411                                         continue;
412                                 }
413
414                                 if (c == '&') {
415                                         state = 1;
416                                         if (have_trailing_digits) {
417                                                 entity.Append (number.ToString (Helpers.InvariantCulture));
418                                                 have_trailing_digits = false;
419                                         }
420
421                                         output.Append (entity.ToString ());
422                                         entity.Length = 0;
423                                         entity.Append ('&');
424                                         continue;
425                                 }
426
427                                 if (state == 1) {
428                                         if (c == ';') {
429                                                 state = 0;
430                                                 output.Append (entity.ToString ());
431                                                 output.Append (c);
432                                                 entity.Length = 0;
433                                         } else {
434                                                 number = 0;
435                                                 is_hex_value = false;
436                                                 if (c != '#') {
437                                                         state = 2;
438                                                 } else {
439                                                         state = 3;
440                                                 }
441                                                 entity.Append (c);
442 #if NET_4_0
443                                                 rawEntity.Append (c);
444 #endif
445                                         }
446                                 } else if (state == 2) {
447                                         entity.Append (c);
448                                         if (c == ';') {
449                                                 string key = entity.ToString ();
450                                                 if (key.Length > 1 && Entities.ContainsKey (key.Substring (1, key.Length - 2)))
451                                                         key = Entities [key.Substring (1, key.Length - 2)].ToString ();
452
453                                                 output.Append (key);
454                                                 state = 0;
455                                                 entity.Length = 0;
456 #if NET_4_0
457                                                 rawEntity.Length = 0;
458 #endif
459                                         }
460                                 } else if (state == 3) {
461                                         if (c == ';') {
462 #if NET_4_0
463                                                 if (number == 0)
464                                                         output.Append (rawEntity.ToString () + ";");
465                                                 else
466 #endif
467                                                 if (number > 65535) {
468                                                         output.Append ("&#");
469                                                         output.Append (number.ToString (Helpers.InvariantCulture));
470                                                         output.Append (";");
471                                                 } else {
472                                                         output.Append ((char) number);
473                                                 }
474                                                 state = 0;
475                                                 entity.Length = 0;
476 #if NET_4_0
477                                                 rawEntity.Length = 0;
478 #endif
479                                                 have_trailing_digits = false;
480                                         } else if (is_hex_value &&  Uri.IsHexDigit(c)) {
481                                                 number = number * 16 + Uri.FromHex(c);
482                                                 have_trailing_digits = true;
483 #if NET_4_0
484                                                 rawEntity.Append (c);
485 #endif
486                                         } else if (Char.IsDigit (c)) {
487                                                 number = number * 10 + ((int) c - '0');
488                                                 have_trailing_digits = true;
489 #if NET_4_0
490                                                 rawEntity.Append (c);
491 #endif
492                                         } else if (number == 0 && (c == 'x' || c == 'X')) {
493                                                 is_hex_value = true;
494 #if NET_4_0
495                                                 rawEntity.Append (c);
496 #endif
497                                         } else {
498                                                 state = 2;
499                                                 if (have_trailing_digits) {
500                                                         entity.Append (number.ToString (Helpers.InvariantCulture));
501                                                         have_trailing_digits = false;
502                                                 }
503                                                 entity.Append (c);
504                                         }
505                                 }
506                         }
507
508                         if (entity.Length > 0) {
509                                 output.Append (entity.ToString ());
510                         } else if (have_trailing_digits) {
511                                 output.Append (number.ToString (Helpers.InvariantCulture));
512                         }
513                         return output.ToString ();
514                 }
515
516                 internal static bool NotEncoded (char c)
517                 {
518                         return (c == '!' || c == '(' || c == ')' || c == '*' || c == '-' || c == '.' || c == '_'
519 #if !NET_4_0
520                                 || c == '\''
521 #endif
522                         );
523                 }
524                 
525                 internal static void UrlEncodeChar (char c, Stream result, bool isUnicode) {
526                         if (c > 255) {
527                                 //FIXME: what happens when there is an internal error?
528                                 //if (!isUnicode)
529                                 //      throw new ArgumentOutOfRangeException ("c", c, "c must be less than 256");
530                                 int idx;
531                                 int i = (int) c;
532
533                                 result.WriteByte ((byte)'%');
534                                 result.WriteByte ((byte)'u');
535                                 idx = i >> 12;
536                                 result.WriteByte ((byte)hexChars [idx]);
537                                 idx = (i >> 8) & 0x0F;
538                                 result.WriteByte ((byte)hexChars [idx]);
539                                 idx = (i >> 4) & 0x0F;
540                                 result.WriteByte ((byte)hexChars [idx]);
541                                 idx = i & 0x0F;
542                                 result.WriteByte ((byte)hexChars [idx]);
543                                 return;
544                         }
545                         
546                         if (c > ' ' && NotEncoded (c)) {
547                                 result.WriteByte ((byte)c);
548                                 return;
549                         }
550                         if (c==' ') {
551                                 result.WriteByte ((byte)'+');
552                                 return;
553                         }
554                         if (    (c < '0') ||
555                                 (c < 'A' && c > '9') ||
556                                 (c > 'Z' && c < 'a') ||
557                                 (c > 'z')) {
558                                 if (isUnicode && c > 127) {
559                                         result.WriteByte ((byte)'%');
560                                         result.WriteByte ((byte)'u');
561                                         result.WriteByte ((byte)'0');
562                                         result.WriteByte ((byte)'0');
563                                 }
564                                 else
565                                         result.WriteByte ((byte)'%');
566                                 
567                                 int idx = ((int) c) >> 4;
568                                 result.WriteByte ((byte)hexChars [idx]);
569                                 idx = ((int) c) & 0x0F;
570                                 result.WriteByte ((byte)hexChars [idx]);
571                         }
572                         else
573                                 result.WriteByte ((byte)c);
574                 }
575
576                 internal static void UrlPathEncodeChar (char c, Stream result)
577                 {
578                         if (c < 33 || c > 126) {
579                                 byte [] bIn = Encoding.UTF8.GetBytes (c.ToString ());
580                                 for (int i = 0; i < bIn.Length; i++) {
581                                         result.WriteByte ((byte) '%');
582                                         int idx = ((int) bIn [i]) >> 4;
583                                         result.WriteByte ((byte) hexChars [idx]);
584                                         idx = ((int) bIn [i]) & 0x0F;
585                                         result.WriteByte ((byte) hexChars [idx]);
586                                 }
587                         }
588                         else if (c == ' ') {
589                                 result.WriteByte ((byte) '%');
590                                 result.WriteByte ((byte) '2');
591                                 result.WriteByte ((byte) '0');
592                         }
593                         else
594                                 result.WriteByte ((byte) c);
595                 }
596                 
597                 static void InitEntities ()
598                 {
599                         // Build the hash table of HTML entity references.  This list comes
600                         // from the HTML 4.01 W3C recommendation.
601                         entities = new SortedDictionary <string, char> (StringComparer.Ordinal);
602                         
603                         entities.Add ("nbsp", '\u00A0');
604                         entities.Add ("iexcl", '\u00A1');
605                         entities.Add ("cent", '\u00A2');
606                         entities.Add ("pound", '\u00A3');
607                         entities.Add ("curren", '\u00A4');
608                         entities.Add ("yen", '\u00A5');
609                         entities.Add ("brvbar", '\u00A6');
610                         entities.Add ("sect", '\u00A7');
611                         entities.Add ("uml", '\u00A8');
612                         entities.Add ("copy", '\u00A9');
613                         entities.Add ("ordf", '\u00AA');
614                         entities.Add ("laquo", '\u00AB');
615                         entities.Add ("not", '\u00AC');
616                         entities.Add ("shy", '\u00AD');
617                         entities.Add ("reg", '\u00AE');
618                         entities.Add ("macr", '\u00AF');
619                         entities.Add ("deg", '\u00B0');
620                         entities.Add ("plusmn", '\u00B1');
621                         entities.Add ("sup2", '\u00B2');
622                         entities.Add ("sup3", '\u00B3');
623                         entities.Add ("acute", '\u00B4');
624                         entities.Add ("micro", '\u00B5');
625                         entities.Add ("para", '\u00B6');
626                         entities.Add ("middot", '\u00B7');
627                         entities.Add ("cedil", '\u00B8');
628                         entities.Add ("sup1", '\u00B9');
629                         entities.Add ("ordm", '\u00BA');
630                         entities.Add ("raquo", '\u00BB');
631                         entities.Add ("frac14", '\u00BC');
632                         entities.Add ("frac12", '\u00BD');
633                         entities.Add ("frac34", '\u00BE');
634                         entities.Add ("iquest", '\u00BF');
635                         entities.Add ("Agrave", '\u00C0');
636                         entities.Add ("Aacute", '\u00C1');
637                         entities.Add ("Acirc", '\u00C2');
638                         entities.Add ("Atilde", '\u00C3');
639                         entities.Add ("Auml", '\u00C4');
640                         entities.Add ("Aring", '\u00C5');
641                         entities.Add ("AElig", '\u00C6');
642                         entities.Add ("Ccedil", '\u00C7');
643                         entities.Add ("Egrave", '\u00C8');
644                         entities.Add ("Eacute", '\u00C9');
645                         entities.Add ("Ecirc", '\u00CA');
646                         entities.Add ("Euml", '\u00CB');
647                         entities.Add ("Igrave", '\u00CC');
648                         entities.Add ("Iacute", '\u00CD');
649                         entities.Add ("Icirc", '\u00CE');
650                         entities.Add ("Iuml", '\u00CF');
651                         entities.Add ("ETH", '\u00D0');
652                         entities.Add ("Ntilde", '\u00D1');
653                         entities.Add ("Ograve", '\u00D2');
654                         entities.Add ("Oacute", '\u00D3');
655                         entities.Add ("Ocirc", '\u00D4');
656                         entities.Add ("Otilde", '\u00D5');
657                         entities.Add ("Ouml", '\u00D6');
658                         entities.Add ("times", '\u00D7');
659                         entities.Add ("Oslash", '\u00D8');
660                         entities.Add ("Ugrave", '\u00D9');
661                         entities.Add ("Uacute", '\u00DA');
662                         entities.Add ("Ucirc", '\u00DB');
663                         entities.Add ("Uuml", '\u00DC');
664                         entities.Add ("Yacute", '\u00DD');
665                         entities.Add ("THORN", '\u00DE');
666                         entities.Add ("szlig", '\u00DF');
667                         entities.Add ("agrave", '\u00E0');
668                         entities.Add ("aacute", '\u00E1');
669                         entities.Add ("acirc", '\u00E2');
670                         entities.Add ("atilde", '\u00E3');
671                         entities.Add ("auml", '\u00E4');
672                         entities.Add ("aring", '\u00E5');
673                         entities.Add ("aelig", '\u00E6');
674                         entities.Add ("ccedil", '\u00E7');
675                         entities.Add ("egrave", '\u00E8');
676                         entities.Add ("eacute", '\u00E9');
677                         entities.Add ("ecirc", '\u00EA');
678                         entities.Add ("euml", '\u00EB');
679                         entities.Add ("igrave", '\u00EC');
680                         entities.Add ("iacute", '\u00ED');
681                         entities.Add ("icirc", '\u00EE');
682                         entities.Add ("iuml", '\u00EF');
683                         entities.Add ("eth", '\u00F0');
684                         entities.Add ("ntilde", '\u00F1');
685                         entities.Add ("ograve", '\u00F2');
686                         entities.Add ("oacute", '\u00F3');
687                         entities.Add ("ocirc", '\u00F4');
688                         entities.Add ("otilde", '\u00F5');
689                         entities.Add ("ouml", '\u00F6');
690                         entities.Add ("divide", '\u00F7');
691                         entities.Add ("oslash", '\u00F8');
692                         entities.Add ("ugrave", '\u00F9');
693                         entities.Add ("uacute", '\u00FA');
694                         entities.Add ("ucirc", '\u00FB');
695                         entities.Add ("uuml", '\u00FC');
696                         entities.Add ("yacute", '\u00FD');
697                         entities.Add ("thorn", '\u00FE');
698                         entities.Add ("yuml", '\u00FF');
699                         entities.Add ("fnof", '\u0192');
700                         entities.Add ("Alpha", '\u0391');
701                         entities.Add ("Beta", '\u0392');
702                         entities.Add ("Gamma", '\u0393');
703                         entities.Add ("Delta", '\u0394');
704                         entities.Add ("Epsilon", '\u0395');
705                         entities.Add ("Zeta", '\u0396');
706                         entities.Add ("Eta", '\u0397');
707                         entities.Add ("Theta", '\u0398');
708                         entities.Add ("Iota", '\u0399');
709                         entities.Add ("Kappa", '\u039A');
710                         entities.Add ("Lambda", '\u039B');
711                         entities.Add ("Mu", '\u039C');
712                         entities.Add ("Nu", '\u039D');
713                         entities.Add ("Xi", '\u039E');
714                         entities.Add ("Omicron", '\u039F');
715                         entities.Add ("Pi", '\u03A0');
716                         entities.Add ("Rho", '\u03A1');
717                         entities.Add ("Sigma", '\u03A3');
718                         entities.Add ("Tau", '\u03A4');
719                         entities.Add ("Upsilon", '\u03A5');
720                         entities.Add ("Phi", '\u03A6');
721                         entities.Add ("Chi", '\u03A7');
722                         entities.Add ("Psi", '\u03A8');
723                         entities.Add ("Omega", '\u03A9');
724                         entities.Add ("alpha", '\u03B1');
725                         entities.Add ("beta", '\u03B2');
726                         entities.Add ("gamma", '\u03B3');
727                         entities.Add ("delta", '\u03B4');
728                         entities.Add ("epsilon", '\u03B5');
729                         entities.Add ("zeta", '\u03B6');
730                         entities.Add ("eta", '\u03B7');
731                         entities.Add ("theta", '\u03B8');
732                         entities.Add ("iota", '\u03B9');
733                         entities.Add ("kappa", '\u03BA');
734                         entities.Add ("lambda", '\u03BB');
735                         entities.Add ("mu", '\u03BC');
736                         entities.Add ("nu", '\u03BD');
737                         entities.Add ("xi", '\u03BE');
738                         entities.Add ("omicron", '\u03BF');
739                         entities.Add ("pi", '\u03C0');
740                         entities.Add ("rho", '\u03C1');
741                         entities.Add ("sigmaf", '\u03C2');
742                         entities.Add ("sigma", '\u03C3');
743                         entities.Add ("tau", '\u03C4');
744                         entities.Add ("upsilon", '\u03C5');
745                         entities.Add ("phi", '\u03C6');
746                         entities.Add ("chi", '\u03C7');
747                         entities.Add ("psi", '\u03C8');
748                         entities.Add ("omega", '\u03C9');
749                         entities.Add ("thetasym", '\u03D1');
750                         entities.Add ("upsih", '\u03D2');
751                         entities.Add ("piv", '\u03D6');
752                         entities.Add ("bull", '\u2022');
753                         entities.Add ("hellip", '\u2026');
754                         entities.Add ("prime", '\u2032');
755                         entities.Add ("Prime", '\u2033');
756                         entities.Add ("oline", '\u203E');
757                         entities.Add ("frasl", '\u2044');
758                         entities.Add ("weierp", '\u2118');
759                         entities.Add ("image", '\u2111');
760                         entities.Add ("real", '\u211C');
761                         entities.Add ("trade", '\u2122');
762                         entities.Add ("alefsym", '\u2135');
763                         entities.Add ("larr", '\u2190');
764                         entities.Add ("uarr", '\u2191');
765                         entities.Add ("rarr", '\u2192');
766                         entities.Add ("darr", '\u2193');
767                         entities.Add ("harr", '\u2194');
768                         entities.Add ("crarr", '\u21B5');
769                         entities.Add ("lArr", '\u21D0');
770                         entities.Add ("uArr", '\u21D1');
771                         entities.Add ("rArr", '\u21D2');
772                         entities.Add ("dArr", '\u21D3');
773                         entities.Add ("hArr", '\u21D4');
774                         entities.Add ("forall", '\u2200');
775                         entities.Add ("part", '\u2202');
776                         entities.Add ("exist", '\u2203');
777                         entities.Add ("empty", '\u2205');
778                         entities.Add ("nabla", '\u2207');
779                         entities.Add ("isin", '\u2208');
780                         entities.Add ("notin", '\u2209');
781                         entities.Add ("ni", '\u220B');
782                         entities.Add ("prod", '\u220F');
783                         entities.Add ("sum", '\u2211');
784                         entities.Add ("minus", '\u2212');
785                         entities.Add ("lowast", '\u2217');
786                         entities.Add ("radic", '\u221A');
787                         entities.Add ("prop", '\u221D');
788                         entities.Add ("infin", '\u221E');
789                         entities.Add ("ang", '\u2220');
790                         entities.Add ("and", '\u2227');
791                         entities.Add ("or", '\u2228');
792                         entities.Add ("cap", '\u2229');
793                         entities.Add ("cup", '\u222A');
794                         entities.Add ("int", '\u222B');
795                         entities.Add ("there4", '\u2234');
796                         entities.Add ("sim", '\u223C');
797                         entities.Add ("cong", '\u2245');
798                         entities.Add ("asymp", '\u2248');
799                         entities.Add ("ne", '\u2260');
800                         entities.Add ("equiv", '\u2261');
801                         entities.Add ("le", '\u2264');
802                         entities.Add ("ge", '\u2265');
803                         entities.Add ("sub", '\u2282');
804                         entities.Add ("sup", '\u2283');
805                         entities.Add ("nsub", '\u2284');
806                         entities.Add ("sube", '\u2286');
807                         entities.Add ("supe", '\u2287');
808                         entities.Add ("oplus", '\u2295');
809                         entities.Add ("otimes", '\u2297');
810                         entities.Add ("perp", '\u22A5');
811                         entities.Add ("sdot", '\u22C5');
812                         entities.Add ("lceil", '\u2308');
813                         entities.Add ("rceil", '\u2309');
814                         entities.Add ("lfloor", '\u230A');
815                         entities.Add ("rfloor", '\u230B');
816                         entities.Add ("lang", '\u2329');
817                         entities.Add ("rang", '\u232A');
818                         entities.Add ("loz", '\u25CA');
819                         entities.Add ("spades", '\u2660');
820                         entities.Add ("clubs", '\u2663');
821                         entities.Add ("hearts", '\u2665');
822                         entities.Add ("diams", '\u2666');
823                         entities.Add ("quot", '\u0022');
824                         entities.Add ("amp", '\u0026');
825                         entities.Add ("lt", '\u003C');
826                         entities.Add ("gt", '\u003E');
827                         entities.Add ("OElig", '\u0152');
828                         entities.Add ("oelig", '\u0153');
829                         entities.Add ("Scaron", '\u0160');
830                         entities.Add ("scaron", '\u0161');
831                         entities.Add ("Yuml", '\u0178');
832                         entities.Add ("circ", '\u02C6');
833                         entities.Add ("tilde", '\u02DC');
834                         entities.Add ("ensp", '\u2002');
835                         entities.Add ("emsp", '\u2003');
836                         entities.Add ("thinsp", '\u2009');
837                         entities.Add ("zwnj", '\u200C');
838                         entities.Add ("zwj", '\u200D');
839                         entities.Add ("lrm", '\u200E');
840                         entities.Add ("rlm", '\u200F');
841                         entities.Add ("ndash", '\u2013');
842                         entities.Add ("mdash", '\u2014');
843                         entities.Add ("lsquo", '\u2018');
844                         entities.Add ("rsquo", '\u2019');
845                         entities.Add ("sbquo", '\u201A');
846                         entities.Add ("ldquo", '\u201C');
847                         entities.Add ("rdquo", '\u201D');
848                         entities.Add ("bdquo", '\u201E');
849                         entities.Add ("dagger", '\u2020');
850                         entities.Add ("Dagger", '\u2021');
851                         entities.Add ("permil", '\u2030');
852                         entities.Add ("lsaquo", '\u2039');
853                         entities.Add ("rsaquo", '\u203A');
854                         entities.Add ("euro", '\u20AC');
855                 }
856         }
857 }