XmlStreamNodeWriter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Serialization / System / Xml / XmlStreamNodeWriter.cs / 1 / XmlStreamNodeWriter.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.Xml
{ 
    using System.IO;
    using System.Collections.Generic; 
    using System.Text; 
    using System.Diagnostics;
    using System.Globalization; 
    using System.Runtime.Serialization;
    using System.Security;

    abstract class XmlStreamNodeWriter : XmlNodeWriter 
    {
        Stream stream; 
        byte[] buffer; 
        int offset;
        bool ownsStream; 
        const int bufferLength = 512;
        const int maxEntityLength = 32;
        const int maxBytesPerChar = 3;
        static UTF8Encoding UTF8Encoding = new UTF8Encoding(false, true); 

        protected XmlStreamNodeWriter() 
        { 
            this.buffer = new byte[bufferLength];
        } 

        protected void SetOutput(Stream stream, bool ownsStream)
        {
            this.stream = stream; 
            this.ownsStream = ownsStream;
            this.offset = 0; 
        } 

        // Getting/Setting the Stream exists for fragmenting 
        public Stream Stream
        {
            get
            { 
                return stream;
            } 
            set 
            {
                stream = value; 
            }
        }

        // StreamBuffer/BufferOffset exists only for the BinaryWriter to fix up nodes 
        public byte[] StreamBuffer
        { 
            get 
            {
                return buffer; 
            }
        }
        public int BufferOffset
        { 
            get
            { 
                return offset; 
            }
        } 

        public int Position
        {
            get 
            {
                return (int)stream.Position + offset; 
            } 
        }
 
        protected byte[] GetBuffer(int count, out int offset)
        {
            DiagnosticUtility.DebugAssert(count >= 0 && count <= bufferLength, "");
            int bufferOffset = this.offset; 
            if (bufferOffset + count <= bufferLength)
            { 
                offset = bufferOffset; 
            }
            else 
            {
                FlushBuffer();
                offset = 0;
            } 
#if DEBUG
            DiagnosticUtility.DebugAssert(offset + count <= bufferLength, ""); 
            for (int i = 0; i < count; i++) 
            {
                buffer[offset + i] = (byte)'<'; 
            }
#endif
            return buffer;
        } 

        protected void Advance(int count) 
        { 
            DiagnosticUtility.DebugAssert(offset + count <= bufferLength, "");
            offset += count; 
        }

        void EnsureByte()
        { 
            if (offset >= bufferLength)
            { 
                FlushBuffer(); 
            }
        } 

        protected void WriteByte(byte b)
        {
            EnsureByte(); 
            buffer[offset++] = b;
        } 
 
        protected void WriteByte(char ch)
        { 
            DiagnosticUtility.DebugAssert(ch < 0x80, "");
            WriteByte((byte)ch);
        }
 
        protected void WriteBytes(byte b1, byte b2)
        { 
            byte[] buffer = this.buffer; 
            int offset = this.offset;
            if (offset + 1 >= bufferLength) 
            {
                FlushBuffer();
                offset = 0;
            } 
            buffer[offset + 0] = b1;
            buffer[offset + 1] = b2; 
            this.offset += 2; 
        }
 
        protected void WriteBytes(char ch1, char ch2)
        {
            DiagnosticUtility.DebugAssert(ch1 < 0x80 && ch2 < 0x80, "");
            WriteBytes((byte)ch1, (byte)ch2); 
        }
 
        public void WriteBytes(byte[] byteBuffer, int byteOffset, int byteCount) 
        {
            if (byteCount < bufferLength) 
            {
                int offset;
                byte[] buffer = GetBuffer(byteCount, out offset);
                Buffer.BlockCopy(byteBuffer, byteOffset, buffer, offset, byteCount); 
                Advance(byteCount);
            } 
            else 
            {
                FlushBuffer(); 
                stream.Write(byteBuffer, byteOffset, byteCount);
            }
        }
 
        /// 
        /// Critical - contains unsafe code 
        ///            caller needs to validate arguments 
        /// 
        [SecurityCritical] 
        unsafe protected void UnsafeWriteBytes(byte* bytes, int byteCount)
        {
            FlushBuffer();
            byte[] buffer = this.buffer; 
            while (byteCount >= bufferLength)
            { 
                for (int i = 0; i < bufferLength; i++) 
                    buffer[i] = bytes[i];
                stream.Write(buffer, 0, bufferLength); 
                bytes += bufferLength;
                byteCount -= bufferLength;
            }
            { 
                for (int i = 0; i < byteCount; i++)
                    buffer[i] = bytes[i]; 
                stream.Write(buffer, 0, byteCount); 
            }
        } 

        /// 
        /// Critical - contains unsafe code
        /// Safe - unsafe code is effectively encapsulated, all inputs are validated 
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        unsafe protected void WriteUTF8Char(int ch) 
        {
            if (ch < 0x80) 
            {
                WriteByte((byte)ch);
            }
            else if (ch <= char.MaxValue) 
            {
                char* chars = stackalloc char[1]; 
                chars[0] = (char)ch; 
                UnsafeWriteUTF8Chars(chars, 1);
            } 
            else
            {
                SurrogateChar surrogateChar = new SurrogateChar(ch);
                char* chars = stackalloc char[2]; 
                chars[0] = surrogateChar.HighChar;
                chars[1] = surrogateChar.LowChar; 
                UnsafeWriteUTF8Chars(chars, 2); 
            }
        } 

        protected void WriteUTF8Chars(byte[] chars, int charOffset, int charCount)
        {
            if (charCount < bufferLength) 
            {
                int offset; 
                byte[] buffer = GetBuffer(charCount, out offset); 
                Buffer.BlockCopy(chars, charOffset, buffer, offset, charCount);
                Advance(charCount); 
            }
            else
            {
                FlushBuffer(); 
                stream.Write(chars, charOffset, charCount);
            } 
        } 

        ///  
        /// Critical - contains unsafe code
        /// Safe - unsafe code is effectively encapsulated, all inputs are validated
        /// 
        [SecurityCritical, SecurityTreatAsSafe] 
        unsafe protected void WriteUTF8Chars(string value)
        { 
            int count = value.Length; 
            if (count > 0)
            { 
                fixed (char* chars = value)
                {
                    UnsafeWriteUTF8Chars(chars, count);
                } 
            }
        } 
 
        /// 
        /// Critical - contains unsafe code 
        ///            caller needs to validate arguments
        /// 
        [SecurityCritical]
        unsafe protected void UnsafeWriteUTF8Chars(char* chars, int charCount) 
        {
            const int charChunkSize = bufferLength / maxBytesPerChar; 
            while (charCount > charChunkSize) 
            {
                int offset; 
                int chunkSize = charChunkSize;
                if ((int)(chars[chunkSize - 1] & 0xFC00) == 0xD800) // This is a high surrogate
                    chunkSize--;
                byte[] buffer = GetBuffer(chunkSize * maxBytesPerChar, out offset); 
                Advance(UnsafeGetUTF8Chars(chars, chunkSize, buffer, offset));
                charCount -= chunkSize; 
                chars += chunkSize; 
            }
            if (charCount > 0) 
            {
                int offset;
                byte[] buffer = GetBuffer(charCount * maxBytesPerChar, out offset);
                Advance(UnsafeGetUTF8Chars(chars, charCount, buffer, offset)); 
            }
        } 
 
        /// 
        /// Critical - contains unsafe code 
        ///            caller needs to validate arguments
        /// 
        [SecurityCritical]
        unsafe protected void UnsafeWriteUnicodeChars(char* chars, int charCount) 
        {
            const int charChunkSize = bufferLength / 2; 
            while (charCount > charChunkSize) 
            {
                int offset; 
                int chunkSize = charChunkSize;
                if ((int)(chars[chunkSize - 1] & 0xFC00) == 0xD800) // This is a high surrogate
                    chunkSize--;
                byte[] buffer = GetBuffer(chunkSize * 2, out offset); 
                Advance(UnsafeGetUnicodeChars(chars, chunkSize, buffer, offset));
                charCount -= chunkSize; 
                chars += chunkSize; 
            }
            if (charCount > 0) 
            {
                int offset;
                byte[] buffer = GetBuffer(charCount * 2, out offset);
                Advance(UnsafeGetUnicodeChars(chars, charCount, buffer, offset)); 
            }
        } 
 
        /// 
        /// Critical - contains unsafe code 
        ///            caller needs to validate arguments
        /// 
        [SecurityCritical]
        unsafe protected int UnsafeGetUnicodeChars(char* chars, int charCount, byte[] buffer, int offset) 
        {
            char* charsMax = chars + charCount; 
            while (chars < charsMax) 
            {
                char value = *chars++; 
                buffer[offset++] = (byte)value;
                value >>= 8;
                buffer[offset++] = (byte)value;
            } 
            return charCount * 2;
        } 
 
        /// 
        /// Critical - contains unsafe code 
        ///            caller needs to validate arguments
        /// 
        [SecurityCritical]
        unsafe protected int UnsafeGetUTF8Length(char* chars, int charCount) 
        {
            char* charsMax = chars + charCount; 
            while (chars < charsMax) 
            {
                if (*chars >= 0x80) 
                    break;

                chars++;
            } 

            if (chars == charsMax) 
                return charCount; 

            return (int)(chars - (charsMax - charCount)) + UTF8Encoding.GetByteCount(chars, (int)(charsMax - chars)); 
        }

        /// 
        /// Critical - contains unsafe code 
        ///            caller needs to validate arguments
        ///  
        [SecurityCritical] 
        unsafe protected int UnsafeGetUTF8Chars(char* chars, int charCount, byte[] buffer, int offset)
        { 
            if (charCount > 0)
            {
                fixed (byte* _bytes = &buffer[offset])
                { 
                    byte* bytes = _bytes;
                    byte* bytesMax = &bytes[buffer.Length - offset]; 
                    char* charsMax = &chars[charCount]; 

                    while (true) 
                    {
                        while (chars < charsMax && *chars < 0x80)
                        {
                            *bytes = (byte)*chars; 
                            bytes++;
                            chars++; 
                        } 

                        if (chars >= charsMax) 
                            break;

                        char* charsStart = chars;
                        while (chars < charsMax && *chars >= 0x80) 
                        {
                            chars++; 
                        } 

                        bytes += UTF8Encoding.GetBytes(charsStart, (int)(chars - charsStart), bytes, (int)(bytesMax - bytes)); 

                        if (chars >= charsMax)
                            break;
                    } 

                    return (int)(bytes - _bytes); 
                } 
            }
            return 0; 
        }

        protected virtual void FlushBuffer()
        { 
            if (offset != 0)
            { 
                stream.Write(buffer, 0, offset); 
                offset = 0;
            } 
        }

        public override void Flush()
        { 
            FlushBuffer();
            stream.Flush(); 
        } 

        public override void Close() 
        {
            if (stream != null)
            {
                if (ownsStream) 
                {
                    stream.Close(); 
                } 
                stream = null;
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK