NativeMsmqMessage.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 / ServiceModel / System / ServiceModel / Channels / NativeMsmqMessage.cs / 2 / NativeMsmqMessage.cs

                            //------------------------------------------------------------ 
// Copyright (c) Microsoft Corporation.  All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Channels
{ 
    using System;
    using System.Globalization; 
    using System.Text; 
    using System.Threading;
    using System.Runtime.InteropServices; 
    using System.Security;
    using System.Runtime.Serialization;
    using System.ServiceModel.Diagnostics;
    using Microsoft.Win32.SafeHandles; 

    abstract class NativeMsmqMessage : IDisposable 
    { 
        UnsafeNativeMethods.MQPROPVARIANT[] variants;
        UnsafeNativeMethods.MQMSGPROPS nativeProperties; 
        int[] ids;
        GCHandle nativePropertiesHandle;
        GCHandle variantsHandle;
        GCHandle idsHandle; 
        MsmqProperty[] properties;
        bool disposed; 
        object[] buffersForAsync; 

        protected NativeMsmqMessage(int propertyCount) 
        {
            this.properties = new MsmqProperty[propertyCount];
            this.nativeProperties = new UnsafeNativeMethods.MQMSGPROPS();
            this.ids = new int[propertyCount]; 
            this.variants = new UnsafeNativeMethods.MQPROPVARIANT[propertyCount];
 
            this.nativePropertiesHandle = GCHandle.Alloc(null, GCHandleType.Pinned); 
            this.idsHandle = GCHandle.Alloc(null, GCHandleType.Pinned);
            this.variantsHandle = GCHandle.Alloc(null, GCHandleType.Pinned); 
        }

        ~NativeMsmqMessage()
        { 
            Dispose(false);
        } 
 
        public virtual void GrowBuffers()
        { 
        }

        public object[] GetBuffersForAsync()
        { 
            if (null == this.buffersForAsync)
            { 
                int propertyBuffersToPin = 0; 
                for (int i = 0; i < this.nativeProperties.count; ++i)
                { 
                    if (this.properties[i].MaintainsBuffer)
                        ++propertyBuffersToPin;
                }
                this.buffersForAsync = new object[propertyBuffersToPin + 3]; 
            }
 
            int bufferCount = 0; 
            for (int i = 0; i < this.nativeProperties.count; ++i)
            { 
                if (this.properties[i].MaintainsBuffer)
                {
                    this.buffersForAsync[bufferCount++] = this.properties[i].MaintainedBuffer;
                } 
            }
            this.buffersForAsync[bufferCount++] = this.ids; 
            this.buffersForAsync[bufferCount++] = this.variants; 
            this.buffersForAsync[bufferCount] = this.nativeProperties;
 
            return this.buffersForAsync;
        }

        public IntPtr Pin() 
        {
            for (int i = 0; i < this.nativeProperties.count; i++) 
                properties[i].Pin(); 

            this.idsHandle.Target = this.ids; 
            this.variantsHandle.Target = this.variants;

            this.nativeProperties.status = IntPtr.Zero;
            this.nativeProperties.variants = this.variantsHandle.AddrOfPinnedObject(); 
            this.nativeProperties.ids = this.idsHandle.AddrOfPinnedObject();
            this.nativePropertiesHandle.Target = this.nativeProperties; 
 
            return nativePropertiesHandle.AddrOfPinnedObject();
        } 

        public void Unpin()
        {
            this.nativePropertiesHandle.Target = null; 
            this.idsHandle.Target = null;
            this.variantsHandle.Target = null; 
 
            for (int i = 0; i < this.nativeProperties.count; i++)
                properties[i].Unpin(); 
        }

        public void Dispose()
        { 
            Dispose(true);
            GC.SuppressFinalize(this); 
        } 

        void Dispose(bool disposing) 
        {
            if (!this.disposed && disposing)
            {
                for (int i = 0; i < this.nativeProperties.count; i++) 
                {
                    this.properties[i].Dispose(); 
                } 

                this.disposed = true; 
            }
            if (this.nativePropertiesHandle.IsAllocated)
                this.nativePropertiesHandle.Free();
            if (this.idsHandle.IsAllocated) 
                this.idsHandle.Free();
            if (this.variantsHandle.IsAllocated) 
                this.variantsHandle.Free(); 
        }
 
        public abstract class MsmqProperty : IDisposable
        {
            UnsafeNativeMethods.MQPROPVARIANT[] variants;
            int index; 

            protected MsmqProperty(NativeMsmqMessage message, int id, ushort vt) 
            { 
                this.variants = message.variants;
                this.index = message.nativeProperties.count++; 
                message.variants[this.index].vt = vt;
                message.ids[this.index] = id;
                message.properties[this.index] = this;
            } 

            protected int Index 
            { 
                get { return this.index; }
            } 

            public virtual bool MaintainsBuffer
            {
                get { return false; } 
            }
 
            public virtual object MaintainedBuffer 
            {
                get { return null; } 
            }

            public virtual void Pin()
            { 
            }
 
            public virtual void Unpin() 
            {
            } 

            public virtual void Dispose()
            {
            } 

            protected UnsafeNativeMethods.MQPROPVARIANT[] Variants 
            { 
                get { return this.variants; }
            } 
        }

        public class ByteProperty : MsmqProperty
        { 
            public ByteProperty(NativeMsmqMessage message, int id)
                : base(message, id, UnsafeNativeMethods.VT_UI1) 
            { 
            }
 
            public ByteProperty(NativeMsmqMessage message, int id, byte value)
                : this(message, id)
            {
                this.Value = value; 
            }
 
            public byte Value 
            {
                get 
                {
                    return this.Variants[this.Index].byteValue;
                }
                set 
                {
                    this.Variants[this.Index].byteValue = value; 
                } 
            }
        } 

        public class ShortProperty : MsmqProperty
        {
            public ShortProperty(NativeMsmqMessage message, int id) 
                : base(message, id, UnsafeNativeMethods.VT_UI2)
            { 
            } 

            public ShortProperty(NativeMsmqMessage message, int id, short value) 
                : this(message, id)
            {
                this.Value = value;
            } 

            public short Value 
            { 
                get
                { 
                    return this.Variants[this.Index].shortValue;
                }
                set
                { 
                    this.Variants[this.Index].shortValue = value;
                } 
            } 
        }
 

        public class BooleanProperty : MsmqProperty
        {
            public BooleanProperty(NativeMsmqMessage message, int id) 
                : base(message, id, UnsafeNativeMethods.VT_BOOL)
            { 
            } 

            public BooleanProperty(NativeMsmqMessage message, int id, bool value) 
                : this(message, id)
            {
                this.Value = value;
            } 

            public bool Value 
            { 
                get
                { 
                    return this.Variants[this.Index].shortValue != 0;
                }
                set
                { 
                    this.Variants[this.Index].shortValue = value ? (short)-1 : (short)0;
                } 
            } 
        }
 
        public class IntProperty : MsmqProperty
        {
            public IntProperty(NativeMsmqMessage message, int id)
                : base(message, id, UnsafeNativeMethods.VT_UI4) 
            {
            } 
 
            public IntProperty(NativeMsmqMessage message, int id, int value)
                : this(message, id) 
            {
                this.Value = value;
            }
 
            public int Value
            { 
                get 
                {
                    return this.Variants[this.Index].intValue; 
                }
                set
                {
                    this.Variants[this.Index].intValue = value; 
                }
            } 
        } 

        public class LongProperty : MsmqProperty 
        {
            public LongProperty(NativeMsmqMessage message, int id)
                : base(message, id, UnsafeNativeMethods.VT_UI8)
            { 
            }
 
            public LongProperty(NativeMsmqMessage message, int id, long value) 
                : this(message, id)
            { 
                this.Value = value;
            }

            public long Value 
            {
                get 
                { 
                    return this.Variants[this.Index].longValue;
                } 
                set
                {
                    this.Variants[this.Index].longValue = value;
                } 
            }
        } 
 
        public class BufferProperty : MsmqProperty
        { 
            byte[] buffer;
            GCHandle bufferHandle;

            public BufferProperty(NativeMsmqMessage message, int id) 
                : base(message, id, UnsafeNativeMethods.VT_UI1 | UnsafeNativeMethods.VT_VECTOR)
            { 
                bufferHandle = GCHandle.Alloc(null, GCHandleType.Pinned); 
            }
 
            public BufferProperty(NativeMsmqMessage message, int id, byte[] buffer)
                : this(message, id, buffer.Length)
            {
                System.Buffer.BlockCopy(buffer, 0, this.Buffer, 0, buffer.Length); 
            }
 
            public BufferProperty(NativeMsmqMessage message, int id, int length) 
                : this(message, id)
            { 
                SetBufferReference(DiagnosticUtility.Utility.AllocateByteArray(length));
            }

            ~BufferProperty() 
            {
                Dispose(false); 
            } 

            public override void Dispose() 
            {
                base.Dispose();
                this.Dispose(true);
                GC.SuppressFinalize(this); 
            }
 
            void Dispose(bool disposing) 
            {
                if (bufferHandle.IsAllocated) 
                    bufferHandle.Free();
            }

            public void SetBufferReference(byte[] buffer) 
            {
                SetBufferReference(buffer, buffer.Length); 
            } 

            public void SetBufferReference(byte[] buffer, int length) 
            {
                this.buffer = buffer;
                this.BufferLength = length;
            } 

            public override bool MaintainsBuffer 
            { 
                get { return true; }
            } 

            public override object MaintainedBuffer
            {
                get { return this.buffer; } 
            }
 
            public override void Pin() 
            {
                bufferHandle.Target = buffer; 
                this.Variants[this.Index].byteArrayValue.intPtr = bufferHandle.AddrOfPinnedObject();
            }

            public override void Unpin() 
            {
                this.Variants[this.Index].byteArrayValue.intPtr = IntPtr.Zero; 
                bufferHandle.Target = null; 
            }
 
            public byte[] GetBufferCopy(int length)
            {
                byte[] buffer = DiagnosticUtility.Utility.AllocateByteArray(length);
                System.Buffer.BlockCopy(this.buffer, 0, buffer, 0, length); 
                return buffer;
            } 
 
            public void EnsureBufferLength(int length)
            { 
                if (this.buffer.Length < length)
                {
                    SetBufferReference(DiagnosticUtility.Utility.AllocateByteArray(length));
                } 
            }
 
            public int BufferLength 
            {
                get 
                {
                    return this.Variants[this.Index].byteArrayValue.size;
                }
                set 
                {
                    if (value > this.buffer.Length) 
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value")); 
                    this.Variants[this.Index].byteArrayValue.size = value;
                } 
            }

            public byte[] Buffer
            { 
                get
                { 
                    return this.buffer; 
                }
            } 
        }

        public class StringProperty : MsmqProperty
        { 
            char[] buffer;
            GCHandle bufferHandle; 
 
            internal StringProperty(NativeMsmqMessage message, int id, string value)
                : this(message, id, value.Length + 1) 
            {
                CopyValueToBuffer(value);
            }
 
            internal StringProperty(NativeMsmqMessage message, int id, int length)
                : base(message, id, UnsafeNativeMethods.VT_LPWSTR) 
            { 
                this.buffer = DiagnosticUtility.Utility.AllocateCharArray(length);
                this.bufferHandle = GCHandle.Alloc(null, GCHandleType.Pinned); 
            }

            ~StringProperty()
            { 
                Dispose(false);
            } 
 
            public override bool MaintainsBuffer
            { 
                get { return true; }
            }

            public override object MaintainedBuffer 
            {
                get { return this.buffer; } 
            } 

            public override void Pin() 
            {
                this.bufferHandle.Target = buffer;
                this.Variants[this.Index].intPtr = bufferHandle.AddrOfPinnedObject();
            } 

            public override void Unpin() 
            { 
                this.Variants[this.Index].intPtr = IntPtr.Zero;
                this.bufferHandle.Target = null; 
            }

            public override void Dispose()
            { 
                base.Dispose();
                Dispose(true); 
                GC.SuppressFinalize(this); 
            }
 
            void Dispose(bool disposing)
            {
                if (bufferHandle.IsAllocated)
                    bufferHandle.Free(); 
            }
 
            public void EnsureValueLength(int length) 
            {
                if (length > this.buffer.Length) 
                {
                    this.buffer = DiagnosticUtility.Utility.AllocateCharArray(length);
                }
            } 

            public void SetValue(string value) 
            { 
                if (null == value)
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value"); 
                EnsureValueLength(value.Length + 1);
                CopyValueToBuffer(value);
            }
 
            void CopyValueToBuffer(string value)
            { 
                value.CopyTo(0, this.buffer, 0, value.Length); 
                this.buffer[value.Length] = '\0';
            } 

            public string GetValue(int length)
            {
                if (length == 0) 
                {
                    return null; 
                } 
                else
                { 
                    return new string(this.buffer, 0, length - 1);
                }
            }
        } 
    }
 
    static class MsmqMessageId 
    {
        const int guidSize = 16; 

        public static string ToString(byte[] messageId)
        {
            StringBuilder result = new StringBuilder(); 
            byte[] guid = new byte[guidSize];
            Array.Copy(messageId, guid, guidSize); 
            int id = BitConverter.ToInt32(messageId, guidSize); 
            result.Append((new Guid(guid)).ToString());
            result.Append("\\"); 
            result.Append(id);
            return result.ToString();
        }
 
        public static byte[] FromString(string messageId)
        { 
            string[] pieces = messageId.Split(new char[] { '\\' }); 
            if (pieces.Length != 2)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidMessageId, messageId), "messageId")); 

            Guid guid;
 	        if(!DiagnosticUtility.Utility.TryCreateGuid(pieces[0], out guid))
	        { 
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidMessageId, messageId), "messageId"));
	     	} 
 
            int integerId;
            try 
            {
                integerId = Convert.ToInt32(pieces[1], CultureInfo.InvariantCulture);
            }
            catch (FormatException) 
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MsmqInvalidMessageId, messageId), "messageId")); 
            } 

            byte[] bytes = new byte[UnsafeNativeMethods.PROPID_M_MSGID_SIZE]; 
            Array.Copy(guid.ToByteArray(), bytes, guidSize);
            Array.Copy(BitConverter.GetBytes(integerId), 0, bytes, guidSize, 4);
            return bytes;
        } 
    }
 
    class MsmqEmptyMessage : NativeMsmqMessage 
    {
        public MsmqEmptyMessage() 
            : base(0)
        {}
    }
 
    static class MsmqDuration
    { 
        public static int FromTimeSpan(TimeSpan timeSpan) 
        {
            long totalSeconds = (long)timeSpan.TotalSeconds; 
            if (totalSeconds > int.MaxValue)
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
                                                                              SR.GetString(SR.MsmqTimeSpanTooLarge)));
            return (int)totalSeconds; 
        }
 
        public static TimeSpan ToTimeSpan(int seconds) 
        {
            return TimeSpan.FromSeconds(seconds); 
        }
    }

    static class MsmqDateTime 
    {
        public static DateTime ToDateTime(int seconds) 
        { 
            return new DateTime(1970, 1, 1).AddSeconds(seconds);
        } 
    }
}

// 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