1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.IO;
7 using System.Xml;
8 using System.Collections;
9 using System.Collections.Generic;
10 using System.Diagnostics;
11 using System.Runtime.InteropServices;
12 using System.Runtime.Serialization;
13 using System.Security;
14 using System.Text;
15 using System.Threading.Tasks;
16 
17 namespace System.Xml
18 {
19     public abstract class XmlDictionaryWriter : XmlWriter
20     {
CreateBinaryWriter(Stream stream)21         public static XmlDictionaryWriter CreateBinaryWriter(Stream stream)
22         {
23             return CreateBinaryWriter(stream, null);
24         }
25 
CreateBinaryWriter(Stream stream, IXmlDictionary dictionary)26         public static XmlDictionaryWriter CreateBinaryWriter(Stream stream, IXmlDictionary dictionary)
27         {
28             return CreateBinaryWriter(stream, dictionary, null);
29         }
30 
CreateBinaryWriter(Stream stream, IXmlDictionary dictionary, XmlBinaryWriterSession session)31         public static XmlDictionaryWriter CreateBinaryWriter(Stream stream, IXmlDictionary dictionary, XmlBinaryWriterSession session)
32         {
33             return CreateBinaryWriter(stream, dictionary, session, true);
34         }
35 
CreateBinaryWriter(Stream stream, IXmlDictionary dictionary, XmlBinaryWriterSession session, bool ownsStream)36         public static XmlDictionaryWriter CreateBinaryWriter(Stream stream, IXmlDictionary dictionary, XmlBinaryWriterSession session, bool ownsStream)
37         {
38             XmlBinaryWriter writer = new XmlBinaryWriter();
39             writer.SetOutput(stream, dictionary, session, ownsStream);
40             return writer;
41         }
42 
43         private static readonly Encoding s_UTF8Encoding = new UTF8Encoding(false);
CreateTextWriter(Stream stream)44         public static XmlDictionaryWriter CreateTextWriter(Stream stream)
45         {
46             return CreateTextWriter(stream, s_UTF8Encoding, true);
47         }
48 
CreateTextWriter(Stream stream, Encoding encoding)49         public static XmlDictionaryWriter CreateTextWriter(Stream stream, Encoding encoding)
50         {
51             return CreateTextWriter(stream, encoding, true);
52         }
53 
CreateTextWriter(Stream stream, Encoding encoding, bool ownsStream)54         public static XmlDictionaryWriter CreateTextWriter(Stream stream, Encoding encoding, bool ownsStream)
55         {
56             XmlUTF8TextWriter writer = new XmlUTF8TextWriter();
57             writer.SetOutput(stream, encoding, ownsStream);
58             var asyncWriter = new XmlDictionaryAsyncCheckWriter(writer);
59             return asyncWriter;
60         }
61 
CreateMtomWriter(Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo)62         public static XmlDictionaryWriter CreateMtomWriter(Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo)
63         {
64             return CreateMtomWriter(stream, encoding, maxSizeInBytes, startInfo, null, null, true, true);
65         }
66 
CreateMtomWriter(Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo, string boundary, string startUri, bool writeMessageHeaders, bool ownsStream)67         public static XmlDictionaryWriter CreateMtomWriter(Stream stream, Encoding encoding, int maxSizeInBytes, string startInfo, string boundary, string startUri, bool writeMessageHeaders, bool ownsStream)
68         {
69             throw new PlatformNotSupportedException(SR.PlatformNotSupported_MtomEncoding);
70         }
71 
CreateDictionaryWriter(XmlWriter writer)72         public static XmlDictionaryWriter CreateDictionaryWriter(XmlWriter writer)
73         {
74             if (writer == null)
75                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));
76 
77             XmlDictionaryWriter dictionaryWriter = writer as XmlDictionaryWriter;
78 
79             if (dictionaryWriter == null)
80             {
81                 dictionaryWriter = new XmlWrappedWriter(writer);
82             }
83 
84             return dictionaryWriter;
85         }
86 
WriteBase64Async(byte[] buffer, int index, int count)87         public override Task WriteBase64Async(byte[] buffer, int index, int count)
88         {
89             WriteBase64(buffer, index, count);
90             return Task.CompletedTask;
91         }
92 
WriteStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)93         public void WriteStartElement(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
94         {
95             WriteStartElement((string)null, localName, namespaceUri);
96         }
97 
WriteStartElement(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri)98         public virtual void WriteStartElement(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri)
99         {
100             WriteStartElement(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri));
101         }
102 
WriteStartAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri)103         public void WriteStartAttribute(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
104         {
105             WriteStartAttribute((string)null, localName, namespaceUri);
106         }
107 
WriteStartAttribute(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri)108         public virtual void WriteStartAttribute(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri)
109         {
110             WriteStartAttribute(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri));
111         }
112 
WriteAttributeString(XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)113         public void WriteAttributeString(XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)
114         {
115             WriteAttributeString((string)null, localName, namespaceUri, value);
116         }
117 
WriteXmlnsAttribute(string prefix, string namespaceUri)118         public virtual void WriteXmlnsAttribute(string prefix, string namespaceUri)
119         {
120             if (namespaceUri == null)
121                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(namespaceUri));
122             if (prefix == null)
123             {
124                 if (LookupPrefix(namespaceUri) != null)
125                     return;
126 #pragma warning suppress 56506 // Microsoft, namespaceUri is already checked
127                 prefix = namespaceUri.Length == 0 ? string.Empty : string.Concat("d", namespaceUri.Length.ToString(System.Globalization.NumberFormatInfo.InvariantInfo));
128             }
129             WriteAttributeString("xmlns", prefix, null, namespaceUri);
130         }
131 
WriteXmlnsAttribute(string prefix, XmlDictionaryString namespaceUri)132         public virtual void WriteXmlnsAttribute(string prefix, XmlDictionaryString namespaceUri)
133         {
134             WriteXmlnsAttribute(prefix, XmlDictionaryString.GetString(namespaceUri));
135         }
136 
WriteXmlAttribute(string localName, string value)137         public virtual void WriteXmlAttribute(string localName, string value)
138         {
139             WriteAttributeString("xml", localName, null, value);
140         }
141 
WriteXmlAttribute(XmlDictionaryString localName, XmlDictionaryString value)142         public virtual void WriteXmlAttribute(XmlDictionaryString localName, XmlDictionaryString value)
143         {
144             WriteXmlAttribute(XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(value));
145         }
146 
WriteAttributeString(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)147         public void WriteAttributeString(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)
148         {
149             WriteStartAttribute(prefix, localName, namespaceUri);
150             WriteString(value);
151             WriteEndAttribute();
152         }
153 
WriteElementString(XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)154         public void WriteElementString(XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)
155         {
156             WriteElementString((string)null, localName, namespaceUri, value);
157         }
158 
WriteElementString(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)159         public void WriteElementString(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, string value)
160         {
161             WriteStartElement(prefix, localName, namespaceUri);
162             WriteString(value);
163             WriteEndElement();
164         }
165 
WriteString(XmlDictionaryString value)166         public virtual void WriteString(XmlDictionaryString value)
167         {
168             WriteString(XmlDictionaryString.GetString(value));
169         }
170 
WriteQualifiedName(XmlDictionaryString localName, XmlDictionaryString namespaceUri)171         public virtual void WriteQualifiedName(XmlDictionaryString localName, XmlDictionaryString namespaceUri)
172         {
173             if (localName == null)
174                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(localName)));
175             if (namespaceUri == null)
176                 namespaceUri = XmlDictionaryString.Empty;
177 #pragma warning suppress 56506 // Microsoft, XmlDictionaryString.Empty is never null
178             WriteQualifiedName(localName.Value, namespaceUri.Value);
179         }
180 
WriteValue(XmlDictionaryString value)181         public virtual void WriteValue(XmlDictionaryString value)
182         {
183             WriteValue(XmlDictionaryString.GetString(value));
184         }
185 
186 
WriteValue(UniqueId value)187         public virtual void WriteValue(UniqueId value)
188         {
189             if (value == null)
190                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value));
191 
192             WriteString(value.ToString());
193         }
194 
WriteValue(Guid value)195         public virtual void WriteValue(Guid value)
196         {
197             WriteString(value.ToString());
198         }
199 
WriteValue(TimeSpan value)200         public virtual void WriteValue(TimeSpan value)
201         {
202             WriteString(XmlConvert.ToString(value));
203         }
204 
WriteValue(IStreamProvider value)205         public virtual void WriteValue(IStreamProvider value)
206         {
207             if (value == null)
208                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(value)));
209 
210             Stream stream = value.GetStream();
211             if (stream == null)
212                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new XmlException(SR.Format(SR.XmlInvalidStream)));
213             int blockSize = 256;
214             int bytesRead = 0;
215             byte[] block = new byte[blockSize];
216             while (true)
217             {
218                 bytesRead = stream.Read(block, 0, blockSize);
219                 if (bytesRead > 0)
220                     WriteBase64(block, 0, bytesRead);
221                 else
222                     break;
223                 if (blockSize < 65536 && bytesRead == blockSize)
224                 {
225                     blockSize = blockSize * 16;
226                     block = new byte[blockSize];
227                 }
228             }
229             value.ReleaseStream(stream);
230         }
231 
WriteValueAsync(IStreamProvider value)232         public virtual Task WriteValueAsync(IStreamProvider value)
233         {
234             WriteValue(value);
235             return Task.CompletedTask;
236         }
237 
238         public virtual bool CanCanonicalize
239         {
240             get
241             {
242                 return false;
243             }
244         }
245 
StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes)246         public virtual void StartCanonicalization(Stream stream, bool includeComments, string[] inclusivePrefixes)
247         {
248             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
249         }
250 
EndCanonicalization()251         public virtual void EndCanonicalization()
252         {
253             throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
254         }
255 
WriteElementNode(XmlDictionaryReader reader, bool defattr)256         private void WriteElementNode(XmlDictionaryReader reader, bool defattr)
257         {
258             XmlDictionaryString localName;
259             XmlDictionaryString namespaceUri;
260             if (reader.TryGetLocalNameAsDictionaryString(out localName) && reader.TryGetNamespaceUriAsDictionaryString(out namespaceUri))
261             {
262                 WriteStartElement(reader.Prefix, localName, namespaceUri);
263             }
264             else
265             {
266                 WriteStartElement(reader.Prefix, reader.LocalName, reader.NamespaceURI);
267             }
268             if (defattr || !reader.IsDefault)
269             {
270                 if (reader.MoveToFirstAttribute())
271                 {
272                     do
273                     {
274                         if (reader.TryGetLocalNameAsDictionaryString(out localName) && reader.TryGetNamespaceUriAsDictionaryString(out namespaceUri))
275                         {
276                             WriteStartAttribute(reader.Prefix, localName, namespaceUri);
277                         }
278                         else
279                         {
280                             WriteStartAttribute(reader.Prefix, reader.LocalName, reader.NamespaceURI);
281                         }
282                         while (reader.ReadAttributeValue())
283                         {
284                             if (reader.NodeType == XmlNodeType.EntityReference)
285                             {
286                                 WriteEntityRef(reader.Name);
287                             }
288                             else
289                             {
290                                 WriteTextNode(reader, true);
291                             }
292                         }
293                         WriteEndAttribute();
294                     }
295                     while (reader.MoveToNextAttribute());
296                     reader.MoveToElement();
297                 }
298             }
299             if (reader.IsEmptyElement)
300             {
301                 WriteEndElement();
302             }
303         }
304 
WriteArrayNode(XmlDictionaryReader reader, string prefix, string localName, string namespaceUri, Type type)305         private void WriteArrayNode(XmlDictionaryReader reader, string prefix, string localName, string namespaceUri, Type type)
306         {
307             if (type == typeof(bool))
308                 BooleanArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
309             else if (type == typeof(Int16))
310                 Int16ArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
311             else if (type == typeof(Int32))
312                 Int32ArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
313             else if (type == typeof(Int64))
314                 Int64ArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
315             else if (type == typeof(float))
316                 SingleArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
317             else if (type == typeof(double))
318                 DoubleArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
319             else if (type == typeof(decimal))
320                 DecimalArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
321             else if (type == typeof(DateTime))
322                 DateTimeArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
323             else if (type == typeof(Guid))
324                 GuidArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
325             else if (type == typeof(TimeSpan))
326                 TimeSpanArrayHelperWithString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
327             else
328             {
329                 WriteElementNode(reader, false);
330                 reader.Read();
331             }
332         }
333 
WriteArrayNode(XmlDictionaryReader reader, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Type type)334         private void WriteArrayNode(XmlDictionaryReader reader, string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Type type)
335         {
336             if (type == typeof(bool))
337                 BooleanArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
338             else if (type == typeof(Int16))
339                 Int16ArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
340             else if (type == typeof(Int32))
341                 Int32ArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
342             else if (type == typeof(Int64))
343                 Int64ArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
344             else if (type == typeof(float))
345                 SingleArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
346             else if (type == typeof(double))
347                 DoubleArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
348             else if (type == typeof(decimal))
349                 DecimalArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
350             else if (type == typeof(DateTime))
351                 DateTimeArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
352             else if (type == typeof(Guid))
353                 GuidArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
354             else if (type == typeof(TimeSpan))
355                 TimeSpanArrayHelperWithDictionaryString.Instance.WriteArray(this, prefix, localName, namespaceUri, reader);
356             else
357             {
358                 WriteElementNode(reader, false);
359                 reader.Read();
360             }
361         }
362 
WriteArrayNode(XmlDictionaryReader reader, Type type)363         private void WriteArrayNode(XmlDictionaryReader reader, Type type)
364         {
365             XmlDictionaryString localName;
366             XmlDictionaryString namespaceUri;
367             if (reader.TryGetLocalNameAsDictionaryString(out localName) && reader.TryGetNamespaceUriAsDictionaryString(out namespaceUri))
368                 WriteArrayNode(reader, reader.Prefix, localName, namespaceUri, type);
369             else
370                 WriteArrayNode(reader, reader.Prefix, reader.LocalName, reader.NamespaceURI, type);
371         }
372 
WriteTextNode(XmlDictionaryReader reader, bool isAttribute)373         protected virtual void WriteTextNode(XmlDictionaryReader reader, bool isAttribute)
374         {
375             XmlDictionaryString value;
376             if (reader.TryGetValueAsDictionaryString(out value))
377             {
378                 WriteString(value);
379             }
380             else
381             {
382                 WriteString(reader.Value);
383             }
384             if (!isAttribute)
385             {
386                 reader.Read();
387             }
388         }
389 
WriteNode(XmlReader reader, bool defattr)390         public override void WriteNode(XmlReader reader, bool defattr)
391         {
392             XmlDictionaryReader dictionaryReader = reader as XmlDictionaryReader;
393             if (dictionaryReader != null)
394                 WriteNode(dictionaryReader, defattr);
395             else
396                 base.WriteNode(reader, defattr);
397         }
398 
WriteNode(XmlDictionaryReader reader, bool defattr)399         public virtual void WriteNode(XmlDictionaryReader reader, bool defattr)
400         {
401             if (reader == null)
402                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(reader)));
403             int d = (reader.NodeType == XmlNodeType.None ? -1 : reader.Depth);
404             do
405             {
406                 XmlNodeType nodeType = reader.NodeType;
407                 Type type;
408                 if (nodeType == XmlNodeType.Text || nodeType == XmlNodeType.Whitespace || nodeType == XmlNodeType.SignificantWhitespace)
409                 {
410                     // This will advance if necessary, so we don't need to call Read() explicitly
411                     WriteTextNode(reader, false);
412                 }
413                 else if (reader.Depth > d && reader.IsStartArray(out type))
414                 {
415                     WriteArrayNode(reader, type);
416                 }
417                 else
418                 {
419                     // These will not advance, so we must call Read() explicitly
420                     switch (nodeType)
421                     {
422                         case XmlNodeType.Element:
423                             WriteElementNode(reader, defattr);
424                             break;
425                         case XmlNodeType.CDATA:
426                             WriteCData(reader.Value);
427                             break;
428                         case XmlNodeType.EntityReference:
429                             WriteEntityRef(reader.Name);
430                             break;
431                         case XmlNodeType.XmlDeclaration:
432                         case XmlNodeType.ProcessingInstruction:
433                             WriteProcessingInstruction(reader.Name, reader.Value);
434                             break;
435                         case XmlNodeType.DocumentType:
436                             WriteDocType(reader.Name, reader.GetAttribute("PUBLIC"), reader.GetAttribute("SYSTEM"), reader.Value);
437                             break;
438                         case XmlNodeType.Comment:
439                             WriteComment(reader.Value);
440                             break;
441                         case XmlNodeType.EndElement:
442                             WriteFullEndElement();
443                             break;
444                     }
445                     if (!reader.Read())
446                         break;
447                 }
448             }
449             while (d < reader.Depth || (d == reader.Depth && reader.NodeType == XmlNodeType.EndElement));
450         }
451 
CheckArray(Array array, int offset, int count)452         private void CheckArray(Array array, int offset, int count)
453         {
454             if (array == null)
455                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException(nameof(array)));
456             if (offset < 0)
457                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(offset), SR.Format(SR.ValueMustBeNonNegative)));
458             if (offset > array.Length)
459                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(offset), SR.Format(SR.OffsetExceedsBufferSize, array.Length)));
460             if (count < 0)
461                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.ValueMustBeNonNegative)));
462             if (count > array.Length - offset)
463                 throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(count), SR.Format(SR.SizeExceedsRemainingBufferSpace, array.Length - offset)));
464         }
465 
466         // bool
WriteArray(string prefix, string localName, string namespaceUri, bool[] array, int offset, int count)467         public virtual void WriteArray(string prefix, string localName, string namespaceUri, bool[] array, int offset, int count)
468         {
469             CheckArray(array, offset, count);
470             for (int i = 0; i < count; i++)
471             {
472                 WriteStartElement(prefix, localName, namespaceUri);
473                 WriteValue(array[offset + i]);
474                 WriteEndElement();
475             }
476         }
477 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)478         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, bool[] array, int offset, int count)
479         {
480             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
481         }
482 
483         // Int16
WriteArray(string prefix, string localName, string namespaceUri, Int16[] array, int offset, int count)484         public virtual void WriteArray(string prefix, string localName, string namespaceUri, Int16[] array, int offset, int count)
485         {
486             CheckArray(array, offset, count);
487             for (int i = 0; i < count; i++)
488             {
489                 WriteStartElement(prefix, localName, namespaceUri);
490                 WriteValue(array[offset + i]);
491                 WriteEndElement();
492             }
493         }
494 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int16[] array, int offset, int count)495         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int16[] array, int offset, int count)
496         {
497             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
498         }
499 
500         // Int32
WriteArray(string prefix, string localName, string namespaceUri, Int32[] array, int offset, int count)501         public virtual void WriteArray(string prefix, string localName, string namespaceUri, Int32[] array, int offset, int count)
502         {
503             CheckArray(array, offset, count);
504             for (int i = 0; i < count; i++)
505             {
506                 WriteStartElement(prefix, localName, namespaceUri);
507                 WriteValue(array[offset + i]);
508                 WriteEndElement();
509             }
510         }
511 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int32[] array, int offset, int count)512         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int32[] array, int offset, int count)
513         {
514             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
515         }
516 
517         // Int64
WriteArray(string prefix, string localName, string namespaceUri, Int64[] array, int offset, int count)518         public virtual void WriteArray(string prefix, string localName, string namespaceUri, Int64[] array, int offset, int count)
519         {
520             CheckArray(array, offset, count);
521             for (int i = 0; i < count; i++)
522             {
523                 WriteStartElement(prefix, localName, namespaceUri);
524                 WriteValue(array[offset + i]);
525                 WriteEndElement();
526             }
527         }
528 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int64[] array, int offset, int count)529         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Int64[] array, int offset, int count)
530         {
531             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
532         }
533 
534         // float
WriteArray(string prefix, string localName, string namespaceUri, float[] array, int offset, int count)535         public virtual void WriteArray(string prefix, string localName, string namespaceUri, float[] array, int offset, int count)
536         {
537             CheckArray(array, offset, count);
538             for (int i = 0; i < count; i++)
539             {
540                 WriteStartElement(prefix, localName, namespaceUri);
541                 WriteValue(array[offset + i]);
542                 WriteEndElement();
543             }
544         }
545 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)546         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, float[] array, int offset, int count)
547         {
548             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
549         }
550 
551         // double
WriteArray(string prefix, string localName, string namespaceUri, double[] array, int offset, int count)552         public virtual void WriteArray(string prefix, string localName, string namespaceUri, double[] array, int offset, int count)
553         {
554             CheckArray(array, offset, count);
555             for (int i = 0; i < count; i++)
556             {
557                 WriteStartElement(prefix, localName, namespaceUri);
558                 WriteValue(array[offset + i]);
559                 WriteEndElement();
560             }
561         }
562 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)563         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, double[] array, int offset, int count)
564         {
565             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
566         }
567 
568         // decimal
WriteArray(string prefix, string localName, string namespaceUri, decimal[] array, int offset, int count)569         public virtual void WriteArray(string prefix, string localName, string namespaceUri, decimal[] array, int offset, int count)
570         {
571             CheckArray(array, offset, count);
572             for (int i = 0; i < count; i++)
573             {
574                 WriteStartElement(prefix, localName, namespaceUri);
575                 WriteValue(array[offset + i]);
576                 WriteEndElement();
577             }
578         }
579 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)580         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, decimal[] array, int offset, int count)
581         {
582             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
583         }
584 
585         // DateTime
WriteArray(string prefix, string localName, string namespaceUri, DateTime[] array, int offset, int count)586         public virtual void WriteArray(string prefix, string localName, string namespaceUri, DateTime[] array, int offset, int count)
587         {
588             CheckArray(array, offset, count);
589             for (int i = 0; i < count; i++)
590             {
591                 WriteStartElement(prefix, localName, namespaceUri);
592                 WriteValue(array[offset + i]);
593                 WriteEndElement();
594             }
595         }
596 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)597         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, DateTime[] array, int offset, int count)
598         {
599             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
600         }
601 
602         // Guid
WriteArray(string prefix, string localName, string namespaceUri, Guid[] array, int offset, int count)603         public virtual void WriteArray(string prefix, string localName, string namespaceUri, Guid[] array, int offset, int count)
604         {
605             CheckArray(array, offset, count);
606             for (int i = 0; i < count; i++)
607             {
608                 WriteStartElement(prefix, localName, namespaceUri);
609                 WriteValue(array[offset + i]);
610                 WriteEndElement();
611             }
612         }
613 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)614         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, Guid[] array, int offset, int count)
615         {
616             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
617         }
618 
619         // TimeSpan
WriteArray(string prefix, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)620         public virtual void WriteArray(string prefix, string localName, string namespaceUri, TimeSpan[] array, int offset, int count)
621         {
622             CheckArray(array, offset, count);
623             for (int i = 0; i < count; i++)
624             {
625                 WriteStartElement(prefix, localName, namespaceUri);
626                 WriteValue(array[offset + i]);
627                 WriteEndElement();
628             }
629         }
630 
WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)631         public virtual void WriteArray(string prefix, XmlDictionaryString localName, XmlDictionaryString namespaceUri, TimeSpan[] array, int offset, int count)
632         {
633             WriteArray(prefix, XmlDictionaryString.GetString(localName), XmlDictionaryString.GetString(namespaceUri), array, offset, count);
634         }
635 
Dispose(bool disposing)636         protected override void Dispose(bool disposing)
637         {
638             if (disposing && WriteState != WriteState.Closed)
639             {
640                 Close();
641             }
642         }
643 
Close()644         public override void Close() { }
645 
646         private class XmlWrappedWriter : XmlDictionaryWriter
647         {
648             private XmlWriter _writer;
649             private int _depth;
650             private int _prefix;
651 
XmlWrappedWriter(XmlWriter writer)652             public XmlWrappedWriter(XmlWriter writer)
653             {
654                 _writer = writer;
655                 _depth = 0;
656             }
657 
Close()658             public override void Close()
659             {
660                 _writer.Dispose();
661             }
662 
Flush()663             public override void Flush()
664             {
665                 _writer.Flush();
666             }
667 
LookupPrefix(string namespaceUri)668             public override string LookupPrefix(string namespaceUri)
669             {
670                 return _writer.LookupPrefix(namespaceUri);
671             }
672 
WriteAttributes(XmlReader reader, bool defattr)673             public override void WriteAttributes(XmlReader reader, bool defattr)
674             {
675                 _writer.WriteAttributes(reader, defattr);
676             }
677 
WriteBase64(byte[] buffer, int index, int count)678             public override void WriteBase64(byte[] buffer, int index, int count)
679             {
680                 _writer.WriteBase64(buffer, index, count);
681             }
682 
WriteBinHex(byte[] buffer, int index, int count)683             public override void WriteBinHex(byte[] buffer, int index, int count)
684             {
685                 _writer.WriteBinHex(buffer, index, count);
686             }
687 
WriteCData(string text)688             public override void WriteCData(string text)
689             {
690                 _writer.WriteCData(text);
691             }
692 
WriteCharEntity(char ch)693             public override void WriteCharEntity(char ch)
694             {
695                 _writer.WriteCharEntity(ch);
696             }
697 
WriteChars(char[] buffer, int index, int count)698             public override void WriteChars(char[] buffer, int index, int count)
699             {
700                 _writer.WriteChars(buffer, index, count);
701             }
702 
WriteComment(string text)703             public override void WriteComment(string text)
704             {
705                 _writer.WriteComment(text);
706             }
707 
WriteDocType(string name, string pubid, string sysid, string subset)708             public override void WriteDocType(string name, string pubid, string sysid, string subset)
709             {
710                 _writer.WriteDocType(name, pubid, sysid, subset);
711             }
712 
WriteEndAttribute()713             public override void WriteEndAttribute()
714             {
715                 _writer.WriteEndAttribute();
716             }
717 
WriteEndDocument()718             public override void WriteEndDocument()
719             {
720                 _writer.WriteEndDocument();
721             }
722 
WriteEndElement()723             public override void WriteEndElement()
724             {
725                 _writer.WriteEndElement();
726                 _depth--;
727             }
728 
WriteEntityRef(string name)729             public override void WriteEntityRef(string name)
730             {
731                 _writer.WriteEntityRef(name);
732             }
733 
WriteFullEndElement()734             public override void WriteFullEndElement()
735             {
736                 _writer.WriteFullEndElement();
737             }
738 
WriteName(string name)739             public override void WriteName(string name)
740             {
741                 _writer.WriteName(name);
742             }
743 
WriteNmToken(string name)744             public override void WriteNmToken(string name)
745             {
746                 _writer.WriteNmToken(name);
747             }
748 
WriteNode(XmlReader reader, bool defattr)749             public override void WriteNode(XmlReader reader, bool defattr)
750             {
751                 _writer.WriteNode(reader, defattr);
752             }
753 
WriteProcessingInstruction(string name, string text)754             public override void WriteProcessingInstruction(string name, string text)
755             {
756                 _writer.WriteProcessingInstruction(name, text);
757             }
758 
WriteQualifiedName(string localName, string namespaceUri)759             public override void WriteQualifiedName(string localName, string namespaceUri)
760             {
761                 _writer.WriteQualifiedName(localName, namespaceUri);
762             }
763 
WriteRaw(char[] buffer, int index, int count)764             public override void WriteRaw(char[] buffer, int index, int count)
765             {
766                 _writer.WriteRaw(buffer, index, count);
767             }
768 
WriteRaw(string data)769             public override void WriteRaw(string data)
770             {
771                 _writer.WriteRaw(data);
772             }
773 
WriteStartAttribute(string prefix, string localName, string namespaceUri)774             public override void WriteStartAttribute(string prefix, string localName, string namespaceUri)
775             {
776                 _writer.WriteStartAttribute(prefix, localName, namespaceUri);
777                 _prefix++;
778             }
779 
WriteStartDocument()780             public override void WriteStartDocument()
781             {
782                 _writer.WriteStartDocument();
783             }
784 
WriteStartDocument(bool standalone)785             public override void WriteStartDocument(bool standalone)
786             {
787                 _writer.WriteStartDocument(standalone);
788             }
789 
WriteStartElement(string prefix, string localName, string namespaceUri)790             public override void WriteStartElement(string prefix, string localName, string namespaceUri)
791             {
792                 _writer.WriteStartElement(prefix, localName, namespaceUri);
793                 _depth++;
794                 _prefix = 1;
795             }
796 
797             public override WriteState WriteState
798             {
799                 get
800                 {
801                     return _writer.WriteState;
802                 }
803             }
804 
WriteString(string text)805             public override void WriteString(string text)
806             {
807                 _writer.WriteString(text);
808             }
809 
WriteSurrogateCharEntity(char lowChar, char highChar)810             public override void WriteSurrogateCharEntity(char lowChar, char highChar)
811             {
812                 _writer.WriteSurrogateCharEntity(lowChar, highChar);
813             }
814 
WriteWhitespace(string whitespace)815             public override void WriteWhitespace(string whitespace)
816             {
817                 _writer.WriteWhitespace(whitespace);
818             }
819 
WriteValue(object value)820             public override void WriteValue(object value)
821             {
822                 _writer.WriteValue(value);
823             }
824 
WriteValue(string value)825             public override void WriteValue(string value)
826             {
827                 _writer.WriteValue(value);
828             }
829 
WriteValue(bool value)830             public override void WriteValue(bool value)
831             {
832                 _writer.WriteValue(value);
833             }
834 
WriteValue(DateTimeOffset value)835             public override void WriteValue(DateTimeOffset value)
836             {
837                 _writer.WriteValue(value);
838             }
839 
WriteValue(double value)840             public override void WriteValue(double value)
841             {
842                 _writer.WriteValue(value);
843             }
844 
WriteValue(int value)845             public override void WriteValue(int value)
846             {
847                 _writer.WriteValue(value);
848             }
849 
WriteValue(long value)850             public override void WriteValue(long value)
851             {
852                 _writer.WriteValue(value);
853             }
854 
WriteXmlnsAttribute(string prefix, string namespaceUri)855             public override void WriteXmlnsAttribute(string prefix, string namespaceUri)
856             {
857                 if (namespaceUri == null)
858                     throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(namespaceUri));
859                 if (prefix == null)
860                 {
861                     if (LookupPrefix(namespaceUri) != null)
862                         return;
863 
864                     if (namespaceUri.Length == 0)
865                     {
866                         prefix = string.Empty;
867                     }
868                     else
869                     {
870                         string depthStr = _depth.ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
871                         string prefixStr = _prefix.ToString(System.Globalization.NumberFormatInfo.InvariantInfo);
872                         prefix = string.Concat("d", depthStr, "p", prefixStr);
873                     }
874                 }
875                 WriteAttributeString("xmlns", prefix, null, namespaceUri);
876             }
877 
878             public override string XmlLang
879             {
880                 get
881                 {
882                     return _writer.XmlLang;
883                 }
884             }
885 
886             public override XmlSpace XmlSpace
887             {
888                 get
889                 {
890                     return _writer.XmlSpace;
891                 }
892             }
893         }
894     }
895 }
896