Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / fx / src / Xml / System / Xml / Core / XmlTextEncoder.cs / 1 / XmlTextEncoder.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// [....]
//-----------------------------------------------------------------------------
using System;
using System.IO;
using System.Diagnostics;
using System.Globalization;
namespace System.Xml {
// XmlTextEncoder
//
// This class does special handling of text content for XML. For example
// it will replace special characters with entities whenever necessary.
internal class XmlTextEncoder {
//
// Fields
//
// output text writer
TextWriter textWriter;
// true when writing out the content of attribute value
bool inAttribute;
// quote char of the attribute (when inAttribute)
char quoteChar;
// caching of attribute value
BufferBuilder attrValue;
bool cacheAttrValue;
// XmlCharType
XmlCharType xmlCharType;
//
// Constants
//
const int SurHighStart = 0xd800;
const int SurHighEnd = 0xdbff;
const int SurLowStart = 0xdc00;
const int SurLowEnd = 0xdfff;
//
// Constructor
//
internal XmlTextEncoder( TextWriter textWriter ) {
this.textWriter = textWriter;
this.quoteChar = '"';
this.xmlCharType = XmlCharType.Instance;
}
//
// Internal methods and properties
//
internal char QuoteChar {
set {
this.quoteChar = value;
}
}
internal void StartAttribute( bool cacheAttrValue ) {
this.inAttribute = true;
this.cacheAttrValue = cacheAttrValue;
if ( cacheAttrValue ) {
if ( attrValue == null ) {
attrValue = new BufferBuilder();
}
else {
attrValue.Clear();
}
}
}
internal void EndAttribute() {
if ( cacheAttrValue ) {
attrValue.Clear();
}
this.inAttribute = false;
this.cacheAttrValue = false;
}
internal string AttributeValue {
get {
if ( cacheAttrValue ) {
return attrValue.ToString();
}
else {
return String.Empty;
}
}
}
internal void WriteSurrogateChar( char lowChar, char highChar ) {
if ( ( (int)lowChar < SurLowStart || (int)lowChar > SurLowEnd ) ||
( (int)highChar < SurHighStart || (int)highChar > SurHighEnd ) ) {
throw XmlConvert.CreateInvalidSurrogatePairException( lowChar, highChar );
}
textWriter.Write( highChar );
textWriter.Write( lowChar );
}
internal void Write( char[] array, int offset, int count ) {
if ( null == array ) {
throw new ArgumentNullException("array");
}
if ( 0 > offset ) {
throw new ArgumentOutOfRangeException("offset");
}
if ( 0 > count ) {
throw new ArgumentOutOfRangeException("count");
}
if ( count > array.Length - offset ) {
throw new ArgumentOutOfRangeException("count");
}
if ( cacheAttrValue ) {
attrValue.Append( array, offset, count );
}
int endPos = offset + count;
int i = offset;
char ch = (char)0;
for (;;) {
int startPos = i;
unsafe {
while ( i < endPos && ( xmlCharType.charProperties[ch = array[i]] & XmlCharType.fAttrValue ) != 0 ) { // ( xmlCharType.IsAttributeValueChar( ( ch = array[i] ) ) ) ) {
i++;
}
}
if ( startPos < i ) {
textWriter.Write( array, startPos, i - startPos );
}
if ( i == endPos ) {
break;
}
switch ( ch ) {
case (char)0x9:
textWriter.Write( ch );
break;
case (char)0xA:
case (char)0xD:
if ( inAttribute ) {
WriteCharEntityImpl( ch );
}
else {
textWriter.Write( ch );
}
break;
case '<':
WriteEntityRefImpl( "lt" );
break;
case '>':
WriteEntityRefImpl( "gt" );
break;
case '&':
WriteEntityRefImpl( "amp" );
break;
case '\'':
if ( inAttribute && quoteChar == ch ) {
WriteEntityRefImpl( "apos" );
}
else {
textWriter.Write( '\'' );
}
break;
case '"':
if ( inAttribute && quoteChar == ch ) {
WriteEntityRefImpl( "quot" );
}
else {
textWriter.Write( '"' );
}
break;
default:
if ( (int)ch >= SurHighStart && (int)ch <= SurHighEnd ) {
if ( i + 1 < endPos ) {
WriteSurrogateChar( array[++i], ch );
}
else {
throw new ArgumentException( Res.GetString( Res.Xml_SurrogatePairSplit ) );
}
}
else if ( (int)ch >= SurLowStart && (int)ch <= SurLowEnd ) {
throw XmlConvert.CreateInvalidHighSurrogateCharException( ch );
}
else {
Debug.Assert( ( ch < 0x20 && !xmlCharType.IsWhiteSpace( ch ) ) || ( ch > 0xFFFD ) );
WriteCharEntityImpl( ch );
}
break;
}
i++;
}
}
internal void Write( char ch ) {
if ( cacheAttrValue ) {
attrValue.Append( ch );
}
bool isAttrValue;
unsafe {
isAttrValue = ( xmlCharType.charProperties[ch] & XmlCharType.fAttrValue ) != 0; // xmlCharType.IsAttributeValueChar( ch )
}
if ( isAttrValue ) {
textWriter.Write( ch );
}
else {
switch ( ch ) {
case (char)0x9:
textWriter.Write( ch );
break;
case (char)0xA:
case (char)0xD:
if ( inAttribute ) {
WriteCharEntityImpl( ch );
}
else {
textWriter.Write( ch );
}
break;
case '<':
WriteEntityRefImpl( "lt" );
break;
case '>':
WriteEntityRefImpl( "gt" );
break;
case '&':
WriteEntityRefImpl( "amp" );
break;
case '\'':
if ( inAttribute && quoteChar == ch ) {
WriteEntityRefImpl( "apos" );
}
else {
textWriter.Write( '\'' );
}
break;
case '"':
if ( inAttribute && quoteChar == ch ) {
WriteEntityRefImpl( "quot" );
}
else {
textWriter.Write( '"' );
}
break;
default:
if ( (int)ch >= SurHighStart && (int)ch <= SurHighEnd ) {
throw new ArgumentException( Res.GetString( Res.Xml_InvalidSurrogateMissingLowChar ) );
}
else if ( (int)ch >= SurLowStart && (int)ch <= SurLowEnd ) {
throw XmlConvert.CreateInvalidHighSurrogateCharException( ch );
}
else {
Debug.Assert( ( ch < 0x20 && !xmlCharType.IsWhiteSpace( ch ) ) || ( ch > 0xFFFD ) );
WriteCharEntityImpl( ch );
}
break;
}
}
}
internal void WriteSurrogateCharEntity( char lowChar, char highChar ) {
if ( ( (int)lowChar < SurLowStart || (int)lowChar > SurLowEnd ) ||
( (int)highChar < SurHighStart || (int)highChar > SurHighEnd ) ) {
throw XmlConvert.CreateInvalidSurrogatePairException( lowChar, highChar );
}
int surrogateChar = ( (int)lowChar - SurLowStart ) | ( ( (int)highChar - SurHighStart ) << 10 ) + 0x10000;
if ( cacheAttrValue ) {
attrValue.Append( highChar );
attrValue.Append( lowChar );
}
textWriter.Write( "" );
textWriter.Write( surrogateChar.ToString( "X", NumberFormatInfo.InvariantInfo ) );
textWriter.Write( ';' );
}
internal void Write( string text ) {
if ( text == null ) {
return;
}
if ( cacheAttrValue ) {
attrValue.Append( text );
}
// scan through the string to see if there are any characters to be escaped
int len = text.Length;
int i = 0;
int startPos = 0;
char ch = (char)0;
for (;;) {
unsafe {
while ( i < len && ( xmlCharType.charProperties[ch = text[i]] & XmlCharType.fAttrValue ) != 0 ) { // ( xmlCharType.IsAttributeValueChar( ( ch = text[i] ) ) ) ) {
i++;
}
}
if ( i == len ) {
// reached the end of the string -> write it whole out
textWriter.Write( text );
return;
}
if ( inAttribute ) {
if ( ch == 0x9 ) {
i++;
continue;
}
}
else {
if ( ch == 0x9 || ch == 0xA || ch == 0xD || ch == '"' || ch == '\'' ) {
i++;
continue;
}
}
// some character that needs to be escaped is found:
break;
}
char[] helperBuffer = new char[256];
for (;;) {
if ( startPos < i ) {
WriteStringFragment( text, startPos, i - startPos, helperBuffer );
}
if ( i == len ) {
break;
}
switch ( ch ) {
case (char)0x9:
textWriter.Write( ch );
break;
case (char)0xA:
case (char)0xD:
if ( inAttribute ) {
WriteCharEntityImpl( ch );
}
else {
textWriter.Write( ch );
}
break;
case '<':
WriteEntityRefImpl( "lt" );
break;
case '>':
WriteEntityRefImpl( "gt" );
break;
case '&':
WriteEntityRefImpl( "amp" );
break;
case '\'':
if ( inAttribute && quoteChar == ch ) {
WriteEntityRefImpl( "apos" );
}
else {
textWriter.Write( '\'' );
}
break;
case '"':
if ( inAttribute && quoteChar == ch ) {
WriteEntityRefImpl( "quot" );
}
else {
textWriter.Write( '"' );
}
break;
default:
if ( (int)ch >= SurHighStart && (int)ch <= SurHighEnd ) {
if ( i + 1 < len ) {
WriteSurrogateChar( text[++i], ch );
}
else {
throw XmlConvert.CreateInvalidSurrogatePairException( text[i], ch );
}
}
else if ( (int)ch >= SurLowStart && (int)ch <= SurLowEnd ) {
throw XmlConvert.CreateInvalidHighSurrogateCharException( ch );
}
else {
Debug.Assert( ( ch < 0x20 && !xmlCharType.IsWhiteSpace( ch ) ) || ( ch > 0xFFFD ) );
WriteCharEntityImpl( ch );
}
break;
}
i++;
startPos = i;
unsafe {
while ( i < len && ( xmlCharType.charProperties[ch = text[i]] & XmlCharType.fAttrValue ) != 0 ) { // ( xmlCharType.IsAttributeValueChar( ( text[i] ) ) ) ) {
i++;
}
}
}
}
internal void WriteRawWithSurrogateChecking( string text ) {
if ( text == null ) {
return;
}
if ( cacheAttrValue ) {
attrValue.Append( text );
}
int len = text.Length;
int i = 0;
char ch = (char)0;
for (;;) {
unsafe {
while ( i < len &&
( ( xmlCharType.charProperties[ch = text[i]] & XmlCharType.fCharData ) != 0 // ( xmlCharType.IsCharData( ( ch = text[i] ) )
|| ch < 0x20 ) ) {
i++;
}
}
if ( i == len ) {
break;
}
if ( (int)ch >= SurHighStart && (int)ch <= SurHighEnd ) {
if ( i + 1 < len ) {
char lowChar = text[i+1];
if ( lowChar >= SurLowStart && lowChar <= SurLowEnd ) {
i += 2;
continue;
}
else {
throw XmlConvert.CreateInvalidSurrogatePairException( lowChar, ch );
}
}
throw new ArgumentException( Res.GetString( Res.Xml_InvalidSurrogateMissingLowChar ) );
}
else if ( (int)ch >= SurLowStart && (int)ch <= SurLowEnd ) {
throw XmlConvert.CreateInvalidHighSurrogateCharException( ch );
}
else {
i++;
}
}
textWriter.Write( text );
return;
}
internal void WriteRaw( string value ) {
if ( cacheAttrValue ) {
attrValue.Append( value );
}
textWriter.Write( value );
}
internal void WriteRaw( char[] array, int offset, int count ) {
if ( null == array ) {
throw new ArgumentNullException("array");
}
if ( 0 > count ) {
throw new ArgumentOutOfRangeException("count");
}
if ( 0 > offset ) {
throw new ArgumentOutOfRangeException("offset");
}
if ( count > array.Length - offset ) {
throw new ArgumentOutOfRangeException("count");
}
if ( cacheAttrValue ) {
attrValue.Append( array, offset, count );
}
textWriter.Write( array, offset, count );
}
internal void WriteCharEntity( char ch ) {
if ( (int)ch >= SurHighStart && (int)ch <= SurLowEnd ) {
throw new ArgumentException( Res.GetString( Res.Xml_InvalidSurrogateMissingLowChar ) );
}
string strVal = ((int)ch).ToString( "X", NumberFormatInfo.InvariantInfo );
if ( cacheAttrValue ) {
attrValue.Append( "" );
attrValue.Append( strVal );
attrValue.Append( ';' );
}
WriteCharEntityImpl( strVal );
}
internal void WriteEntityRef( string name ) {
if ( cacheAttrValue ) {
attrValue.Append( '&' );
attrValue.Append( name );
attrValue.Append( ';' );
}
WriteEntityRefImpl( name );
}
internal void Flush() {
//
}
//
// Private implementation methods
//
// This is a helper method to woraround the fact that TextWriter does not have a Write method
// for fragment of a string such as Write( string, offset, count).
// The string fragment will be written out by copying into a small helper buffer and then
// calling textWriter to write out the buffer.
private void WriteStringFragment( string str, int offset, int count, char[] helperBuffer ) {
int bufferSize = helperBuffer.Length;
while ( count > 0 ) {
int copyCount = count;
if ( copyCount > bufferSize ) {
copyCount = bufferSize;
}
str.CopyTo( offset, helperBuffer, 0, copyCount );
textWriter.Write( helperBuffer, 0, copyCount );
offset += copyCount;
count -= copyCount;
}
}
private void WriteCharEntityImpl( char ch ) {
WriteCharEntityImpl( ((int)ch).ToString( "X", NumberFormatInfo.InvariantInfo ) );
}
private void WriteCharEntityImpl( string strVal ) {
textWriter.Write( "" );
textWriter.Write( strVal );
textWriter.Write( ';' );
}
private void WriteEntityRefImpl( string name ) {
textWriter.Write( '&' );
textWriter.Write( name );
textWriter.Write( ';' );
}
}
}
// 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
- XmlSchemaComplexContentExtension.cs
- LayoutUtils.cs
- PointConverter.cs
- ProviderConnectionPointCollection.cs
- TableCellAutomationPeer.cs
- RenderOptions.cs
- SolidColorBrush.cs
- ProxyElement.cs
- RowToFieldTransformer.cs
- CodePageUtils.cs
- SettingsProperty.cs
- SafeEventLogReadHandle.cs
- TextRunTypographyProperties.cs
- DataGridItemCollection.cs
- EventManager.cs
- PageContentAsyncResult.cs
- AuthStoreRoleProvider.cs
- ellipse.cs
- CodeAttachEventStatement.cs
- MemberHolder.cs
- NaturalLanguageHyphenator.cs
- CodeAccessPermission.cs
- ActiveXContainer.cs
- TransportListener.cs
- TableRow.cs
- ControlBuilderAttribute.cs
- _AutoWebProxyScriptHelper.cs
- BezierSegment.cs
- ReceiveMessageAndVerifySecurityAsyncResultBase.cs
- WinInet.cs
- PreProcessor.cs
- CompositeFontFamily.cs
- XPathDocumentIterator.cs
- DataGridClipboardCellContent.cs
- WindowShowOrOpenTracker.cs
- ToolStripItem.cs
- EventManager.cs
- SqlWriter.cs
- IfJoinedCondition.cs
- PathFigure.cs
- TextContainerChangedEventArgs.cs
- Membership.cs
- MetabaseServerConfig.cs
- XmlC14NWriter.cs
- HttpModuleCollection.cs
- Vector3D.cs
- StorageModelBuildProvider.cs
- NativeMethods.cs
- SqlInternalConnectionSmi.cs
- PointAnimationBase.cs
- UpDownEvent.cs
- GenericPrincipal.cs
- TableStyle.cs
- WindowsAuthenticationModule.cs
- LayoutSettings.cs
- Label.cs
- SqlNotificationRequest.cs
- Section.cs
- UriExt.cs
- FileEnumerator.cs
- DocumentGridPage.cs
- UserControlAutomationPeer.cs
- SqlTriggerContext.cs
- ProcessRequestArgs.cs
- ContentControl.cs
- XmlQualifiedName.cs
- StorageAssociationTypeMapping.cs
- XmlResolver.cs
- WCFServiceClientProxyGenerator.cs
- SystemIPInterfaceStatistics.cs
- MetadataArtifactLoaderCompositeFile.cs
- CodeDirectoryCompiler.cs
- ControlValuePropertyAttribute.cs
- ExeContext.cs
- WebException.cs
- SessionEndingEventArgs.cs
- ProtectedConfigurationSection.cs
- XmlSchemaImporter.cs
- AddingNewEventArgs.cs
- MsmqChannelFactory.cs
- XPathScanner.cs
- InvalidOleVariantTypeException.cs
- WorkflowOperationFault.cs
- HeaderedItemsControl.cs
- SmiRequestExecutor.cs
- Attributes.cs
- StagingAreaInputItem.cs
- FormViewCommandEventArgs.cs
- ModuleBuilderData.cs
- RichTextBox.cs
- MdiWindowListItemConverter.cs
- nulltextnavigator.cs
- AVElementHelper.cs
- PictureBox.cs
- SimpleHandlerFactory.cs
- BindingExpression.cs
- ObjectContextServiceProvider.cs
- PropertyDescriptor.cs
- XamlTreeBuilderBamlRecordWriter.cs
- ClientData.cs