Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Xml / System / Xml / Core / ReadContentAsBinaryHelper.cs / 1 / 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
- DbProviderSpecificTypePropertyAttribute.cs
- ActiveDocumentEvent.cs
- ObjectSecurity.cs
- LicenseProviderAttribute.cs
- AlternateViewCollection.cs
- ComponentChangingEvent.cs
- PropertyFilterAttribute.cs
- RangeBaseAutomationPeer.cs
- sqlser.cs
- WebHeaderCollection.cs
- GeneralTransform3DGroup.cs
- ColumnHeader.cs
- ReturnType.cs
- SwitchExpression.cs
- LineInfo.cs
- ProcessManager.cs
- WebPartTransformer.cs
- Symbol.cs
- DataPager.cs
- TransformProviderWrapper.cs
- ObjectListGeneralPage.cs
- ScopedKnownTypes.cs
- HighlightOverlayGlyph.cs
- PointIndependentAnimationStorage.cs
- BamlBinaryReader.cs
- ExpressionBindings.cs
- DuplicateWaitObjectException.cs
- PropertyKey.cs
- QueryStringHandler.cs
- DocumentViewerConstants.cs
- CodeIdentifier.cs
- SqlEnums.cs
- WebPartCatalogCloseVerb.cs
- KerberosRequestorSecurityToken.cs
- FigureHelper.cs
- DataExpression.cs
- WebException.cs
- _AcceptOverlappedAsyncResult.cs
- _Win32.cs
- DesignerSerializerAttribute.cs
- PartialCachingAttribute.cs
- SQlBooleanStorage.cs
- AppSettingsExpressionBuilder.cs
- UdpTransportSettings.cs
- NamedObjectList.cs
- HttpCapabilitiesSectionHandler.cs
- ICspAsymmetricAlgorithm.cs
- SQLDouble.cs
- CacheChildrenQuery.cs
- PowerEase.cs
- ImageCreator.cs
- SqlCacheDependencyDatabase.cs
- KeyboardNavigation.cs
- OpCellTreeNode.cs
- MachineKeyConverter.cs
- PointCollection.cs
- CrossAppDomainChannel.cs
- SamlAction.cs
- ViewKeyConstraint.cs
- WebMessageBodyStyleHelper.cs
- IntMinMaxAggregationOperator.cs
- DetailsViewRowCollection.cs
- HtmlInputText.cs
- XmlDesignerDataSourceView.cs
- DataGridItemCollection.cs
- CompilerScope.Storage.cs
- MasterPageCodeDomTreeGenerator.cs
- ResourceProperty.cs
- ReadOnlyDictionary.cs
- SchemaNotation.cs
- Int32Rect.cs
- DefaultDialogButtons.cs
- Models.cs
- LineBreak.cs
- BitmapEffectInputConnector.cs
- ToolboxDataAttribute.cs
- InlinedAggregationOperator.cs
- HtmlEmptyTagControlBuilder.cs
- BindingContext.cs
- DataSourceSelectArguments.cs
- FormatVersion.cs
- JpegBitmapDecoder.cs
- WorkflowInstanceExtensionCollection.cs
- WebPartsSection.cs
- PropertyRecord.cs
- HtmlEmptyTagControlBuilder.cs
- Label.cs
- IndicFontClient.cs
- IndexedEnumerable.cs
- COAUTHIDENTITY.cs
- ChannelEndpointElement.cs
- RoleManagerModule.cs
- WebControl.cs
- BinaryParser.cs
- DateTimeFormatInfo.cs
- TextTreeDeleteContentUndoUnit.cs
- ExpressionDumper.cs
- PngBitmapEncoder.cs
- CryptoKeySecurity.cs
- ListBox.cs