File: StreamBodyWriter.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (206 lines) | stat: -rw-r--r-- 8,413 bytes parent folder | download | duplicates (7)
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
//----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation.  All rights reserved.
//----------------------------------------------------------------------------
namespace System.ServiceModel.Channels
{
    using System;
    using System.IO;
    using System.Runtime;
    using System.ServiceModel;
    using System.Xml;
    using DiagnosticUtility = System.ServiceModel.DiagnosticUtility;

    public abstract class StreamBodyWriter : BodyWriter
    {
        // if isQuirkedTo40Behavior = true, does not try to write out <Binary> tags 
        //   this maintains compatibility for 4.0 implementers of a derived StreamBodyWriter if they 
        //   depended on behaviour where StreamBodyWriter isn't ByteStreamEncoder aware. 
        //   e.g., if they wrote their own <Binary> tags and relied on StreamBodyWriter to only write out the body. 
        //
        // if isQuirkedTo40Behavior = false, XmlWriterBackedStream will write out <Binary> tags (default in 4.5)
        readonly bool isQuirkedTo40Behavior;

        // externally accessible constructor quirked: 
        // if version <  4.5, XmlWriterBackedStream does not try to write out <Binary> tags
        // if version >= 4.5, XmlWriterBackedStream will write out <Binary> tags
        protected StreamBodyWriter(bool isBuffered)
            : this(isBuffered, !OSEnvironmentHelper.IsApplicationTargeting45)
        { }

        // internally accessible constructor allows derived types to determine whether StreamBodyWriter should be ByteStream aware
        // internal implementations SHOULD use isQuirkedTo40Behavior = false. 
        internal StreamBodyWriter(bool isBuffered, bool isQuirkedTo40Behavior)
            : base(isBuffered)
        {
            this.isQuirkedTo40Behavior = isQuirkedTo40Behavior;  
        }

        internal static StreamBodyWriter CreateStreamBodyWriter(Action<Stream> streamAction)
        {
            if (streamAction == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("actionOfStream");
            }
            return new ActionOfStreamBodyWriter(streamAction);
        }

        protected abstract void OnWriteBodyContents(Stream stream);

        protected override BodyWriter OnCreateBufferedCopy(int maxBufferSize)
        {
            using (BufferManagerOutputStream bufferedStream = new BufferManagerOutputStream(SR2.MaxReceivedMessageSizeExceeded, maxBufferSize))
            {
                this.OnWriteBodyContents(bufferedStream);
                int size;
                byte[] bytesArray = bufferedStream.ToArray(out size);
                return new BufferedBytesStreamBodyWriter(bytesArray, size);
            }
        }

        protected override void OnWriteBodyContents(XmlDictionaryWriter writer)
        {
            using (XmlWriterBackedStream stream = new XmlWriterBackedStream(writer, this.isQuirkedTo40Behavior))
            {
                OnWriteBodyContents(stream);
            }
        }

        class XmlWriterBackedStream : Stream
        {
            private const string StreamElementName = "Binary";
            private readonly bool isQuirkedTo40Behavior; 

            XmlWriter writer;

            public XmlWriterBackedStream(XmlWriter writer, bool isQuirkedTo40Behavior)
            {
                if (writer == null)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
                }
                this.writer = writer;

                this.isQuirkedTo40Behavior = isQuirkedTo40Behavior;
            }

            public override bool CanRead
            {
                get { return false; }
            }

            public override bool CanSeek
            {
                get { return false; }
            }

            public override bool CanWrite
            {
                get { return true; }
            }

            public override void Flush()
            {
                this.writer.Flush();
            }

            public override long Length
            {
                get
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamPropertyGetNotSupported, "Length")));
                }
            }

            public override long Position
            {
                get
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamPropertyGetNotSupported, "Position")));
                }
                set
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamPropertySetNotSupported, "Position")));
                }
            }

            public override int Read(byte[] buffer, int offset, int count)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamMethodNotSupported, "Read")));
            }

            public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamMethodNotSupported, "BeginRead")));
            }

            public override int EndRead(IAsyncResult asyncResult)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamMethodNotSupported, "EndRead")));
            }

            public override int ReadByte()
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamMethodNotSupported, "ReadByte")));
            }

            public override long Seek(long offset, SeekOrigin origin)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamMethodNotSupported, "Seek")));
            }

            public override void SetLength(long value)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperWarning(new InvalidOperationException(SR2.GetString(SR2.XmlWriterBackedStreamMethodNotSupported, "SetLength")));
            }

            public override void Write(byte[] buffer, int offset, int count)
            {
                if (writer.WriteState == WriteState.Content || this.isQuirkedTo40Behavior)
                {
                    // if isQuirkedTo40Behavior == true, maintains compatibility for 4.0 implementers of a derived StreamBodyWriter 
                    // if they depended on behaviour without state checks, e.g., if they wrote their own <Binary> tags 
                    this.writer.WriteBase64(buffer, offset, count);
                }
                else if (writer.WriteState == WriteState.Start)
                {
                    writer.WriteStartElement(StreamElementName, string.Empty);
                    this.writer.WriteBase64(buffer, offset, count);
                }
            }
        }

        class BufferedBytesStreamBodyWriter : StreamBodyWriter
        {
            byte[] array;
            int size;

            public BufferedBytesStreamBodyWriter(byte[] array, int size)
                : base(true, false)
            {
                this.array = array;
                this.size = size;
            }

            protected override void OnWriteBodyContents(Stream stream)
            {
                stream.Write(this.array, 0, this.size);
            }
        }

        class ActionOfStreamBodyWriter : StreamBodyWriter
        {
            Action<Stream> actionOfStream;

            public ActionOfStreamBodyWriter(Action<Stream> actionOfStream)
                : base(false, false)
            {
                this.actionOfStream = actionOfStream;
            }

            protected override void OnWriteBodyContents(Stream stream)
            {
                actionOfStream(stream);
            }
        }
    }
}