Welcome to mirror list, hosted at ThFree Co, Russian Federation.

XmlRawWriter.cs « Core « Xml « System « System.Xml « referencesource « class « mcs - github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 0de566338830afa6025e374bcd5ea6a25c0c5128 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

//------------------------------------------------------------------------------
// <copyright file="XmlRawWriter.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------

using System;
using System.IO;
using System.Diagnostics;
#if !SILVERLIGHT
using System.Xml.XPath;
#endif
using System.Xml.Schema;
using System.Collections;

namespace System.Xml {

    /// <summary>
    /// Implementations of XmlRawWriter are intended to be wrapped by the XmlWellFormedWriter.  The
    /// well-formed writer performs many checks in behalf of the raw writer, and keeps state that the
    /// raw writer otherwise would have to keep.  Therefore, the well-formed writer will call the
    /// XmlRawWriter using the following rules, in order to make raw writers easier to implement:
    ///
    ///  1. The well-formed writer keeps a stack of element names, and always calls
    ///     WriteEndElement(string, string, string) instead of WriteEndElement().
    ///  2. The well-formed writer tracks namespaces, and will pass himself in via the
    ///     WellformedWriter property. It is used in the XmlRawWriter's implementation of IXmlNamespaceResolver.
    ///     Thus, LookupPrefix does not have to be implemented.
    ///  3. The well-formed writer tracks write states, so the raw writer doesn't need to.
    ///  4. The well-formed writer will always call StartElementContent.
    ///  5. The well-formed writer will always call WriteNamespaceDeclaration for namespace nodes,
    ///     rather than calling WriteStartAttribute(). If the writer is supporting namespace declarations in chunks
    ///     (SupportsNamespaceDeclarationInChunks is true), the XmlWellFormedWriter will call WriteStartNamespaceDeclaration,
    ///      then any method that can be used to write out a value of an attribute (WriteString, WriteChars, WriteRaw, WriteCharEntity...) 
    ///      and then WriteEndNamespaceDeclaration - instead of just a single WriteNamespaceDeclaration call. This feature will be 
    ///      supported by raw writers serializing to text that wish to preserve the attribute value escaping etc.
    ///  6. The well-formed writer guarantees a well-formed document, including correct call sequences,
    ///     correct namespaces, and correct document rule enforcement.
    ///  7. All element and attribute names will be fully resolved and validated.  Null will never be
    ///     passed for any of the name parts.
    ///  8. The well-formed writer keeps track of xml:space and xml:lang.
    ///  9. The well-formed writer verifies NmToken, Name, and QName values and calls WriteString().
    /// </summary>
    internal abstract partial class XmlRawWriter : XmlWriter {

//
// Fields
//
        // base64 converter
        protected XmlRawWriterBase64Encoder base64Encoder;

        // namespace resolver
        protected IXmlNamespaceResolver resolver;

//
// XmlWriter implementation
//

        // Raw writers do not have to track whether this is a well-formed document.
        public override void WriteStartDocument() {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        public override void WriteStartDocument(bool standalone) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        public override void WriteEndDocument() {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

#if !SILVERLIGHT // This code is not being hit in Silverlight
        public override void WriteDocType(string name, string pubid, string sysid, string subset) {

        }
#endif

        // Raw writers do not have to keep a stack of element names.
        public override void WriteEndElement() {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        // Raw writers do not have to keep a stack of element names.
        public override void WriteFullEndElement() {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        // By default, convert base64 value to string and call WriteString.
        public override void WriteBase64( byte[] buffer, int index, int count ) {
            if ( base64Encoder == null ) {
                base64Encoder = new XmlRawWriterBase64Encoder( this );
            }
            // Encode will call WriteRaw to write out the encoded characters
            base64Encoder.Encode( buffer, index, count );
        }

        // Raw writers do not have to keep track of namespaces.
        public override string LookupPrefix( string ns ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        // Raw writers do not have to keep track of write states.
        public override WriteState WriteState {
            get {
                throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
            }
        }

        // Raw writers do not have to keep track of xml:space.
        public override XmlSpace XmlSpace { 
            get { throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) ); }
        }

        // Raw writers do not have to keep track of xml:lang.
        public override string XmlLang { 
            get { throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) ); }
        }

        // Raw writers do not have to verify NmToken values.
        public override void WriteNmToken( string name ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        // Raw writers do not have to verify Name values.
        public override void WriteName( string name ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        // Raw writers do not have to verify QName values.
        public override void WriteQualifiedName( string localName, string ns ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

#if !SILVERLIGHT // This code is not being hit in Silverlight
        // Forward call to WriteString(string).
        public override void WriteCData( string text ) {
            WriteString( text );
        }

        // Forward call to WriteString(string).
        public override void WriteCharEntity( char ch ) {
            WriteString( new string( new char[] {ch} ) );
        }

        // Forward call to WriteString(string).
        public override void WriteSurrogateCharEntity( char lowChar, char highChar ) {
            WriteString( new string( new char[] {lowChar, highChar} ) );
        }

        // Forward call to WriteString(string).
        public override void WriteWhitespace( string ws ) {
            WriteString( ws );
        }

        // Forward call to WriteString(string).
        public override void WriteChars( char[] buffer, int index, int count ) {
            WriteString( new string( buffer, index, count ) );
        }

        // Forward call to WriteString(string).
        public override void WriteRaw(char[] buffer, int index, int count) {
            WriteString( new string( buffer, index, count ) );
        }

        // Forward call to WriteString(string).
        public override void WriteRaw(string data) {
            WriteString( data );
        }
#endif

        // Override in order to handle Xml simple typed values and to pass resolver for QName values
        public override void WriteValue(object value) {
            if ( value == null ) {
                throw new ArgumentNullException( "value" );
            }
#if SILVERLIGHT // 
            WriteString(XmlUntypedStringConverter.Instance.ToString( value, resolver ) );
#else
            WriteString(XmlUntypedConverter.Untyped.ToString( value, resolver ) );
#endif
        }

        // Override in order to handle Xml simple typed values and to pass resolver for QName values
        public override void WriteValue( string value ) {
            WriteString( value );
        }

        public override void WriteValue(DateTimeOffset value) {
            // For compatibility with custom writers, XmlWriter writes DateTimeOffset as DateTime. 
            // Our internal writers should use the DateTimeOffset-String conversion from XmlConvert.
            WriteString(XmlConvert.ToString(value));
        }

        // Copying to XmlRawWriter is not currently supported.
        public override void WriteAttributes( XmlReader reader, bool defattr ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

        public override void WriteNode( XmlReader reader, bool defattr ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }

#if !SILVERLIGHT  // Removing dependency on XPathNavigator
        public override void WriteNode( System.Xml.XPath.XPathNavigator navigator, bool defattr ) {
            throw new InvalidOperationException( Res.GetString( Res.Xml_InvalidOperation ) );
        }
#endif

//
// XmlRawWriter methods and properties
//

        // Get and set the namespace resolver that's used by this RawWriter to resolve prefixes.
        internal virtual IXmlNamespaceResolver NamespaceResolver  {
            get {
                return resolver;
            }
            set {
                resolver = value;
            }
        }

        // Write the xml declaration.  This must be the first call.
#if !SILVERLIGHT // This code is not being hit in Silverlight
        internal virtual void WriteXmlDeclaration( XmlStandalone standalone ) {

        }
        internal virtual void WriteXmlDeclaration( string xmldecl ) {

        }
#else

        internal abstract void WriteXmlDeclaration(XmlStandalone standalone);

        internal abstract void WriteXmlDeclaration(string xmldecl);

#endif

        // Called after an element's attributes have been enumerated, but before any children have been
        // enumerated.  This method must always be called, even for empty elements.

        internal abstract void StartElementContent();

        // Called before a root element is written (before the WriteStartElement call)
        //   the conformanceLevel specifies the current conformance level the writer is operating with.
        internal virtual void OnRootElement(ConformanceLevel conformanceLevel) { }

        // WriteEndElement() and WriteFullEndElement() overloads, in which caller gives the full name of the
        // element, so that raw writers do not need to keep a stack of element names.  This method should
        // always be called instead of WriteEndElement() or WriteFullEndElement() without parameters.

        internal abstract void WriteEndElement( string prefix, string localName, string ns );

#if !SILVERLIGHT // This code is not being hit in Silverlight
        internal virtual void WriteFullEndElement( string prefix, string localName, string ns ) {
            WriteEndElement( prefix, localName, ns );
        }
#else

        internal abstract void WriteFullEndElement(string prefix, string localName, string ns);

#endif

        internal virtual void WriteQualifiedName( string prefix, string localName, string ns ) {
            if ( prefix.Length != 0 ) {
                WriteString( prefix );
                WriteString( ":" );
            }
            WriteString( localName );
        }

        // This method must be called instead of WriteStartAttribute() for namespaces.

        internal abstract void WriteNamespaceDeclaration( string prefix, string ns );

        // When true, the XmlWellFormedWriter will call:
        //      1) WriteStartNamespaceDeclaration
        //      2) any method that can be used to write out a value of an attribute: WriteString, WriteChars, WriteRaw, WriteCharEntity... 
        //      3) WriteEndNamespaceDeclaration
        // instead of just a single WriteNamespaceDeclaration call. 
        //
        // This feature will be supported by raw writers serializing to text that wish to preserve the attribute value escaping and entities.
        internal virtual bool SupportsNamespaceDeclarationInChunks {
            get {
                return false;
            }
        }

        internal virtual void WriteStartNamespaceDeclaration(string prefix) {
            throw new NotSupportedException();
        }

        internal virtual void WriteEndNamespaceDeclaration() {
            throw new NotSupportedException();
        }

        // This is called when the remainder of a base64 value should be output.
        internal virtual void WriteEndBase64() {
            // The Flush will call WriteRaw to write out the rest of the encoded characters
            base64Encoder.Flush();
        }

        internal virtual void Close( WriteState currentState ) {
            Close();
        }

    }
}