Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Xml / System / Xml / Core / ReadContentAsBinaryHelper.cs / 1305376 / ReadContentAsBinaryHelper.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
using System.Diagnostics;
namespace System.Xml
{
internal class ReadContentAsBinaryHelper {
// Private enums
enum State {
None,
InReadContent,
InReadElementContent,
}
// Fields
XmlReader reader;
State state;
int valueOffset;
bool isEnd;
bool canReadValueChunk;
char[] valueChunk;
int valueChunkLength;
IncrementalReadDecoder decoder;
Base64Decoder base64Decoder;
BinHexDecoder binHexDecoder;
// Constants
const int ChunkSize = 256;
// Constructor
internal ReadContentAsBinaryHelper( XmlReader reader ) {
this.reader = reader;
this.canReadValueChunk = reader.CanReadValueChunk;
if ( canReadValueChunk ) {
valueChunk = new char[ChunkSize];
}
}
// Static methods
internal static ReadContentAsBinaryHelper CreateOrReset( ReadContentAsBinaryHelper helper, XmlReader reader ) {
if ( helper == null ) {
return new ReadContentAsBinaryHelper( reader );
}
else {
helper.Reset();
return helper;
}
}
// Internal methods
internal int ReadContentAsBase64( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( !reader.CanReadContentAs() ) {
throw reader.CreateReadContentAsException( "ReadContentAsBase64" );
}
if ( !Init() ) {
return 0;
}
break;
case State.InReadContent:
// if we have a correct decoder, go read
if ( decoder == base64Decoder ) {
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
break;
case State.InReadElementContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadContent );
// setup base64 decoder
InitBase64Decoder();
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
internal int ReadContentAsBinHex( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( !reader.CanReadContentAs() ) {
throw reader.CreateReadContentAsException( "ReadContentAsBinHex" );
}
if ( !Init() ) {
return 0;
}
break;
case State.InReadContent:
// if we have a correct decoder, go read
if ( decoder == binHexDecoder ) {
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
break;
case State.InReadElementContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadContent );
// setup binhex decoder
InitBinHexDecoder();
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
internal int ReadElementContentAsBase64( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( reader.NodeType != XmlNodeType.Element ) {
throw reader.CreateReadElementContentAsException( "ReadElementContentAsBase64" );
}
if ( !InitOnElement() ) {
return 0;
}
break;
case State.InReadContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
case State.InReadElementContent:
// if we have a correct decoder, go read
if ( decoder == base64Decoder ) {
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
break;
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadElementContent );
// setup base64 decoder
InitBase64Decoder();
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
internal int ReadElementContentAsBinHex( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( reader.NodeType != XmlNodeType.Element ) {
throw reader.CreateReadElementContentAsException( "ReadElementContentAsBinHex" );
}
if ( !InitOnElement() ) {
return 0;
}
break;
case State.InReadContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
case State.InReadElementContent:
// if we have a correct decoder, go read
if ( decoder == binHexDecoder ) {
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
break;
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadElementContent );
// setup binhex decoder
InitBinHexDecoder();
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
internal void Finish() {
if ( state != State.None ) {
while ( MoveToNextContentNode( true ) )
;
if ( state == State.InReadElementContent ) {
if ( reader.NodeType != XmlNodeType.EndElement ) {
throw new XmlException( Res.Xml_InvalidNodeType, reader.NodeType.ToString(), reader as IXmlLineInfo );
}
// move off the EndElement
reader.Read();
}
}
Reset();
}
internal void Reset() {
state = State.None;
isEnd = false;
valueOffset = 0;
}
// Private methods
private bool Init() {
// make sure we are on a content node
if ( !MoveToNextContentNode( false ) ) {
return false;
}
state = State.InReadContent;
isEnd = false;
return true;
}
private bool InitOnElement() {
Debug.Assert( reader.NodeType == XmlNodeType.Element );
bool isEmpty = reader.IsEmptyElement;
// move to content or off the empty element
reader.Read();
if ( isEmpty ) {
return false;
}
// make sure we are on a content node
if ( !MoveToNextContentNode( false ) ) {
if ( reader.NodeType != XmlNodeType.EndElement ) {
throw new XmlException( Res.Xml_InvalidNodeType, reader.NodeType.ToString(), reader as IXmlLineInfo );
}
// move off end element
reader.Read();
return false;
}
state = State.InReadElementContent;
isEnd = false;
return true;
}
private void InitBase64Decoder() {
if ( base64Decoder == null ) {
base64Decoder = new Base64Decoder();
}
else {
base64Decoder.Reset();
}
decoder = base64Decoder;
}
private void InitBinHexDecoder() {
if ( binHexDecoder == null ) {
binHexDecoder = new BinHexDecoder();
}
else {
binHexDecoder.Reset();
}
decoder = binHexDecoder;
}
private int ReadContentAsBinary( byte[] buffer, int index, int count ) {
Debug.Assert( decoder != null );
if ( isEnd ) {
Reset();
return 0;
}
decoder.SetNextOutputBuffer( buffer, index, count );
for (;;) {
// use streaming ReadValueChunk if the reader supports it
if ( canReadValueChunk ) {
for (;;) {
if ( valueOffset < valueChunkLength ) {
int decodedCharsCount = decoder.Decode( valueChunk, valueOffset, valueChunkLength - valueOffset );
valueOffset += decodedCharsCount;
}
if ( decoder.IsFull ) {
return decoder.DecodedCount;
}
Debug.Assert( valueOffset == valueChunkLength );
if ( ( valueChunkLength = reader.ReadValueChunk( valueChunk, 0, ChunkSize ) ) == 0 ) {
break;
}
valueOffset = 0;
}
}
else {
// read what is reader.Value
string value = reader.Value;
int decodedCharsCount = decoder.Decode( value, valueOffset, value.Length - valueOffset );
valueOffset += decodedCharsCount;
if ( decoder.IsFull ) {
return decoder.DecodedCount;
}
}
valueOffset = 0;
// move to next textual node in the element content; throw on sub elements
if ( !MoveToNextContentNode( true ) ) {
isEnd = true;
return decoder.DecodedCount;
}
}
}
private int ReadElementContentAsBinary( byte[] buffer, int index, int count ) {
if ( count == 0 ) {
return 0;
}
// read binary
int decoded = ReadContentAsBinary( buffer, index, count );
if ( decoded > 0 ) {
return decoded;
}
// if 0 bytes returned check if we are on a closing EndElement, throw exception if not
if ( reader.NodeType != XmlNodeType.EndElement ) {
throw new XmlException( Res.Xml_InvalidNodeType, reader.NodeType.ToString(), reader as IXmlLineInfo );
}
// move off the EndElement
reader.Read();
state = State.None;
return 0;
}
bool MoveToNextContentNode( bool moveIfOnContentNode ) {
do {
switch ( reader.NodeType ) {
case XmlNodeType.Attribute:
return !moveIfOnContentNode;
case XmlNodeType.Text:
case XmlNodeType.Whitespace:
case XmlNodeType.SignificantWhitespace:
case XmlNodeType.CDATA:
if ( !moveIfOnContentNode ) {
return true;
}
break;
case XmlNodeType.ProcessingInstruction:
case XmlNodeType.Comment:
case XmlNodeType.EndEntity:
// skip comments, pis and end entity nodes
break;
case XmlNodeType.EntityReference:
if ( reader.CanResolveEntity ) {
reader.ResolveEntity();
break;
}
goto default;
default:
return false;
}
moveIfOnContentNode = false;
} while ( reader.Read() );
return false;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
using System.Diagnostics;
namespace System.Xml
{
internal class ReadContentAsBinaryHelper {
// Private enums
enum State {
None,
InReadContent,
InReadElementContent,
}
// Fields
XmlReader reader;
State state;
int valueOffset;
bool isEnd;
bool canReadValueChunk;
char[] valueChunk;
int valueChunkLength;
IncrementalReadDecoder decoder;
Base64Decoder base64Decoder;
BinHexDecoder binHexDecoder;
// Constants
const int ChunkSize = 256;
// Constructor
internal ReadContentAsBinaryHelper( XmlReader reader ) {
this.reader = reader;
this.canReadValueChunk = reader.CanReadValueChunk;
if ( canReadValueChunk ) {
valueChunk = new char[ChunkSize];
}
}
// Static methods
internal static ReadContentAsBinaryHelper CreateOrReset( ReadContentAsBinaryHelper helper, XmlReader reader ) {
if ( helper == null ) {
return new ReadContentAsBinaryHelper( reader );
}
else {
helper.Reset();
return helper;
}
}
// Internal methods
internal int ReadContentAsBase64( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( !reader.CanReadContentAs() ) {
throw reader.CreateReadContentAsException( "ReadContentAsBase64" );
}
if ( !Init() ) {
return 0;
}
break;
case State.InReadContent:
// if we have a correct decoder, go read
if ( decoder == base64Decoder ) {
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
break;
case State.InReadElementContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadContent );
// setup base64 decoder
InitBase64Decoder();
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
internal int ReadContentAsBinHex( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( !reader.CanReadContentAs() ) {
throw reader.CreateReadContentAsException( "ReadContentAsBinHex" );
}
if ( !Init() ) {
return 0;
}
break;
case State.InReadContent:
// if we have a correct decoder, go read
if ( decoder == binHexDecoder ) {
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
break;
case State.InReadElementContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadContent );
// setup binhex decoder
InitBinHexDecoder();
// read more binary data
return ReadContentAsBinary( buffer, index, count );
}
internal int ReadElementContentAsBase64( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( reader.NodeType != XmlNodeType.Element ) {
throw reader.CreateReadElementContentAsException( "ReadElementContentAsBase64" );
}
if ( !InitOnElement() ) {
return 0;
}
break;
case State.InReadContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
case State.InReadElementContent:
// if we have a correct decoder, go read
if ( decoder == base64Decoder ) {
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
break;
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadElementContent );
// setup base64 decoder
InitBase64Decoder();
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
internal int ReadElementContentAsBinHex( byte[] buffer, int index, int count ) {
// check arguments
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( buffer.Length - index < count ) {
throw new ArgumentOutOfRangeException( "count" );
}
switch ( state ) {
case State.None:
if ( reader.NodeType != XmlNodeType.Element ) {
throw reader.CreateReadElementContentAsException( "ReadElementContentAsBinHex" );
}
if ( !InitOnElement() ) {
return 0;
}
break;
case State.InReadContent:
throw new InvalidOperationException( Res.GetString( Res.Xml_MixingBinaryContentMethods ) );
case State.InReadElementContent:
// if we have a correct decoder, go read
if ( decoder == binHexDecoder ) {
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
break;
default:
Debug.Assert( false );
return 0;
}
Debug.Assert( state == State.InReadElementContent );
// setup binhex decoder
InitBinHexDecoder();
// read more binary data
return ReadElementContentAsBinary( buffer, index, count );
}
internal void Finish() {
if ( state != State.None ) {
while ( MoveToNextContentNode( true ) )
;
if ( state == State.InReadElementContent ) {
if ( reader.NodeType != XmlNodeType.EndElement ) {
throw new XmlException( Res.Xml_InvalidNodeType, reader.NodeType.ToString(), reader as IXmlLineInfo );
}
// move off the EndElement
reader.Read();
}
}
Reset();
}
internal void Reset() {
state = State.None;
isEnd = false;
valueOffset = 0;
}
// Private methods
private bool Init() {
// make sure we are on a content node
if ( !MoveToNextContentNode( false ) ) {
return false;
}
state = State.InReadContent;
isEnd = false;
return true;
}
private bool InitOnElement() {
Debug.Assert( reader.NodeType == XmlNodeType.Element );
bool isEmpty = reader.IsEmptyElement;
// move to content or off the empty element
reader.Read();
if ( isEmpty ) {
return false;
}
// make sure we are on a content node
if ( !MoveToNextContentNode( false ) ) {
if ( reader.NodeType != XmlNodeType.EndElement ) {
throw new XmlException( Res.Xml_InvalidNodeType, reader.NodeType.ToString(), reader as IXmlLineInfo );
}
// move off end element
reader.Read();
return false;
}
state = State.InReadElementContent;
isEnd = false;
return true;
}
private void InitBase64Decoder() {
if ( base64Decoder == null ) {
base64Decoder = new Base64Decoder();
}
else {
base64Decoder.Reset();
}
decoder = base64Decoder;
}
private void InitBinHexDecoder() {
if ( binHexDecoder == null ) {
binHexDecoder = new BinHexDecoder();
}
else {
binHexDecoder.Reset();
}
decoder = binHexDecoder;
}
private int ReadContentAsBinary( byte[] buffer, int index, int count ) {
Debug.Assert( decoder != null );
if ( isEnd ) {
Reset();
return 0;
}
decoder.SetNextOutputBuffer( buffer, index, count );
for (;;) {
// use streaming ReadValueChunk if the reader supports it
if ( canReadValueChunk ) {
for (;;) {
if ( valueOffset < valueChunkLength ) {
int decodedCharsCount = decoder.Decode( valueChunk, valueOffset, valueChunkLength - valueOffset );
valueOffset += decodedCharsCount;
}
if ( decoder.IsFull ) {
return decoder.DecodedCount;
}
Debug.Assert( valueOffset == valueChunkLength );
if ( ( valueChunkLength = reader.ReadValueChunk( valueChunk, 0, ChunkSize ) ) == 0 ) {
break;
}
valueOffset = 0;
}
}
else {
// read what is reader.Value
string value = reader.Value;
int decodedCharsCount = decoder.Decode( value, valueOffset, value.Length - valueOffset );
valueOffset += decodedCharsCount;
if ( decoder.IsFull ) {
return decoder.DecodedCount;
}
}
valueOffset = 0;
// move to next textual node in the element content; throw on sub elements
if ( !MoveToNextContentNode( true ) ) {
isEnd = true;
return decoder.DecodedCount;
}
}
}
private int ReadElementContentAsBinary( byte[] buffer, int index, int count ) {
if ( count == 0 ) {
return 0;
}
// read binary
int decoded = ReadContentAsBinary( buffer, index, count );
if ( decoded > 0 ) {
return decoded;
}
// if 0 bytes returned check if we are on a closing EndElement, throw exception if not
if ( reader.NodeType != XmlNodeType.EndElement ) {
throw new XmlException( Res.Xml_InvalidNodeType, reader.NodeType.ToString(), reader as IXmlLineInfo );
}
// move off the EndElement
reader.Read();
state = State.None;
return 0;
}
bool MoveToNextContentNode( bool moveIfOnContentNode ) {
do {
switch ( reader.NodeType ) {
case XmlNodeType.Attribute:
return !moveIfOnContentNode;
case XmlNodeType.Text:
case XmlNodeType.Whitespace:
case XmlNodeType.SignificantWhitespace:
case XmlNodeType.CDATA:
if ( !moveIfOnContentNode ) {
return true;
}
break;
case XmlNodeType.ProcessingInstruction:
case XmlNodeType.Comment:
case XmlNodeType.EndEntity:
// skip comments, pis and end entity nodes
break;
case XmlNodeType.EntityReference:
if ( reader.CanResolveEntity ) {
reader.ResolveEntity();
break;
}
goto default;
default:
return false;
}
moveIfOnContentNode = false;
} while ( reader.Read() );
return false;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PageThemeBuildProvider.cs
- updatecommandorderer.cs
- EventLogPermissionAttribute.cs
- MissingMethodException.cs
- SkewTransform.cs
- BufferedOutputStream.cs
- AsymmetricSignatureDeformatter.cs
- cache.cs
- HwndProxyElementProvider.cs
- DataShape.cs
- CodeLinePragma.cs
- SoapMessage.cs
- StoreItemCollection.cs
- FloatUtil.cs
- ProcessModule.cs
- NameValueConfigurationCollection.cs
- SHA256.cs
- FixedBufferAttribute.cs
- ClaimTypeElementCollection.cs
- TemplateBuilder.cs
- TextRenderer.cs
- DelegatedStream.cs
- SessionSymmetricMessageSecurityProtocolFactory.cs
- XmlBinaryWriterSession.cs
- TextBox.cs
- DeclarativeCatalogPart.cs
- LateBoundBitmapDecoder.cs
- ImageUrlEditor.cs
- HtmlTableCell.cs
- Application.cs
- RegistrySecurity.cs
- HostElement.cs
- EntitySqlException.cs
- SafeNativeMethods.cs
- NameValuePair.cs
- ToolStripPanelRow.cs
- UInt32Storage.cs
- DataMemberConverter.cs
- GetLedgerRequest.cs
- HtmlForm.cs
- KeyTime.cs
- VBIdentifierName.cs
- CompilerError.cs
- SchemaEntity.cs
- HtmlInputButton.cs
- KeyPressEvent.cs
- ValidationResult.cs
- COM2ICategorizePropertiesHandler.cs
- SqlConnectionFactory.cs
- TableLayoutPanel.cs
- Vector.cs
- BitmapPalette.cs
- XmlWriterTraceListener.cs
- PlanCompilerUtil.cs
- NativeMethods.cs
- DebuggerAttributes.cs
- ConstraintStruct.cs
- WindowsListViewSubItem.cs
- MouseWheelEventArgs.cs
- SerializableAttribute.cs
- SafeArchiveContext.cs
- HealthMonitoringSectionHelper.cs
- ContentFileHelper.cs
- DragStartedEventArgs.cs
- DispatcherHookEventArgs.cs
- Misc.cs
- VirtualPathData.cs
- SqlClientWrapperSmiStream.cs
- CellParagraph.cs
- XPathNodeList.cs
- TextProperties.cs
- Scene3D.cs
- FileEnumerator.cs
- ChangeNode.cs
- UrlAuthFailedErrorFormatter.cs
- FormatException.cs
- TextServicesManager.cs
- SecurityTokenResolver.cs
- WebServicesDescriptionAttribute.cs
- ShimAsPublicXamlType.cs
- ContentPropertyAttribute.cs
- Assert.cs
- SqlWriter.cs
- ValidationErrorInfo.cs
- ContextMenu.cs
- ObjectViewQueryResultData.cs
- SerializationFieldInfo.cs
- TrackingRecordPreFilter.cs
- TextEditorMouse.cs
- cryptoapiTransform.cs
- XmlUtil.cs
- ProxyOperationRuntime.cs
- ScrollableControl.cs
- TrackBarRenderer.cs
- DelegatingTypeDescriptionProvider.cs
- EffectiveValueEntry.cs
- ProfileParameter.cs
- ObjectStateManagerMetadata.cs
- StorageBasedPackageProperties.cs
- Vector3DCollectionConverter.cs