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
|
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
#define BINARY
namespace System.ServiceModel
{
using System.Collections.Generic;
using System.Runtime;
using System.ServiceModel.Channels;
using System.Xml;
class XmlBuffer
{
List<Section> sections;
byte[] buffer;
int offset;
BufferedOutputStream stream;
BufferState bufferState;
XmlDictionaryWriter writer;
XmlDictionaryReaderQuotas quotas;
enum BufferState
{
Created,
Writing,
Reading,
}
struct Section
{
int offset;
int size;
XmlDictionaryReaderQuotas quotas;
public Section(int offset, int size, XmlDictionaryReaderQuotas quotas)
{
this.offset = offset;
this.size = size;
this.quotas = quotas;
}
public int Offset
{
get { return this.offset; }
}
public int Size
{
get { return this.size; }
}
public XmlDictionaryReaderQuotas Quotas
{
get { return this.quotas; }
}
}
public XmlBuffer(int maxBufferSize)
{
if (maxBufferSize < 0)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("maxBufferSize", maxBufferSize,
SR.GetString(SR.ValueMustBeNonNegative)));
int initialBufferSize = Math.Min(512, maxBufferSize);
stream = new BufferManagerOutputStream(SR.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 this.sections.Count; }
}
public XmlDictionaryWriter OpenSection(XmlDictionaryReaderQuotas quotas)
{
if (bufferState != BufferState.Created)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException());
bufferState = BufferState.Writing;
this.quotas = new XmlDictionaryReaderQuotas();
quotas.CopyTo(this.quotas);
if (this.writer == null)
{
this.writer = XmlDictionaryWriter.CreateBinaryWriter(stream, XD.Dictionary, null, true);
}
else
{
((IXmlBinaryWriterInitializer)this.writer).SetOutput(stream, XD.Dictionary, null, true);
}
return this.writer;
}
public void CloseSection()
{
if (bufferState != BufferState.Writing)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(CreateInvalidStateException());
this.writer.Close();
bufferState = BufferState.Created;
int size = (int)stream.Length - offset;
sections.Add(new Section(offset, size, this.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;
}
Exception CreateInvalidStateException()
{
return new InvalidOperationException(SR.GetString(SR.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, null, null);
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.Close();
}
}
}
}
|