Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / 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 ) { // 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 ) { // 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 ) { // 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 ) { // 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 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.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- CapabilitiesPattern.cs
- XmlCompatibilityReader.cs
- ListBindingHelper.cs
- BitmapPalette.cs
- VirtualPathUtility.cs
- InheritanceService.cs
- UdpDiscoveryEndpointElement.cs
- TemplateContainer.cs
- Rect.cs
- AssemblyLoader.cs
- MemberPath.cs
- FindCriteria11.cs
- FormViewUpdatedEventArgs.cs
- HttpProfileBase.cs
- BaseCodeDomTreeGenerator.cs
- DecimalAnimationUsingKeyFrames.cs
- ClientUrlResolverWrapper.cs
- XslCompiledTransform.cs
- PageSettings.cs
- CapabilitiesSection.cs
- SequentialOutput.cs
- MappingItemCollection.cs
- TextDecorationLocationValidation.cs
- ParentUndoUnit.cs
- SemanticValue.cs
- PointF.cs
- ToolStripContentPanel.cs
- X509Extension.cs
- RouteItem.cs
- TempEnvironment.cs
- HighlightComponent.cs
- ConfigurationLocationCollection.cs
- DefaultTextStoreTextComposition.cs
- ModelPropertyDescriptor.cs
- XmlSerializerFormatAttribute.cs
- WebPart.cs
- ExecutionContext.cs
- LockedBorderGlyph.cs
- IMembershipProvider.cs
- BitmapCodecInfoInternal.cs
- PageWrapper.cs
- LogicalExpr.cs
- _HeaderInfoTable.cs
- IPipelineRuntime.cs
- SeparatorAutomationPeer.cs
- HandledMouseEvent.cs
- BinaryObjectInfo.cs
- WinEventWrap.cs
- ConnectionStringsExpressionBuilder.cs
- XPathDocumentIterator.cs
- EntryPointNotFoundException.cs
- ObjectViewQueryResultData.cs
- DataServiceQueryProvider.cs
- ViewGenerator.cs
- WorkBatch.cs
- DiscreteKeyFrames.cs
- SqlDuplicator.cs
- OleDbErrorCollection.cs
- ToolStripItemTextRenderEventArgs.cs
- ReferentialConstraintRoleElement.cs
- TrackingProfile.cs
- ChunkedMemoryStream.cs
- ReturnEventArgs.cs
- DateTimeFormatInfoScanner.cs
- XsltArgumentList.cs
- FontUnit.cs
- activationcontext.cs
- SqlDependencyUtils.cs
- BlockingCollection.cs
- AuthorizationSection.cs
- DataRelation.cs
- DateRangeEvent.cs
- DeriveBytes.cs
- ModelUIElement3D.cs
- BaseAutoFormat.cs
- BitmapEffectGroup.cs
- WeakHashtable.cs
- NamespaceMapping.cs
- IdnMapping.cs
- SqlConnection.cs
- CalendarButton.cs
- TypeConverterHelper.cs
- GridViewUpdatedEventArgs.cs
- VectorCollection.cs
- ChangeNode.cs
- BackStopAuthenticationModule.cs
- BaseDataBoundControl.cs
- PolicyConversionContext.cs
- MenuItem.cs
- FrameworkContentElement.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- ProfileGroupSettings.cs
- CapabilitiesAssignment.cs
- SiteOfOriginPart.cs
- XmlQueryRuntime.cs
- ConfigurationSectionGroupCollection.cs
- DataGridViewUtilities.cs
- HierarchicalDataSourceConverter.cs
- ToolbarAUtomationPeer.cs
- GridProviderWrapper.cs