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
- VisualBrush.cs
- ColorConvertedBitmap.cs
- SqlConnectionPoolProviderInfo.cs
- SqlError.cs
- AspProxy.cs
- WebExceptionStatus.cs
- ToolStripItemEventArgs.cs
- CookieHandler.cs
- JoinSymbol.cs
- XmlResolver.cs
- PolyLineSegment.cs
- Module.cs
- BamlResourceSerializer.cs
- HtmlAnchor.cs
- EntryPointNotFoundException.cs
- XmlILStorageConverter.cs
- DbBuffer.cs
- Socket.cs
- TraceXPathNavigator.cs
- HighContrastHelper.cs
- DefaultAssemblyResolver.cs
- Substitution.cs
- ListSourceHelper.cs
- SynchronizedDispatch.cs
- BasicExpressionVisitor.cs
- BitVector32.cs
- MatrixCamera.cs
- CmsUtils.cs
- ActivityAction.cs
- httpapplicationstate.cs
- ScriptHandlerFactory.cs
- ZipIOExtraFieldPaddingElement.cs
- MobileControlPersister.cs
- SQLByte.cs
- DataGridViewCellStyle.cs
- Drawing.cs
- TransactedBatchingElement.cs
- DataGridViewRowErrorTextNeededEventArgs.cs
- MessageSmuggler.cs
- Trigger.cs
- Rect3DValueSerializer.cs
- CommentAction.cs
- _CacheStreams.cs
- SqlCommandSet.cs
- PropertyStore.cs
- DataControlFieldCell.cs
- SqlDataSource.cs
- DependencyObjectType.cs
- ServerValidateEventArgs.cs
- SettingsProviderCollection.cs
- AdPostCacheSubstitution.cs
- ResXResourceSet.cs
- Border.cs
- EventSetter.cs
- QilChoice.cs
- UidManager.cs
- WebConfigurationFileMap.cs
- ResourceReferenceExpression.cs
- SqlDataRecord.cs
- BinaryCommonClasses.cs
- Scheduler.cs
- XmlHierarchyData.cs
- ListInitExpression.cs
- XmlTextReaderImpl.cs
- ControlCollection.cs
- SystemIPInterfaceStatistics.cs
- CodeLabeledStatement.cs
- CompositeCollectionView.cs
- NotifyParentPropertyAttribute.cs
- SubpageParagraph.cs
- Message.cs
- MenuAdapter.cs
- MessageSecurityVersion.cs
- NotificationContext.cs
- ConfigXmlComment.cs
- NotificationContext.cs
- Point3DConverter.cs
- CompensationExtension.cs
- NavigationProperty.cs
- TailPinnedEventArgs.cs
- ProcessProtocolHandler.cs
- FileNotFoundException.cs
- RuntimeEnvironment.cs
- OleAutBinder.cs
- SchemaNamespaceManager.cs
- TextEffectResolver.cs
- RewritingProcessor.cs
- CapabilitiesSection.cs
- ConfigurationSectionGroupCollection.cs
- DrawingImage.cs
- OwnerDrawPropertyBag.cs
- StringArrayConverter.cs
- ShaperBuffers.cs
- TextAutomationPeer.cs
- EventMappingSettings.cs
- XmlSchemaException.cs
- JoinTreeNode.cs
- SystemInfo.cs
- _SslState.cs
- DesignerActionUIStateChangeEventArgs.cs