Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <copyright file="System.Xml.Assembly.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
using System.Runtime.CompilerServices;
// Friend assemblies
#if SILVERLIGHT
#if !FEATURE_CORESYSTEM
[assembly: InternalsVisibleTo("System.ServiceModel, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9", AllInternalsVisible = false)]
#endif
// Depends on XsdDuration
[assembly: InternalsVisibleTo("System.Runtime.Serialization, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB", AllInternalsVisible = false)]
// Depends on XmlXapResolver.RegisterApplicationResourceStreamResolver and IApplicationResourceStreamResolver opened bug DevDiv:326719 to try and eliminate this dependency
[assembly: InternalsVisibleTo("System.Windows, PublicKey=00240000048000009400000006020000002400005253413100040000010001008D56C76F9E8649383049F383C44BE0EC204181822A6C31CF5EB7EF486944D032188EA1D3920763712CCB12D75FB77E9811149E6148E5D32FBAAB37611C1878DDC19E20EF135D0CB2CFF2BFEC3D115810C3D9069638FE4BE215DBF795861920E5AB6F7DB2E2CEEF136AC23D5DD2BF031700AEC232F6C6B1C785B4305C123B37AB", AllInternalsVisible = false)]
// System.Xml.Serialization needs AllInternalsVisible = true because it needs access to internal methods on XmlRootAttribute and the [FriendAccessAllowed] cannot be placed on an Attribute class.
[assembly: InternalsVisibleTo("System.Xml.Serialization, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9", AllInternalsVisible = true)]
#else
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Data.SqlXml, PublicKey=00000000000000000400000000000000")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("System.Xml.Linq, PublicKey=00000000000000000400000000000000")]
// This is to allow writing unit tests that test the internal functionality contained in this assembly.
[assembly: InternalsVisibleToAttribute("System.ServiceModel.Friend, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
#endif

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace System.Xml {
internal static class AsyncHelper {
public static readonly Task DoneTask = Task.FromResult(true);
public static readonly Task<bool> DoneTaskTrue = Task.FromResult(true);
public static readonly Task<bool> DoneTaskFalse = Task.FromResult(false);
public static readonly Task<int> DoneTaskZero = Task.FromResult(0);
public static bool IsSuccess(this Task task) {
return task.IsCompleted && task.Exception == null;
}
public static Task CallVoidFuncWhenFinish(this Task task, Action func) {
if (task.IsSuccess()) {
func();
return DoneTask;
}
else {
return _CallVoidFuncWhenFinish(task, func);
}
}
private static async Task _CallVoidFuncWhenFinish(this Task task, Action func) {
await task.ConfigureAwait(false);
func();
}
public static Task<bool> ReturnTaskBoolWhenFinish(this Task task, bool ret) {
if (task.IsSuccess()) {
if (ret)
return DoneTaskTrue;
else
return DoneTaskFalse;
}
else {
return _ReturnTaskBoolWhenFinish(task, ret);
}
}
public static async Task<bool> _ReturnTaskBoolWhenFinish(this Task task, bool ret) {
await task.ConfigureAwait(false);
return ret;
}
public static Task CallTaskFuncWhenFinish(this Task task, Func<Task> func) {
if (task.IsSuccess()) {
return func();
}
else {
return _CallTaskFuncWhenFinish(task, func);
}
}
private static async Task _CallTaskFuncWhenFinish(Task task, Func<Task> func) {
await task.ConfigureAwait(false);
await func().ConfigureAwait(false);
}
public static Task<bool> CallBoolTaskFuncWhenFinish(this Task task, Func<Task<bool>> func) {
if (task.IsSuccess()) {
return func();
}
else {
return _CallBoolTaskFuncWhenFinish(task, func);
}
}
private static async Task<bool> _CallBoolTaskFuncWhenFinish(this Task task, Func<Task<bool>> func) {
await task.ConfigureAwait(false);
return await func().ConfigureAwait(false);
}
public static Task<bool> ContinueBoolTaskFuncWhenFalse(this Task<bool> task, Func<Task<bool>> func) {
if (task.IsSuccess()) {
if (task.Result)
return DoneTaskTrue;
else
return func();
}
else {
return _ContinueBoolTaskFuncWhenFalse(task, func);
}
}
private static async Task<bool> _ContinueBoolTaskFuncWhenFalse(Task<bool> task, Func<Task<bool>> func) {
if (await task.ConfigureAwait(false))
return true;
else
return await func().ConfigureAwait(false);
}
}
}

View File

@@ -0,0 +1,211 @@
//------------------------------------------------------------------------------
// <copyright file="Base64Decoder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
namespace System.Xml {
internal class Base64Decoder : IncrementalReadDecoder {
//
// Fields
//
byte[] buffer;
int startIndex;
int curIndex;
int endIndex;
int bits;
int bitsFilled;
private static readonly String CharsBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
private static readonly byte[] MapBase64 = ConstructMapBase64();
private const int MaxValidChar = (int)'z';
private const byte Invalid = unchecked((byte)-1);
//
// IncrementalReadDecoder interface
//
internal override int DecodedCount {
get {
return curIndex - startIndex;
}
}
internal override bool IsFull {
get {
return curIndex == endIndex;
}
}
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecuritySafeCritical]
#endif
internal override unsafe int Decode( char[] chars, int startPos, int len ) {
if ( chars == null ) {
throw new ArgumentNullException( "chars" );
}
if ( len < 0 ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( startPos < 0 ) {
throw new ArgumentOutOfRangeException( "startPos" );
}
if ( chars.Length - startPos < len ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( len == 0 ) {
return 0;
}
int bytesDecoded, charsDecoded;
fixed ( char* pChars = &chars[startPos] ) {
fixed ( byte* pBytes = &buffer[curIndex] ) {
Decode( pChars, pChars + len, pBytes, pBytes + ( endIndex - curIndex ), out charsDecoded, out bytesDecoded );
}
}
curIndex += bytesDecoded;
return charsDecoded;
}
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecuritySafeCritical]
#endif
internal override unsafe int Decode(string str, int startPos, int len) {
if ( str == null ) {
throw new ArgumentNullException( "str" );
}
if ( len < 0 ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( startPos < 0 ) {
throw new ArgumentOutOfRangeException( "startPos" );
}
if ( str.Length - startPos < len ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( len == 0 ) {
return 0;
}
int bytesDecoded, charsDecoded;
fixed ( char* pChars = str ) {
fixed ( byte* pBytes = &buffer[curIndex] ) {
Decode( pChars + startPos, pChars + startPos + len, pBytes, pBytes + ( endIndex - curIndex ), out charsDecoded, out bytesDecoded );
}
}
curIndex += bytesDecoded;
return charsDecoded;
}
internal override void Reset() {
bitsFilled = 0;
bits = 0;
}
internal override void SetNextOutputBuffer( Array buffer, int index, int count ) {
Debug.Assert( buffer != null );
Debug.Assert( count >= 0 );
Debug.Assert( index >= 0 );
Debug.Assert( buffer.Length - index >= count );
Debug.Assert( ( buffer as byte[] ) != null );
this.buffer = (byte[])buffer;
this.startIndex = index;
this.curIndex = index;
this.endIndex = index + count;
}
//
// Private methods
//
private static byte[] ConstructMapBase64() {
byte[] mapBase64 = new byte[MaxValidChar + 1];
for ( int i = 0; i < mapBase64.Length; i++ ) {
mapBase64[i]= Invalid;
}
for ( int i = 0; i < CharsBase64.Length; i++ ) {
mapBase64[(int)CharsBase64[i]] = (byte)i;
}
return mapBase64;
}
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecurityCritical]
#endif
private unsafe void Decode(char* pChars, char* pCharsEndPos,
byte* pBytes, byte* pBytesEndPos,
out int charsDecoded, out int bytesDecoded ) {
#if DEBUG
Debug.Assert( pCharsEndPos - pChars >= 0 );
Debug.Assert( pBytesEndPos - pBytes >= 0 );
#endif
// walk hex digits pairing them up and shoving the value of each pair into a byte
byte *pByte = pBytes;
char *pChar = pChars;
int b = bits;
int bFilled = bitsFilled;
XmlCharType xmlCharType = XmlCharType.Instance;
while ( pChar < pCharsEndPos && pByte < pBytesEndPos ) {
char ch = *pChar;
// end?
if ( ch == '=' ) {
break;
}
pChar++;
// ignore white space
if ( ( xmlCharType.charProperties[ch] & XmlCharType.fWhitespace ) != 0 ) { // if ( xmlCharType.IsWhiteSpace(ch) ) {
continue;
}
int digit;
if ( ch > 122 || ( digit = MapBase64[ch] ) == Invalid ) {
throw new XmlException( Res.Xml_InvalidBase64Value, new string( pChars, 0, (int)( pCharsEndPos - pChars ) ) );
}
b = ( b << 6 ) | digit;
bFilled += 6;
if ( bFilled >= 8 ) {
// get top eight valid bits
*pByte++ = (byte)( ( b >> ( bFilled - 8 ) ) & 0xFF );
bFilled -= 8;
if ( pByte == pBytesEndPos ) {
goto Return;
}
}
}
if ( pChar < pCharsEndPos && *pChar == '=' ) {
bFilled = 0;
// ignore padding chars
do {
pChar++;
} while ( pChar < pCharsEndPos && *pChar == '=' );
// ignore whitespace after the padding chars
if ( pChar < pCharsEndPos ) {
do {
if ( !( ( xmlCharType.charProperties[*pChar++] & XmlCharType.fWhitespace ) != 0 ) ) { // if ( !( xmlCharType.IsWhiteSpace( chars[charPos++] ) ) ) {
throw new XmlException( Res.Xml_InvalidBase64Value, new string( pChars, 0, (int)( pCharsEndPos - pChars ) ) );
}
} while ( pChar < pCharsEndPos );
}
}
Return:
bits = b;
bitsFilled = bFilled;
bytesDecoded = (int)(pByte - pBytes);
charsDecoded = (int)(pChar - pChars);
}
}
}

View File

@@ -0,0 +1,125 @@
//------------------------------------------------------------------------------
// <copyright file="Base64Encoder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System.Text;
using System.Diagnostics;
namespace System.Xml {
internal abstract partial class Base64Encoder {
byte[] leftOverBytes;
int leftOverBytesCount;
char[] charsLine;
internal const int Base64LineSize = 76;
internal const int LineSizeInBytes = Base64LineSize/4*3;
internal Base64Encoder() {
charsLine = new char[Base64LineSize];
}
internal abstract void WriteChars( char[] chars, int index, int count );
internal void Encode( byte[] buffer, int index, int count ) {
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( count > buffer.Length - index ) {
throw new ArgumentOutOfRangeException( "count" );
}
// encode left-over buffer
if( leftOverBytesCount > 0 ) {
int i = leftOverBytesCount;
while ( i < 3 && count > 0 ) {
leftOverBytes[i++] = buffer[index++];
count--;
}
// the total number of buffer we have is less than 3 -> return
if ( count == 0 && i < 3 ) {
leftOverBytesCount = i;
return;
}
// encode the left-over buffer and write out
int leftOverChars = Convert.ToBase64CharArray( leftOverBytes, 0, 3, charsLine, 0 );
WriteChars( charsLine, 0, leftOverChars );
}
// store new left-over buffer
leftOverBytesCount = count % 3;
if ( leftOverBytesCount > 0 ) {
count -= leftOverBytesCount;
if ( leftOverBytes == null ) {
leftOverBytes = new byte[3];
}
for( int i = 0; i < leftOverBytesCount; i++ ) {
leftOverBytes[i] = buffer[ index + count + i ];
}
}
// encode buffer in 76 character long chunks
int endIndex = index + count;
int chunkSize = LineSizeInBytes;
while( index < endIndex ) {
if ( index + chunkSize > endIndex ) {
chunkSize = endIndex - index;
}
int charCount = Convert.ToBase64CharArray( buffer, index, chunkSize, charsLine, 0 );
WriteChars( charsLine, 0, charCount );
index += chunkSize;
}
}
internal void Flush() {
if ( leftOverBytesCount > 0 ) {
int leftOverChars = Convert.ToBase64CharArray( leftOverBytes, 0, leftOverBytesCount, charsLine, 0 );
WriteChars( charsLine, 0, leftOverChars );
leftOverBytesCount = 0;
}
}
}
internal partial class XmlRawWriterBase64Encoder : Base64Encoder {
XmlRawWriter rawWriter;
internal XmlRawWriterBase64Encoder( XmlRawWriter rawWriter ) {
this.rawWriter = rawWriter;
}
internal override void WriteChars( char[] chars, int index, int count ) {
rawWriter.WriteRaw( chars, index, count );
}
}
#if !SILVERLIGHT || FEATURE_NETCORE
internal partial class XmlTextWriterBase64Encoder : Base64Encoder {
XmlTextEncoder xmlTextEncoder;
internal XmlTextWriterBase64Encoder( XmlTextEncoder xmlTextEncoder ) {
this.xmlTextEncoder = xmlTextEncoder;
}
internal override void WriteChars( char[] chars, int index, int count ) {
xmlTextEncoder.WriteRaw( chars, index, count );
}
}
#endif
}

View File

@@ -0,0 +1,94 @@
using System.Text;
using System.Diagnostics;
using System.Threading.Tasks;
namespace System.Xml {
internal abstract partial class Base64Encoder {
internal abstract Task WriteCharsAsync(char[] chars, int index, int count);
internal async Task EncodeAsync( byte[] buffer, int index, int count ) {
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( count > buffer.Length - index ) {
throw new ArgumentOutOfRangeException( "count" );
}
// encode left-over buffer
if( leftOverBytesCount > 0 ) {
int i = leftOverBytesCount;
while ( i < 3 && count > 0 ) {
leftOverBytes[i++] = buffer[index++];
count--;
}
// the total number of buffer we have is less than 3 -> return
if ( count == 0 && i < 3 ) {
leftOverBytesCount = i;
return;
}
// encode the left-over buffer and write out
int leftOverChars = Convert.ToBase64CharArray( leftOverBytes, 0, 3, charsLine, 0 );
await WriteCharsAsync( charsLine, 0, leftOverChars ).ConfigureAwait(false);
}
// store new left-over buffer
leftOverBytesCount = count % 3;
if ( leftOverBytesCount > 0 ) {
count -= leftOverBytesCount;
if ( leftOverBytes == null ) {
leftOverBytes = new byte[3];
}
for( int i = 0; i < leftOverBytesCount; i++ ) {
leftOverBytes[i] = buffer[ index + count + i ];
}
}
// encode buffer in 76 character long chunks
int endIndex = index + count;
int chunkSize = LineSizeInBytes;
while( index < endIndex ) {
if ( index + chunkSize > endIndex ) {
chunkSize = endIndex - index;
}
int charCount = Convert.ToBase64CharArray( buffer, index, chunkSize, charsLine, 0 );
await WriteCharsAsync( charsLine, 0, charCount ).ConfigureAwait(false);
index += chunkSize;
}
}
internal async Task FlushAsync() {
if ( leftOverBytesCount > 0 ) {
int leftOverChars = Convert.ToBase64CharArray( leftOverBytes, 0, leftOverBytesCount, charsLine, 0 );
await WriteCharsAsync( charsLine, 0, leftOverChars ).ConfigureAwait(false);
leftOverBytesCount = 0;
}
}
}
internal partial class XmlTextWriterBase64Encoder : Base64Encoder {
internal override Task WriteCharsAsync(char[] chars, int index, int count) {
throw new NotImplementedException();
}
}
internal partial class XmlRawWriterBase64Encoder : Base64Encoder {
internal override Task WriteCharsAsync( char[] chars, int index, int count ) {
return rawWriter.WriteRawAsync( chars, index, count );
}
}
}

View File

@@ -0,0 +1,212 @@
//------------------------------------------------------------------------------
// <copyright file="BinHexDecoder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Diagnostics;
namespace System.Xml
{
internal class BinHexDecoder : IncrementalReadDecoder {
//
// Fields
//
byte[] buffer;
int startIndex;
int curIndex;
int endIndex;
bool hasHalfByteCached;
byte cachedHalfByte;
//
// IncrementalReadDecoder interface
//
internal override int DecodedCount {
get {
return curIndex - startIndex;
}
}
internal override bool IsFull {
get {
return curIndex == endIndex;
}
}
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecuritySafeCritical]
#endif
internal override unsafe int Decode(char[] chars, int startPos, int len) {
if ( chars == null ) {
throw new ArgumentNullException( "chars" );
}
if ( len < 0 ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( startPos < 0 ) {
throw new ArgumentOutOfRangeException( "startPos" );
}
if ( chars.Length - startPos < len ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( len == 0 ) {
return 0;
}
int bytesDecoded, charsDecoded;
fixed ( char* pChars = &chars[startPos] ) {
fixed ( byte* pBytes = &buffer[curIndex] ) {
Decode( pChars, pChars + len, pBytes, pBytes + ( endIndex - curIndex ),
ref this.hasHalfByteCached, ref this.cachedHalfByte, out charsDecoded, out bytesDecoded );
}
}
curIndex += bytesDecoded;
return charsDecoded;
}
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecuritySafeCritical]
#endif
internal override unsafe int Decode(string str, int startPos, int len) {
if ( str == null ) {
throw new ArgumentNullException( "str" );
}
if ( len < 0 ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( startPos < 0 ) {
throw new ArgumentOutOfRangeException( "startPos" );
}
if ( str.Length - startPos < len ) {
throw new ArgumentOutOfRangeException( "len" );
}
if ( len == 0 ) {
return 0;
}
int bytesDecoded, charsDecoded;
fixed ( char* pChars = str ) {
fixed ( byte* pBytes = &buffer[curIndex] ) {
Decode( pChars + startPos, pChars + startPos + len, pBytes, pBytes + ( endIndex - curIndex ),
ref this.hasHalfByteCached, ref this.cachedHalfByte, out charsDecoded, out bytesDecoded );
}
}
curIndex += bytesDecoded;
return charsDecoded;
}
internal override void Reset() {
this.hasHalfByteCached = false;
this.cachedHalfByte = 0;
}
internal override void SetNextOutputBuffer( Array buffer, int index, int count ) {
Debug.Assert( buffer != null );
Debug.Assert( count >= 0 );
Debug.Assert( index >= 0 );
Debug.Assert( buffer.Length - index >= count );
Debug.Assert( ( buffer as byte[] ) != null );
this.buffer = (byte[])buffer;
this.startIndex = index;
this.curIndex = index;
this.endIndex = index + count;
}
//
// Static methods
//
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecuritySafeCritical]
#endif
public static unsafe byte[] Decode(char[] chars, bool allowOddChars) {
if ( chars == null ) {
throw new ArgumentNullException( "chars" );
}
int len = chars.Length;
if ( len == 0 ) {
return new byte[0];
}
byte[] bytes = new byte[ ( len + 1 ) / 2 ];
int bytesDecoded, charsDecoded;
bool hasHalfByteCached = false;
byte cachedHalfByte = 0;
fixed ( char* pChars = &chars[0] ) {
fixed ( byte* pBytes = &bytes[0] ) {
Decode( pChars, pChars + len, pBytes, pBytes + bytes.Length, ref hasHalfByteCached, ref cachedHalfByte, out charsDecoded, out bytesDecoded );
}
}
if ( hasHalfByteCached && !allowOddChars ) {
throw new XmlException( Res.Xml_InvalidBinHexValueOddCount, new string( chars ) );
}
if ( bytesDecoded < bytes.Length ) {
byte[] tmp = new byte[ bytesDecoded ];
Array.Copy( bytes, 0, tmp, 0, bytesDecoded );
bytes = tmp;
}
return bytes;
}
//
// Private methods
//
#if SILVERLIGHT && !SILVERLIGHT_DISABLE_SECURITY
[System.Security.SecurityCritical]
#endif
private static unsafe void Decode(char* pChars, char* pCharsEndPos,
byte* pBytes, byte* pBytesEndPos,
ref bool hasHalfByteCached, ref byte cachedHalfByte,
out int charsDecoded, out int bytesDecoded ) {
#if DEBUG
Debug.Assert( pCharsEndPos - pChars >= 0 );
Debug.Assert( pBytesEndPos - pBytes >= 0 );
#endif
char* pChar = pChars;
byte* pByte = pBytes;
XmlCharType xmlCharType = XmlCharType.Instance;
while ( pChar < pCharsEndPos && pByte < pBytesEndPos ) {
byte halfByte;
char ch = *pChar++;
if ( ch >= 'a' && ch <= 'f' ) {
halfByte = (byte)(ch - 'a' + 10);
}
else if ( ch >= 'A' && ch <= 'F' ) {
halfByte = (byte)(ch - 'A' + 10);
}
else if ( ch >= '0' && ch <= '9' ) {
halfByte = (byte)(ch - '0');
}
else if ( ( xmlCharType.charProperties[ch] & XmlCharType.fWhitespace ) != 0 ) { // else if ( xmlCharType.IsWhiteSpace( ch ) ) {
continue;
}
else {
throw new XmlException( Res.Xml_InvalidBinHexValue, new string( pChars, 0, (int)( pCharsEndPos - pChars ) ) );
}
if ( hasHalfByteCached ) {
*pByte++ = (byte)( ( cachedHalfByte << 4 ) + halfByte );
hasHalfByteCached = false;
}
else {
cachedHalfByte = halfByte;
hasHalfByteCached = true;
}
}
bytesDecoded = (int)(pByte - pBytes);
charsDecoded = (int)(pChar - pChars);
}
}
}

View File

@@ -0,0 +1,79 @@
//------------------------------------------------------------------------------
// <copyright file="BinHexEncoder.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
namespace System.Xml {
internal static partial class BinHexEncoder {
private const string s_hexDigits = "0123456789ABCDEF";
private const int CharsChunkSize = 128;
internal static void Encode( byte[] buffer, int index, int count, XmlWriter writer ) {
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( count > buffer.Length - index ) {
throw new ArgumentOutOfRangeException( "count" );
}
char[] chars = new char[ ( count * 2 ) < CharsChunkSize ? ( count * 2 ) : CharsChunkSize ];
int endIndex = index + count;
while ( index < endIndex ) {
int cnt = ( count < CharsChunkSize/2 ) ? count : CharsChunkSize/2;
int charCount = Encode( buffer, index, cnt, chars );
writer.WriteRaw( chars, 0, charCount );
index += cnt;
count -= cnt;
}
}
internal static string Encode(byte[] inArray, int offsetIn, int count) {
if (null == inArray) {
throw new ArgumentNullException("inArray");
}
if (0 > offsetIn) {
throw new ArgumentOutOfRangeException("offsetIn");
}
if (0 > count) {
throw new ArgumentOutOfRangeException("count");
}
if (count > inArray.Length - offsetIn) {
throw new ArgumentOutOfRangeException("count");
}
char[] outArray = new char[2 * count];
int lenOut = Encode(inArray, offsetIn, count, outArray);
return new String(outArray, 0, lenOut);
}
private static int Encode(byte[] inArray, int offsetIn, int count, char[] outArray) {
int curOffsetOut =0, offsetOut = 0;
byte b;
int lengthOut = outArray.Length;
for (int j=0; j<count; j++) {
b = inArray[offsetIn ++];
outArray[curOffsetOut ++] = s_hexDigits[b >> 4];
if (curOffsetOut == lengthOut) {
break;
}
outArray[curOffsetOut ++] = s_hexDigits[b & 0xF];
if (curOffsetOut == lengthOut) {
break;
}
}
return curOffsetOut - offsetOut;
} // function
} // class
} // namespace

View File

@@ -0,0 +1,33 @@
using System.Threading.Tasks;
namespace System.Xml {
internal static partial class BinHexEncoder {
internal static async Task EncodeAsync( byte[] buffer, int index, int count, XmlWriter writer ) {
if ( buffer == null ) {
throw new ArgumentNullException( "buffer" );
}
if ( index < 0 ) {
throw new ArgumentOutOfRangeException( "index" );
}
if ( count < 0 ) {
throw new ArgumentOutOfRangeException( "count" );
}
if ( count > buffer.Length - index ) {
throw new ArgumentOutOfRangeException( "count" );
}
char[] chars = new char[ ( count * 2 ) < CharsChunkSize ? ( count * 2 ) : CharsChunkSize ];
int endIndex = index + count;
while ( index < endIndex ) {
int cnt = ( count < CharsChunkSize/2 ) ? count : CharsChunkSize/2;
int charCount = Encode( buffer, index, cnt, chars );
await writer.WriteRawAsync( chars, 0, charCount ).ConfigureAwait(false);
index += cnt;
count -= cnt;
}
}
} // class
} // namespace

View File

@@ -0,0 +1,85 @@
//------------------------------------------------------------------------------
// <copyright file="XmlBinaryWriter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Globalization;
namespace System.Xml {
/* These are the tokens used by the Yukon BinaryXml protocol */
internal enum BinXmlToken {
Error = 0,
NotImpl = -2,
EOF = -1,
XmlDecl = 0xFE,
Encoding = 0xFD,
DocType = 0xFC,
System = 0xFB,
Public = 0xFA,
Subset = 0xF9,
Element = 0xF8,
EndElem = 0xF7,
Attr = 0xF6,
EndAttrs = 0xF5,
PI = 0xF4,
Comment = 0xF3,
CData = 0xF2,
EndCData = 0xF1,
Name = 0xF0,
QName = 0xEF,
XmlText = 0xED,
Nest = 0xEC,
EndNest = 0xEB,
Extn = 0xEA,
NmFlush = 0xE9,
SQL_BIT = 0x06,
SQL_TINYINT = 0x07,
SQL_SMALLINT = 0x1,
SQL_INT = 0x02,
SQL_BIGINT = 0x08,
SQL_REAL = 0x03,
SQL_FLOAT = 0x04,
SQL_MONEY = 0x05,
SQL_SMALLMONEY = 0x14,
SQL_DATETIME = 0x12,
SQL_SMALLDATETIME = 0x13,
SQL_DECIMAL = 0x0A,
SQL_NUMERIC = 0x0B,
SQL_UUID = 0x09,
SQL_VARBINARY = 0x0F,
SQL_BINARY = 0x0C,
SQL_IMAGE = 0x17,
SQL_CHAR = 0x0D,
SQL_VARCHAR = 0x10,
SQL_TEXT = 0x16,
SQL_NVARCHAR = 0x11,
SQL_NCHAR = 0x0E,
SQL_NTEXT = 0x18,
SQL_UDT = 0x1B,
XSD_KATMAI_DATE = 0x7F,
XSD_KATMAI_DATETIME = 0x7E,
XSD_KATMAI_TIME = 0x7D,
XSD_KATMAI_DATEOFFSET = 0x7C,
XSD_KATMAI_DATETIMEOFFSET = 0x7B,
XSD_KATMAI_TIMEOFFSET = 0x7A,
XSD_BOOLEAN = 0x86,
XSD_TIME = 0x81,
XSD_DATETIME = 0x82,
XSD_DATE = 0x83,
XSD_BINHEX = 0x84,
XSD_BASE64 = 0x85,
XSD_DECIMAL = 0x87,
XSD_BYTE = 0x88,
XSD_UNSIGNEDSHORT = 0x89,
XSD_UNSIGNEDINT = 0x8A,
XSD_UNSIGNEDLONG = 0x8B,
XSD_QNAME = 0x8C,
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
7ec7d87c084fb519ca76c4e2fa804b1f08c64d37

View File

@@ -0,0 +1,83 @@
//------------------------------------------------------------------------------
// <copyright file="XmlBinaryWriter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Globalization;
using System.Xml.Schema;
using System.Threading.Tasks;
namespace System.Xml {
internal sealed partial class XmlSqlBinaryReader : XmlReader, IXmlNamespaceResolver {
public override Task<string> GetValueAsync() {
throw new NotSupportedException();
}
public override Task<bool> ReadAsync() {
throw new NotSupportedException();
}
public override Task<object> ReadContentAsObjectAsync() {
throw new NotSupportedException();
}
public override Task<object> ReadContentAsAsync(Type returnType, IXmlNamespaceResolver namespaceResolver) {
throw new NotSupportedException();
}
public override Task<XmlNodeType> MoveToContentAsync() {
throw new NotSupportedException();
}
public override Task<string> ReadContentAsStringAsync() {
throw new NotSupportedException();
}
public override Task<int> ReadContentAsBase64Async(byte[] buffer, int index, int count) {
throw new NotSupportedException();
}
public override Task<object> ReadElementContentAsAsync(Type returnType, IXmlNamespaceResolver namespaceResolver) {
throw new NotSupportedException();
}
public override Task<object> ReadElementContentAsObjectAsync() {
throw new NotSupportedException();
}
public override Task<int> ReadElementContentAsBinHexAsync(byte[] buffer, int index, int count) {
throw new NotSupportedException();
}
public override Task<string> ReadInnerXmlAsync() {
throw new NotSupportedException();
}
public override Task<string> ReadOuterXmlAsync() {
throw new NotSupportedException();
}
public override Task<int> ReadValueChunkAsync(char[] buffer, int index, int count) {
throw new NotSupportedException();
}
public override Task SkipAsync() {
throw new NotSupportedException();
}
public override Task<string> ReadElementContentAsStringAsync() {
throw new NotSupportedException();
}
}
}

View File

@@ -0,0 +1,115 @@
//------------------------------------------------------------------------------
// <copyright file="BitStack.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
namespace System.Xml {
using System;
using System.Diagnostics;
/// <summary>
/// Manages a stack of bits. Exposes push, pop, and peek operations.
/// </summary>
internal class BitStack {
private uint[] bitStack;
private int stackPos;
private uint curr;
/// <summary>
/// Initialize stack.
/// </summary>
public BitStack() {
// Set sentinel bit in 1st position. As bits are shifted onto this.curr, this sentinel
// bit shifts to the left. When it's about to overflow, this.curr will be pushed
// onto an unsigned int stack and the sentinel bit will be reset to 0x1.
this.curr = 0x1;
}
/// <summary>
/// Push a 0 or 1 bit onto the stack.
/// </summary>
public void PushBit(bool bit) {
if ((this.curr & 0x80000000) != 0) {
// If sentinel bit has reached the last position, push this.curr
PushCurr();
}
// Shift new bit onto this.curr (which must have at least one open position)
this.curr = (this.curr << 1) | (bit ? 1u : 0u);
}
/// <summary>
/// Pop the top bit from the stack and return it.
/// </summary>
public bool PopBit() {
bool bit;
Debug.Assert(this.curr != 0x1, "Stack empty");
// Shift rightmost bit from this.curr
bit = (this.curr & 0x1) != 0;
this.curr >>= 1;
if (this.curr == 0x1) {
// If sentinel bit has reached the rightmost position, pop this.curr
PopCurr();
}
return bit;
}
/// <summary>
/// Return the top bit on the stack without pushing or popping.
/// </summary>
public bool PeekBit() {
Debug.Assert(this.curr != 0x1, "Stack empty");
return (this.curr & 0x1) != 0;
}
#if !SILVERLIGHT // This property is not used in Silverlight
/// <summary>
/// Return true if there are currently no bits on the stack.
/// </summary>
public bool IsEmpty {
get { return this.curr == 0x1; }
}
#endif
/// <summary>
/// this.curr has enough space for 31 bits (minus 1 for sentinel bit). Once this space is
/// exhausted, a uint stack is created to handle the overflow.
/// </summary>
private void PushCurr() {
int len;
if (this.bitStack == null) {
this.bitStack = new uint[16];
}
// Push current unsigned int (which has been filled) onto a stack
// and initialize this.curr to be used for future pushes.
this.bitStack[this.stackPos++] = this.curr;
this.curr = 0x1;
// Resize stack if necessary
len = this.bitStack.Length;
if (this.stackPos >= len) {
uint[] bitStackNew = new uint[2 * len];
Array.Copy(this.bitStack, bitStackNew, len);
this.bitStack = bitStackNew;
}
}
/// <summary>
/// If all bits have been popped from this.curr, then pop the previous uint value from the stack in
/// order to provide another 31 bits.
/// </summary>
private void PopCurr() {
if (this.stackPos > 0)
this.curr = this.bitStack[--this.stackPos];
}
}
}

View File

@@ -0,0 +1,69 @@
//------------------------------------------------------------------------------
// <copyright file="Bits.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
namespace System.Xml {
using System;
using System.Diagnostics;
/// <summary>
/// Contains static utility methods used to manipulate bits in a word.
/// </summary>
internal static class Bits {
private static readonly uint MASK_0101010101010101 = 0x55555555;
private static readonly uint MASK_0011001100110011 = 0x33333333;
private static readonly uint MASK_0000111100001111 = 0x0f0f0f0f;
private static readonly uint MASK_0000000011111111 = 0x00ff00ff;
private static readonly uint MASK_1111111111111111 = 0x0000ffff;
/// <summary>
/// Returns the number of 1 bits in an unsigned integer. Counts bits by divide-and-conquer method,
/// first computing 16 2-bit counts, then 8 4-bit counts, then 4 8-bit counts, then 2 16-bit counts,
/// and finally 1 32-bit count.
/// </summary>
public static int Count(uint num) {
num = (num & MASK_0101010101010101) + ((num >> 1) & MASK_0101010101010101);
num = (num & MASK_0011001100110011) + ((num >> 2) & MASK_0011001100110011);
num = (num & MASK_0000111100001111) + ((num >> 4) & MASK_0000111100001111);
num = (num & MASK_0000000011111111) + ((num >> 8) & MASK_0000000011111111);
num = (num & MASK_1111111111111111) + (num >> 16);
return (int) num;
}
/// <summary>
/// Returns true if the unsigned integer has exactly one bit set.
/// </summary>
public static bool ExactlyOne(uint num) {
return num != 0 && (num & (num - 1)) == 0;
}
#if !SILVERLIGHT // These methods are not used in Silverlight
/// <summary>
/// Returns true if the unsigned integer has more than one bit set.
/// </summary>
public static bool MoreThanOne(uint num) {
return (num & (num - 1)) != 0;
}
/// <summary>
/// Clear the least significant bit that is set and return the result.
/// </summary>
public static uint ClearLeast(uint num) {
return num & (num - 1);
}
#endif
/// <summary>
/// Compute the 1-based position of the least sigificant bit that is set, and return it (return 0 if no bits are set).
/// (e.g. 0x1001100 will return 3, since the 3rd bit is set).
/// </summary>
public static int LeastPosition(uint num) {
if (num == 0) return 0;
return Count(num ^ (num - 1));
}
}
}

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
// <copyright file="ByteStack.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
namespace System.Xml {
// This stack is designed to minimize object creation for the
// objects being stored in the stack by allowing them to be
// re-used over time. It basically pushes the objects creating
// a high water mark then as Pop() is called they are not removed
// so that next time Push() is called it simply returns the last
// object that was already on the stack.
internal class ByteStack {
private byte[] stack;
private int growthRate;
private int top;
private int size;
public ByteStack(int growthRate) {
this.growthRate = growthRate;
top = 0;
stack = new byte[growthRate];
size = growthRate;
}
public void Push(byte data) {
if (size == top) {
byte[] newstack = new byte[size + growthRate];
if (top > 0) {
Buffer.BlockCopy(stack, 0, newstack, 0, top);
}
stack = newstack;
size += growthRate;
}
stack[top++] = data;
}
public byte Pop() {
if (top > 0) {
return stack[--top];
} else {
return 0;
}
}
public byte Peek() {
if (top > 0) {
return stack[top - 1];
} else {
return 0;
}
}
public int Length {
get {
return top;
}
}
}
}

View File

@@ -0,0 +1,301 @@
//------------------------------------------------------------------------------
// <copyright file="Shape.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
#if ENABLEDATABINDING
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Collections;
using System.Diagnostics;
using System.ComponentModel;
using System.Text;
namespace System.Xml.XPath.DataBinding
{
internal enum BindingType {
Text,
Element,
Attribute,
ElementNested,
Repeat,
Sequence,
Choice,
All
}
internal sealed class Shape
{
string name;
BindingType bindingType;
ArrayList particles; // XmlSchemaElement or XmlSchemaAttribute
ArrayList subShapes;
Shape nestedShape;
PropertyDescriptor[] propertyDescriptors;
XmlSchemaElement containerDecl;
static object[] emptyIList = new object[0];
public Shape(string name, BindingType bindingType)
{
this.name = name;
this.bindingType = bindingType;
}
public string Name {
get { return this.name; }
set { this.name = value; }
}
public BindingType BindingType {
get { return this.bindingType; }
set { this.bindingType = value; }
}
public XmlSchemaElement ContainerDecl {
get { return this.containerDecl; }
set { this.containerDecl = value; }
}
public bool IsNestedTable {
get {
switch (this.BindingType) {
case BindingType.ElementNested:
case BindingType.Repeat:
case BindingType.Sequence:
case BindingType.Choice:
case BindingType.All:
return true;
default:
return false;
}
}
}
public bool IsGroup {
get {
switch (this.BindingType) {
case BindingType.Sequence:
case BindingType.Choice:
case BindingType.All:
return true;
default:
return false;
}
}
}
public XmlSchemaType SchemaType {
get {
switch (this.bindingType) {
case BindingType.Text:
case BindingType.Element:
case BindingType.ElementNested: {
Debug.Assert(this.particles.Count == 1);
XmlSchemaElement xse = (XmlSchemaElement)this.particles[0];
return xse.ElementSchemaType;
}
case BindingType.Attribute: {
Debug.Assert(this.particles.Count == 1);
XmlSchemaAttribute xsa = (XmlSchemaAttribute)this.particles[0];
return xsa.AttributeSchemaType;
}
default:
return null;
}
}
}
public XmlSchemaElement XmlSchemaElement {
get {
switch (this.bindingType) {
case BindingType.Text:
case BindingType.Element:
case BindingType.ElementNested: {
Debug.Assert(this.particles.Count == 1);
return (XmlSchemaElement)this.particles[0];
}
default:
return this.containerDecl;
}
}
}
public IList Particles {
get {
if (null == this.particles)
return emptyIList;
return this.particles;
}
}
public IList SubShapes {
get {
if (null == this.subShapes)
return emptyIList;
return this.subShapes;
}
}
public Shape SubShape(int i) {
return (Shape)SubShapes[i];
}
public Shape NestedShape {
get {
//Debug.Assert(this.bindingType == BindingType.ElementNested);
return this.nestedShape;
}
set {
this.nestedShape = value;
}
}
public XmlQualifiedName AttributeName {
get {
Debug.Assert(this.bindingType == BindingType.Attribute);
XmlSchemaAttribute xsa = (XmlSchemaAttribute)this.particles[0];
return xsa.QualifiedName;
}
}
public void Clear() {
if (this.subShapes != null) {
this.subShapes.Clear();
this.subShapes = null;
}
if (this.particles != null) {
this.particles.Clear();
this.particles = null;
}
}
public void AddParticle(XmlSchemaElement elem) {
if (null == this.particles)
this.particles = new ArrayList();
Debug.Assert(this.bindingType != BindingType.Attribute);
this.particles.Add(elem);
}
public void AddParticle(XmlSchemaAttribute elem) {
Debug.Assert(this.bindingType == BindingType.Attribute);
Debug.Assert(this.particles == null);
this.particles = new ArrayList();
this.particles.Add(elem);
}
public void AddSubShape(Shape shape) {
if (null == this.subShapes)
this.subShapes = new ArrayList();
this.subShapes.Add(shape);
foreach (object p in shape.Particles) {
XmlSchemaElement xse = p as XmlSchemaElement;
if (null != xse)
AddParticle(xse);
}
}
public void AddAttrShapeAt(Shape shape, int pos) {
if (null == this.subShapes)
this.subShapes = new ArrayList();
this.subShapes.Insert(pos, shape);
}
public string[] SubShapeNames() {
string[] names = new string[SubShapes.Count];
for (int i=0; i<SubShapes.Count; i++)
names[i] = this.SubShape(i).Name;
return names;
}
public PropertyDescriptor[] PropertyDescriptors {
get {
if (null == this.propertyDescriptors) {
PropertyDescriptor[] descs;
switch (this.BindingType) {
case BindingType.Element:
case BindingType.Text:
case BindingType.Attribute:
case BindingType.Repeat:
descs = new PropertyDescriptor[1];
descs[0] = new XPathNodeViewPropertyDescriptor(this);
break;
case BindingType.ElementNested:
descs = this.nestedShape.PropertyDescriptors;
break;
case BindingType.Sequence:
case BindingType.Choice:
case BindingType.All:
descs = new PropertyDescriptor[SubShapes.Count];
for (int i=0; i < descs.Length; i++) {
descs[i] = new XPathNodeViewPropertyDescriptor(this, this.SubShape(i), i);
}
break;
default:
throw new NotSupportedException();
}
this.propertyDescriptors = descs;
}
return this.propertyDescriptors;
}
}
public int FindNamedSubShape(string name) {
for (int i=0; i<SubShapes.Count; i++) {
Shape shape = SubShape(i);
if (shape.Name == name)
return i;
}
return -1;
}
public int FindMatchingSubShape(object particle) {
for (int i=0; i<SubShapes.Count; i++) {
Shape shape = SubShape(i);
if (shape.IsParticleMatch(particle))
return i;
}
return -1;
}
public bool IsParticleMatch(object particle) {
for (int i=0; i<this.particles.Count; i++) {
if (particle == this.particles[i])
return true;
}
return false;
}
#if DEBUG
public string DebugDump() {
StringBuilder sb = new StringBuilder();
DebugDump(sb,"");
return sb.ToString();
}
void DebugDump(StringBuilder sb, String indent) {
sb.AppendFormat("{0}{1} '{2}'", indent, this.BindingType.ToString(), this.Name);
if (this.subShapes != null) {
sb.AppendLine(" {");
string subindent = String.Concat(indent, " ");
foreach (Shape s in this.SubShapes) {
s.DebugDump(sb, subindent);
}
sb.Append(indent);
sb.Append('}');
}
sb.AppendLine();
}
#endif
}
}
#endif

View File

@@ -0,0 +1,202 @@
//------------------------------------------------------------------------------
// <copyright file="ShapeGenerator.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
#if ENABLEDATABINDING
using System;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Collections;
using System.Diagnostics;
using System.ComponentModel;
using System.Text;
namespace System.Xml.XPath.DataBinding
{
internal sealed class ShapeGenerator
{
private Hashtable elementTypesProcessed;
private IXmlNamespaceResolver nsResolver;
public ShapeGenerator(IXmlNamespaceResolver nsResolver) {
this.elementTypesProcessed = new Hashtable();
this.nsResolver = nsResolver;
}
public Shape GenerateFromSchema(XmlSchemaElement xse) {
XmlQualifiedName xseName = xse.QualifiedName;
XmlSchemaType schemaType = xse.ElementSchemaType;
XmlSchemaComplexType complexType = schemaType as XmlSchemaComplexType;
if (null != complexType) {
XmlSchemaParticle particle = null;
Shape rootShape = null;
XmlSchemaContentType contentType = complexType.ElementDecl.ContentValidator.ContentType;
switch (contentType) {
case XmlSchemaContentType.Mixed:
case XmlSchemaContentType.TextOnly:
rootShape = new Shape(GenName(xseName) + "_Text", BindingType.Text);
rootShape.AddParticle(xse);
break;
case XmlSchemaContentType.Empty:
rootShape = new Shape(null, BindingType.Sequence);
break;
case XmlSchemaContentType.ElementOnly:
particle = complexType.ContentTypeParticle;
rootShape = ProcessParticle(particle, null);
break;
}
Debug.Assert(rootShape != null);
if (complexType.AttributeUses.Values.Count > 0) {
if (rootShape.BindingType != BindingType.Sequence) {
Shape s = new Shape(null, BindingType.Sequence);
s.AddSubShape(rootShape);
rootShape = s;
}
int pos = 0;
string[] names = rootShape.SubShapeNames();
ICollection attributes = complexType.AttributeUses.Values;
XmlSchemaAttribute[] xsaArray = new XmlSchemaAttribute[attributes.Count];
attributes.CopyTo(xsaArray, 0);
Array.Sort(xsaArray, new XmlSchemaAttributeComparer());
foreach(XmlSchemaAttribute xsa in xsaArray) {
string name = GenAttrName(xsa.QualifiedName, names);
Shape attrShape = new Shape(name, BindingType.Attribute);
attrShape.AddParticle(xsa);
rootShape.AddAttrShapeAt(attrShape, pos++);
}
}
if (rootShape.BindingType != BindingType.Text) {
rootShape.Name = GenName(xseName);
rootShape.ContainerDecl = xse;
}
return rootShape;
}
else { // simple type
Shape s = new Shape(GenName(xseName), BindingType.Text);
s.AddParticle(xse);
return s;
}
}
public Shape GenerateFromSchema(XmlSchemaAttribute xsa) {
Shape s = new Shape(GenName(xsa.QualifiedName), BindingType.Attribute);
s.AddParticle(xsa);
return s;
}
Shape ProcessParticle(XmlSchemaParticle xsp, Shape parent) {
Shape s;
if (xsp == XmlSchemaParticle.Empty) {
return null;
}
if (xsp is XmlSchemaElement) {
s = ProcessParticleElement((XmlSchemaElement)xsp);
}
else if (xsp is XmlSchemaSequence) {
s = ProcessParticleGroup((XmlSchemaSequence)xsp, BindingType.Sequence);
}
else if (xsp is XmlSchemaChoice) {
s = ProcessParticleGroup((XmlSchemaChoice)xsp, BindingType.Choice);
}
else if (xsp is XmlSchemaAll) {
s = ProcessParticleGroup((XmlSchemaAll)xsp, BindingType.All);
}
else { //XmlSchemaAny
return null; //Ignore Any in the content model
}
if (xsp.MaxOccurs > 1) {
Shape rep = new Shape(s.Name, BindingType.Repeat);
rep.AddSubShape(s);
s = rep;
}
if (parent != null)
parent.AddSubShape(s);
return s;
}
Shape ProcessParticleElement(XmlSchemaElement xse) {
// watch out for recursive schema
Shape s = (Shape)this.elementTypesProcessed[xse];
if (null != s)
return s;
bool complex = xse.ElementSchemaType is XmlSchemaComplexType;
s = new Shape(GenName(xse.QualifiedName), complex ? BindingType.ElementNested : BindingType.Element);
s.AddParticle(xse);
if (complex) {
this.elementTypesProcessed.Add(xse, s);
s.NestedShape = GenerateFromSchema(xse);
this.elementTypesProcessed.Remove(xse);
}
return s;
}
Shape ProcessParticleGroup(XmlSchemaGroupBase xsg, BindingType bt) {
Shape s = new Shape(null, bt);
StringBuilder sb = new StringBuilder();
foreach (XmlSchemaParticle xsp in xsg.Items) {
Shape sub = ProcessParticle(xsp, s);
if (sub != null) { //sub can be null if the child particle is xs:any
if (sb.Length > 0)
sb.Append('_');
sb.Append(sub.Name);
}
}
// need to also test if paretn != null for this to work
//if (s.IsGroup && s.SubShapes.Count == 1) {
// Shape sub = (Shape)s.SubShapes[0];
// s.Clear();
// return sub;
//}
s.Name = sb.ToString();
return s;
}
string GenName(XmlQualifiedName xqn) {
string ns = xqn.Namespace;
string ln = xqn.Name;
if (ns.Length != 0) {
string prefix = (null==this.nsResolver) ? null : this.nsResolver.LookupPrefix(ns);
if (prefix != null && prefix.Length != 0)
return String.Concat(prefix, ":", ln);
}
return ln;
}
string GenAttrName(XmlQualifiedName xqn, string[] names) {
string name = GenName(xqn);
if (null != names) {
for (int i=0; i<names.Length; i++) {
if (name == names[i]) {
return String.Concat("@", name);
}
}
}
return name;
}
public void ResetState() {
this.elementTypesProcessed.Clear();
}
class XmlSchemaAttributeComparer : IComparer {
public virtual int Compare(object a, object b) {
XmlSchemaAttribute xsaA = (XmlSchemaAttribute)a;
XmlSchemaAttribute xsaB = (XmlSchemaAttribute)b;
return XmlQualifiedName.Compare(xsaA.QualifiedName, xsaB.QualifiedName);
}
}
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,271 @@
//------------------------------------------------------------------------------
// <copyright file="XPathDocumentIterator.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <owner current="true" primary="true">[....]</owner>
//------------------------------------------------------------------------------
using System;
using System.Xml;
using System.Xml.XPath;
using System.Diagnostics;
namespace MS.Internal.Xml.Cache {
/// <summary>
/// Base internal class of all XPathDocument XPathNodeIterator implementations.
/// </summary>
internal abstract class XPathDocumentBaseIterator : XPathNodeIterator {
protected XPathDocumentNavigator ctxt;
protected int pos;
/// <summary>
/// Create a new iterator that is initially positioned on the "ctxt" node.
/// </summary>
protected XPathDocumentBaseIterator(XPathDocumentNavigator ctxt) {
this.ctxt = new XPathDocumentNavigator(ctxt);
}
/// <summary>
/// Create a new iterator that is a copy of "iter".
/// </summary>
protected XPathDocumentBaseIterator(XPathDocumentBaseIterator iter) {
this.ctxt = new XPathDocumentNavigator(iter.ctxt);
this.pos = iter.pos;
}
/// <summary>
/// Return the current navigator.
/// </summary>
public override XPathNavigator Current {
get { return this.ctxt; }
}
/// <summary>
/// Return the iterator's current position.
/// </summary>
public override int CurrentPosition {
get { return this.pos; }
}
}
/// <summary>
/// Iterate over all element children with a particular QName.
/// </summary>
internal class XPathDocumentElementChildIterator : XPathDocumentBaseIterator {
private string localName, namespaceUri;
/// <summary>
/// Create an iterator that ranges over all element children of "parent" having the specified QName.
/// </summary>
public XPathDocumentElementChildIterator(XPathDocumentNavigator parent, string name, string namespaceURI) : base(parent) {
if (namespaceURI == null) throw new ArgumentNullException("namespaceURI");
this.localName = parent.NameTable.Get(name);
this.namespaceUri = namespaceURI;
}
/// <summary>
/// Create a new iterator that is a copy of "iter".
/// </summary>
public XPathDocumentElementChildIterator(XPathDocumentElementChildIterator iter) : base(iter) {
this.localName = iter.localName;
this.namespaceUri = iter.namespaceUri;
}
/// <summary>
/// Create a copy of this iterator.
/// </summary>
public override XPathNodeIterator Clone() {
return new XPathDocumentElementChildIterator(this);
}
/// <summary>
/// Position the iterator to the next matching child.
/// </summary>
public override bool MoveNext() {
if (this.pos == 0) {
if (!this.ctxt.MoveToChild(this.localName, this.namespaceUri))
return false;
}
else {
if (!this.ctxt.MoveToNext(this.localName, this.namespaceUri))
return false;
}
this.pos++;
return true;
}
}
/// <summary>
/// Iterate over all content children with a particular XPathNodeType.
/// </summary>
internal class XPathDocumentKindChildIterator : XPathDocumentBaseIterator {
private XPathNodeType typ;
/// <summary>
/// Create an iterator that ranges over all content children of "parent" having the specified XPathNodeType.
/// </summary>
public XPathDocumentKindChildIterator(XPathDocumentNavigator parent, XPathNodeType typ) : base(parent) {
this.typ = typ;
}
/// <summary>
/// Create a new iterator that is a copy of "iter".
/// </summary>
public XPathDocumentKindChildIterator(XPathDocumentKindChildIterator iter) : base(iter) {
this.typ = iter.typ;
}
/// <summary>
/// Create a copy of this iterator.
/// </summary>
public override XPathNodeIterator Clone() {
return new XPathDocumentKindChildIterator(this);
}
/// <summary>
/// Position the iterator to the next descendant.
/// </summary>
public override bool MoveNext() {
if (this.pos == 0) {
if (!this.ctxt.MoveToChild(this.typ))
return false;
}
else {
if (!this.ctxt.MoveToNext(this.typ))
return false;
}
this.pos++;
return true;
}
}
/// <summary>
/// Iterate over all element descendants with a particular QName.
/// </summary>
internal class XPathDocumentElementDescendantIterator : XPathDocumentBaseIterator {
private XPathDocumentNavigator end;
private string localName, namespaceUri;
private bool matchSelf;
/// <summary>
/// Create an iterator that ranges over all element descendants of "root" having the specified QName.
/// </summary>
public XPathDocumentElementDescendantIterator(XPathDocumentNavigator root, string name, string namespaceURI, bool matchSelf) : base(root) {
if (namespaceURI == null) throw new ArgumentNullException("namespaceURI");
this.localName = root.NameTable.Get(name);
this.namespaceUri = namespaceURI;
this.matchSelf = matchSelf;
// Find the next non-descendant node that follows "root" in document order
if (root.NodeType != XPathNodeType.Root) {
this.end = new XPathDocumentNavigator(root);
this.end.MoveToNonDescendant();
}
}
/// <summary>
/// Create a new iterator that is a copy of "iter".
/// </summary>
public XPathDocumentElementDescendantIterator(XPathDocumentElementDescendantIterator iter) : base(iter) {
this.end = iter.end;
this.localName = iter.localName;
this.namespaceUri = iter.namespaceUri;
this.matchSelf = iter.matchSelf;
}
/// <summary>
/// Create a copy of this iterator.
/// </summary>
public override XPathNodeIterator Clone() {
return new XPathDocumentElementDescendantIterator(this);
}
/// <summary>
/// Position the iterator to the next descendant.
/// </summary>
public override bool MoveNext() {
if (this.matchSelf) {
this.matchSelf = false;
if (this.ctxt.IsElementMatch(this.localName, this.namespaceUri)) {
this.pos++;
return true;
}
}
if (!this.ctxt.MoveToFollowing(this.localName, this.namespaceUri, this.end))
return false;
this.pos++;
return true;
}
}
/// <summary>
/// Iterate over all content descendants with a particular XPathNodeType.
/// </summary>
internal class XPathDocumentKindDescendantIterator : XPathDocumentBaseIterator {
private XPathDocumentNavigator end;
private XPathNodeType typ;
private bool matchSelf;
/// <summary>
/// Create an iterator that ranges over all content descendants of "root" having the specified XPathNodeType.
/// </summary>
public XPathDocumentKindDescendantIterator(XPathDocumentNavigator root, XPathNodeType typ, bool matchSelf) : base(root) {
this.typ = typ;
this.matchSelf = matchSelf;
// Find the next non-descendant node that follows "root" in document order
if (root.NodeType != XPathNodeType.Root) {
this.end = new XPathDocumentNavigator(root);
this.end.MoveToNonDescendant();
}
}
/// <summary>
/// Create a new iterator that is a copy of "iter".
/// </summary>
public XPathDocumentKindDescendantIterator(XPathDocumentKindDescendantIterator iter) : base(iter) {
this.end = iter.end;
this.typ = iter.typ;
this.matchSelf = iter.matchSelf;
}
/// <summary>
/// Create a copy of this iterator.
/// </summary>
public override XPathNodeIterator Clone() {
return new XPathDocumentKindDescendantIterator(this);
}
/// <summary>
/// Position the iterator to the next descendant.
/// </summary>
public override bool MoveNext() {
if (this.matchSelf) {
this.matchSelf = false;
if (this.ctxt.IsKindMatch(this.typ)) {
this.pos++;
return true;
}
}
if (!this.ctxt.MoveToFollowing(this.typ, this.end))
return false;
this.pos++;
return true;
}
}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More