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