334c57fab33c99a32fe2894fcffd683eb538f440
[mono.git] / mcs / tools / corcompare / WellFormedXmlWriter.cs
1 //
2 // WellFormedXmlWriter.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc. http://www.novell.com
8 //
9 using System;
10 using System.Globalization;
11 using System.Collections;
12 using System.Xml;
13
14 namespace CorCompare {
15
16         public class WellFormedXmlWriter : DefaultXmlWriter
17         {
18                 public static bool IsValid (int ch)
19                 {
20                         return !IsInvalid (ch);
21                 }
22
23                 public static bool IsInvalid (int ch)
24                 {
25                         switch (ch) {
26                         case 9:
27                         case 10:
28                         case 13:
29                                 return false;
30                         }
31                         if (ch < 32)
32                                 return true;
33                         if (ch < 0xD800)
34                                 return false;
35                         if (ch < 0xE000)
36                                 return true;
37                         if (ch < 0xFFFE)
38                                 return false;
39                         if (ch < 0x10000)
40                                 return true;
41                         if (ch < 0x110000)
42                                 return false;
43                         else
44                                 return true;
45                 }
46
47                 public static int IndexOfInvalid (string s, bool allowSurrogate)
48                 {
49                         for (int i = 0; i < s.Length; i++)
50                                 if (IsInvalid (s [i])) {
51                                         if (!allowSurrogate ||
52                                             i + 1 == s.Length ||
53                                             s [i] < '\uD800' ||
54                                             s [i] >= '\uDC00' ||
55                                             s [i + 1] < '\uDC00' ||
56                                             s [i + 1] >= '\uE000')
57                                                 return i;
58                                         i++;
59                                 }
60                         return -1;
61                 }
62
63                 public static int IndexOfInvalid (char [] s, int start, int length, bool allowSurrogate)
64                 {
65                         int end = start + length;
66                         if (s.Length < end)
67                                 throw new ArgumentOutOfRangeException ("length");
68                         for (int i = start; i < end; i++)
69                                 if (IsInvalid (s [i])) {
70                                         if (!allowSurrogate ||
71                                             i + 1 == end ||
72                                             s [i] < '\uD800' ||
73                                             s [i] >= '\uDC00' ||
74                                             s [i + 1] < '\uDC00' ||
75                                             s [i + 1] >= '\uE000')
76                                                 return i;
77                                         i++;
78                                 }
79                         return -1;
80                 }
81
82                 public WellFormedXmlWriter (XmlWriter writer) : base (writer)
83                 {
84                 }
85
86                 public override void WriteString (string text)
87                 {
88                         int i = IndexOfInvalid (text, true);
89                         if (i >= 0) {
90                                 char [] arr = text.ToCharArray ();
91                                 Writer.WriteChars (arr, 0, i);
92                                 WriteChars (arr, i, arr.Length - i);
93                         } else {
94                                 // no invalid character.
95                                 Writer.WriteString (text);
96                         }
97                 }
98
99                 public override void WriteChars (char [] text, int idx, int length)
100                 {
101                         int start = idx;
102                         int end = idx + length;
103                         while ((idx = IndexOfInvalid (text, start, length, true)) >= 0) {
104                                 if (start < idx)
105                                         Writer.WriteChars (text, start, idx - start);
106                                 Writer.WriteString (String.Format (CultureInfo.InvariantCulture,
107                                         text [idx] < 0x80 ? "\\x{0:X02}" : "\\u{0:X04}",
108                                         (int) text [idx]));
109                                 length -= idx - start + 1;
110                                 start = idx + 1;
111                         }
112                         if (start < end)
113                                 Writer.WriteChars (text, start, end - start);
114                 }
115
116         }
117
118         public class DefaultXmlWriter : XmlWriter
119         {
120                 XmlWriter writer;
121
122                 public DefaultXmlWriter (XmlWriter writer)
123                 {
124                         this.writer = writer;
125                 }
126
127                 protected XmlWriter Writer {
128                         get { return writer; }
129                 }
130
131                 public override void Close ()
132                 {
133                         writer.Close ();
134                 }
135
136                 public override void Flush ()
137                 {
138                         writer.Flush ();
139                 }
140
141                 public override string LookupPrefix (string ns)
142                 {
143                         return writer.LookupPrefix (ns);
144                 }
145
146                 public override void WriteBase64 (byte [] buffer, int index, int count)
147                 {
148                         writer.WriteBase64 (buffer, index, count);
149                 }
150
151                 public override void WriteBinHex (byte [] buffer, int index, int count)
152                 {
153                         writer.WriteBinHex (buffer, index, count);
154                 }
155
156                 public override void WriteCData (string text)
157                 {
158                         writer.WriteCData (text);
159                 }
160
161                 public override void WriteCharEntity (char ch)
162                 {
163                         writer.WriteCharEntity (ch);
164                 }
165
166                 public override void WriteChars (char [] buffer, int index, int count)
167                 {
168                         writer.WriteChars (buffer, index, count);
169                 }
170
171                 public override void WriteComment (string text)
172                 {
173                         writer.WriteComment (text);
174                 }
175
176                 public override void WriteDocType (string name, string pubid, string sysid, string subset)
177                 {
178                         writer.WriteDocType (name, pubid, sysid, subset);
179                 }
180
181                 public override void WriteEndAttribute ()
182                 {
183                         writer.WriteEndAttribute ();
184                 }
185
186                 public override void WriteEndDocument ()
187                 {
188                         writer.WriteEndDocument ();
189                 }
190
191                 public override void WriteEndElement ()
192                 {
193                         writer.WriteEndElement ();
194                 }
195
196                 public override void WriteEntityRef (string name)
197                 {
198                         writer.WriteEntityRef (name);
199                 }
200
201                 public override void WriteFullEndElement ()
202                 {
203                         writer.WriteFullEndElement ();
204                 }
205
206                 public override void WriteName (string name)
207                 {
208                         writer.WriteName (name);
209                 }
210
211                 public override void WriteNmToken (string name)
212                 {
213                         writer.WriteNmToken (name);
214                 }
215
216                 public override void WriteNode (XmlReader reader, bool defattr)
217                 {
218                         writer.WriteNode (reader, defattr);
219                 }
220
221                 public override void WriteProcessingInstruction (string name, string text)
222                 {
223                         writer.WriteProcessingInstruction (name, text);
224                 }
225
226                 public override void WriteQualifiedName (string localName, string ns)
227                 {
228                         writer.WriteQualifiedName (localName, ns);
229                 }
230
231                 public override void WriteRaw (string data)
232                 {
233                         writer.WriteRaw (data);
234                 }
235
236                 public override void WriteRaw (char [] buffer, int index, int count)
237                 {
238                         writer.WriteRaw (buffer, index, count);
239                 }
240
241                 public override void WriteStartAttribute (string prefix, string localName, string ns)
242                 {
243                         writer.WriteStartAttribute (prefix, localName, ns);
244                 }
245
246                 public override void WriteStartDocument (bool standalone)
247                 {
248                         writer.WriteStartDocument (standalone);
249                 }
250
251                 public override void WriteStartDocument ()
252                 {
253                         writer.WriteStartDocument ();
254                 }
255
256                 public override void WriteStartElement (string prefix, string localName, string ns)
257                 {
258                         writer.WriteStartElement (prefix, localName, ns);
259                 }
260
261                 public override void WriteString (string text)
262                 {
263                         writer.WriteString (text);
264                 }
265
266                 public override void WriteSurrogateCharEntity (char lowChar, char highChar)
267                 {
268                         writer.WriteSurrogateCharEntity (lowChar, highChar);
269                 }
270
271                 public override void WriteWhitespace (string ws)
272                 {
273                         writer.WriteWhitespace (ws);
274                 }
275
276                 public override WriteState WriteState {
277                         get {
278                                 return writer.WriteState;
279                         }
280                 }
281
282                 public override string XmlLang {
283                         get {
284                                 return writer.XmlLang;
285                         }
286                 }
287
288                 public override XmlSpace XmlSpace {
289                         get {
290                                 return writer.XmlSpace;
291                         }
292                 }
293         }
294 }