| File: FrameworkFork\System.ServiceModel\System\ServiceModel\XmlBuffer.cs | Web Access |
| Project: src\src\dotnet-svcutil\lib\src\dotnet-svcutil-lib.csproj (dotnet-svcutil-lib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Collections.Generic; using System.Runtime; using System.ServiceModel.Channels; using Microsoft.Xml; namespace System.ServiceModel { internal class XmlBuffer { private List<Section> _sections; private byte[] _buffer; private int _offset; private BufferedOutputStream _stream; private BufferState _bufferState; private XmlDictionaryWriter _writer; private XmlDictionaryReaderQuotas _quotas; private enum BufferState { Created, Writing, Reading, } internal struct Section { private int _offset; private int _size; private XmlDictionaryReaderQuotas _quotas; public Section(int offset, int size, XmlDictionaryReaderQuotas quotas) { _offset = offset; _size = size; _quotas = quotas; } public int Offset { get { return _offset; } } public int Size { get { return _size; } } public XmlDictionaryReaderQuotas Quotas { get { return _quotas; } } } public XmlBuffer(int maxBufferSize) { if (maxBufferSize < 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferSize", maxBufferSize, SRServiceModel.ValueMustBeNonNegative)); int initialBufferSize = Math.Min(512, maxBufferSize); _stream = new BufferManagerOutputStream(SRServiceModel.XmlBufferQuotaExceeded, initialBufferSize, maxBufferSize, BufferManager.CreateBufferManager(0, int.MaxValue)); _sections = new List<Section>(1); } public int BufferSize { get { Fx.Assert(_bufferState == BufferState.Reading, "Buffer size shuold only be retrieved during Reading state"); return _buffer.Length; } } public int SectionCount { get { return _sections.Count; } } public XmlDictionaryWriter OpenSection(XmlDictionaryReaderQuotas quotas) { if (_bufferState != BufferState.Created) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException()); _bufferState = BufferState.Writing; _quotas = new XmlDictionaryReaderQuotas(); quotas.CopyTo(_quotas); if (_writer != null) { // We always want to Dispose of the writer now; previously, writers could be reassigned // to a new stream, with a new dictionary and session. var thisWriter = _writer; thisWriter.Dispose(); _writer = null; } _writer = XmlDictionaryWriter.CreateBinaryWriter(_stream, XD.Dictionary, null, true); return _writer; } public void CloseSection() { if (_bufferState != BufferState.Writing) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException()); _writer.Dispose(); _writer = null; _bufferState = BufferState.Created; int size = (int)_stream.Length - _offset; _sections.Add(new Section(_offset, size, _quotas)); _offset += size; } public void Close() { if (_bufferState != BufferState.Created) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException()); _bufferState = BufferState.Reading; int bufferSize; _buffer = _stream.ToArray(out bufferSize); _writer = null; _stream = null; } private Exception CreateInvalidStateException() { return new InvalidOperationException(SRServiceModel.XmlBufferInInvalidState); } public XmlDictionaryReader GetReader(int sectionIndex) { if (_bufferState != BufferState.Reading) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException()); Section section = _sections[sectionIndex]; XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(_buffer, section.Offset, section.Size, XD.Dictionary, section.Quotas); reader.MoveToContent(); return reader; } public void WriteTo(int sectionIndex, XmlWriter writer) { if (_bufferState != BufferState.Reading) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException()); XmlDictionaryReader reader = GetReader(sectionIndex); try { writer.WriteNode(reader, false); } finally { reader.Dispose(); } } } }