Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Messaging / System / Messaging / ActiveXMessageFormatter.cs / 1305376 / ActiveXMessageFormatter.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Messaging { using System.Runtime.Serialization.Formatters; using System.Runtime.InteropServices; using System.Text; using System.Runtime.Serialization; using System.Diagnostics; using System; using System.IO; using System.Globalization; using System.ComponentModel; using System.Messaging.Interop; ////// /// public class ActiveXMessageFormatter : IMessageFormatter { internal const short VT_ARRAY = 0x2000; internal const short VT_BOOL = 11; internal const short VT_BSTR = 8; internal const short VT_CLSID = 72; internal const short VT_CY = 6; internal const short VT_DATE = 7; internal const short VT_I1 = 16; internal const short VT_I2 = 2; internal const short VT_I4 = 3; internal const short VT_I8 = 20; internal const short VT_LPSTR = 30; internal const short VT_LPWSTR = 31; internal const short VT_NULL = 1; internal const short VT_R4 = 4; internal const short VT_R8 = 5; internal const short VT_STREAMED_OBJECT = 68; internal const short VT_STORED_OBJECT = 69; internal const short VT_UI1 = 17; internal const short VT_UI2 = 18; internal const short VT_UI4 = 19; internal const short VT_UI8 = 21; internal const short VT_VECTOR = 0x1000; private byte[] internalBuffer; private UnicodeEncoding unicodeEncoding; private ASCIIEncoding asciiEncoding; private char[] internalCharBuffer; ////// Formatter class that serializes and deserializes /// primitives, classes, enumeration, and other objects into and from ////// messages using binary format. /// /// /// When this method is called, the formatter will attempt to determine /// if the contents of the message are something the formatter can deal with. /// public bool CanRead(Message message) { if (message == null) throw new ArgumentNullException("message"); int variantType = message.BodyType; if (variantType != VT_BOOL && variantType != VT_CLSID && variantType != VT_CY && variantType != VT_DATE && variantType != VT_I1 && variantType != VT_UI1 && variantType != VT_I2 && variantType != VT_UI2 && variantType != VT_I4 && variantType != VT_UI4 && variantType != VT_I8 && variantType != VT_UI8 && variantType != VT_NULL && variantType != VT_R4 && variantType != VT_I8 && variantType != VT_STREAMED_OBJECT && variantType != VT_STORED_OBJECT && variantType != (VT_VECTOR | VT_UI1) && variantType != VT_LPSTR && variantType != VT_LPWSTR && variantType != VT_BSTR && variantType != VT_R8) return false; return true; } ////// /// This method is needed to improve scalability on Receive and ReceiveAsync scenarios. Not requiring /// thread safety on read and write. /// public object Clone() { return new ActiveXMessageFormatter(); } ////// /// public static void InitStreamedObject(object streamedObject) { IPersistStreamInit persistStreamInit = streamedObject as IPersistStreamInit; if (persistStreamInit != null) persistStreamInit.InitNew(); } ///[To be supplied.] ////// /// This method is used to read the contents from the given message /// and create an object. /// public object Read(Message message) { if (message == null) throw new ArgumentNullException("message"); Stream stream; byte[] bytes; byte[] newBytes; int size; int variantType = message.BodyType; switch (variantType) { case VT_LPSTR: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); size = message.properties.GetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE); if (this.internalCharBuffer == null || this.internalCharBuffer.Length < size) this.internalCharBuffer = new char[size]; if (asciiEncoding == null) this.asciiEncoding = new ASCIIEncoding(); this.asciiEncoding.GetChars(bytes, 0, size, this.internalCharBuffer, 0); return new String(this.internalCharBuffer, 0, size); case VT_BSTR: case VT_LPWSTR: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); size = message.properties.GetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE) / 2; if (this.internalCharBuffer == null || this.internalCharBuffer.Length < size) this.internalCharBuffer = new char[size]; if (unicodeEncoding == null) this.unicodeEncoding = new UnicodeEncoding(); this.unicodeEncoding.GetChars(bytes, 0, size * 2, this.internalCharBuffer, 0); return new String(this.internalCharBuffer, 0, size); case VT_VECTOR | VT_UI1: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); size = message.properties.GetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE); newBytes = new byte[size]; Array.Copy(bytes, newBytes, size); return newBytes; case VT_BOOL: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[1]; Array.Copy(bytes, newBytes, 1); if (bytes[0] != 0) return true; return false; case VT_CLSID: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[16]; Array.Copy(bytes, newBytes, 16); return new Guid(newBytes); case VT_CY: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[8]; Array.Copy(bytes, newBytes, 8); return Decimal.FromOACurrency(BitConverter.ToInt64(newBytes, 0)); case VT_DATE: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[8]; Array.Copy(bytes, newBytes, 8); return new DateTime(BitConverter.ToInt64(newBytes, 0)); case VT_I1: case VT_UI1: stream = message.BodyStream; bytes = new byte[1]; stream.Read(bytes, 0, 1); return bytes[0]; case VT_I2: stream = message.BodyStream; bytes = new byte[2]; stream.Read(bytes, 0, 2); return BitConverter.ToInt16(bytes, 0); case VT_UI2: stream = message.BodyStream; bytes = new byte[2]; stream.Read(bytes, 0, 2); return BitConverter.ToUInt16(bytes, 0); case VT_I4: stream = message.BodyStream; bytes = new byte[4]; stream.Read(bytes, 0, 4); return BitConverter.ToInt32(bytes, 0); case VT_UI4: stream = message.BodyStream; bytes = new byte[4]; stream.Read(bytes, 0, 4); return BitConverter.ToUInt32(bytes, 0); case VT_I8: stream = message.BodyStream; bytes = new byte[8]; stream.Read(bytes, 0, 8); return BitConverter.ToInt64(bytes, 0); case VT_UI8: stream = message.BodyStream; bytes = new byte[8]; stream.Read(bytes, 0, 8); return BitConverter.ToUInt64(bytes, 0); case VT_R4: stream = message.BodyStream; bytes = new byte[4]; stream.Read(bytes, 0, 4); return BitConverter.ToSingle(bytes, 0); case VT_R8: stream = message.BodyStream; bytes = new byte[8]; stream.Read(bytes, 0, 8); return BitConverter.ToDouble(bytes, 0); case VT_NULL: return null; case VT_STREAMED_OBJECT: stream = message.BodyStream; ComStreamFromDataStream comStream = new ComStreamFromDataStream(stream); return NativeMethods.OleLoadFromStream(comStream, ref NativeMethods.IID_IUnknown); case VT_STORED_OBJECT: throw new NotSupportedException(Res.GetString(Res.StoredObjectsNotSupported)); default: throw new InvalidOperationException(Res.GetString(Res.InvalidTypeDeserialization)); } } ////// /// This method is used to write the given object into the given message. /// If the formatter cannot understand the given object, an exception is thrown. /// public void Write(Message message, object obj) { if (message == null) throw new ArgumentNullException("message"); Stream stream; int variantType; if (obj is string) { int size = ((string)obj).Length * 2; if (this.internalBuffer == null || this.internalBuffer.Length < size) this.internalBuffer = new byte[size]; if (unicodeEncoding == null) this.unicodeEncoding = new UnicodeEncoding(); this.unicodeEncoding.GetBytes(((string)obj).ToCharArray(), 0, size /2, this.internalBuffer, 0); message.properties.SetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY, this.internalBuffer); message.properties.AdjustSize(NativeMethods.MESSAGE_PROPID_BODY, size); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE, size); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_TYPE, VT_LPWSTR); return; } else if (obj is byte[]) { byte[] bytes = (byte[])obj; if (this.internalBuffer == null || this.internalBuffer.Length < bytes.Length) this.internalBuffer = new byte[bytes.Length]; Array.Copy(bytes, this.internalBuffer, bytes.Length); message.properties.SetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY, this.internalBuffer); message.properties.AdjustSize(NativeMethods.MESSAGE_PROPID_BODY, bytes.Length); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE, bytes.Length); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_TYPE, VT_UI1 | VT_VECTOR); return; } else if (obj is char[]) { char[] chars = (char[])obj; int size = chars.Length * 2; if (this.internalBuffer == null || this.internalBuffer.Length < size) this.internalBuffer = new byte[size]; if (unicodeEncoding == null) this.unicodeEncoding = new UnicodeEncoding(); this.unicodeEncoding.GetBytes(chars, 0, size /2, this.internalBuffer, 0); message.properties.SetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY, this.internalBuffer); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE, size); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_TYPE, VT_LPWSTR); return; } else if (obj is byte) { stream = new MemoryStream(1); stream.Write(new byte[]{(byte)obj}, 0, 1); variantType = VT_UI1; } else if (obj is bool) { stream = new MemoryStream(1); if ((bool)obj) stream.Write(new byte[]{0xff}, 0, 1); else stream.Write(new byte[]{0x00}, 0, 1); variantType = VT_BOOL; } else if (obj is char) { stream = new MemoryStream(2); byte[] bytes = BitConverter.GetBytes((Char)obj); stream.Write(bytes, 0, 2); variantType = VT_UI2; } else if (obj is Decimal) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes(Decimal.ToOACurrency((Decimal)obj)); stream.Write(bytes, 0, 8); variantType = VT_CY; } else if (obj is DateTime) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes(((DateTime)obj).Ticks); stream.Write(bytes, 0, 8); variantType = VT_DATE; } else if (obj is Double) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes((Double)obj); stream.Write(bytes, 0, 8); variantType = VT_R8; } else if (obj is Int16) { stream = new MemoryStream(2); byte[] bytes = BitConverter.GetBytes((short)obj); stream.Write(bytes, 0, 2); variantType = VT_I2; } else if (obj is UInt16) { stream = new MemoryStream(2); byte[] bytes = BitConverter.GetBytes((UInt16)obj); stream.Write(bytes, 0, 2); variantType = VT_UI2; } else if (obj is Int32) { stream = new MemoryStream(4); byte[] bytes = BitConverter.GetBytes((int)obj); stream.Write(bytes, 0, 4); variantType = VT_I4; } else if (obj is UInt32) { stream = new MemoryStream(4); byte[] bytes = BitConverter.GetBytes((UInt32)obj); stream.Write(bytes, 0, 4); variantType = VT_UI4; } else if (obj is Int64) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes((Int64)obj); stream.Write(bytes, 0, 8); variantType = VT_I8; } else if (obj is UInt64) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes((UInt64)obj); stream.Write(bytes, 0, 8); variantType = VT_UI8; } else if (obj is Single) { stream = new MemoryStream(4); byte[] bytes = BitConverter.GetBytes((float)obj); stream.Write(bytes, 0, 4); variantType = VT_R4; } else if (obj is IPersistStream) { IPersistStream pstream = (IPersistStream) obj; ComStreamFromDataStream comStream = new ComStreamFromDataStream(new MemoryStream()); NativeMethods.OleSaveToStream(pstream, comStream); stream = comStream.GetDataStream(); variantType = VT_STREAMED_OBJECT; } else if (obj == null) { stream = new MemoryStream(); variantType = VT_NULL; } else { throw new InvalidOperationException(Res.GetString(Res.InvalidTypeSerialization)); } message.BodyStream = stream; message.BodyType = variantType; } [ComVisible(false)] private class ComStreamFromDataStream : IStream { private Stream dataStream; // to support seeking ahead of the stream length... private long virtualPosition = -1; public ComStreamFromDataStream(Stream dataStream) { if (dataStream == null) throw new ArgumentNullException("dataStream"); this.dataStream = dataStream; } private void ActualizeVirtualPosition() { if (virtualPosition == -1) return; if (virtualPosition > dataStream.Length) dataStream.SetLength(virtualPosition); dataStream.Position = virtualPosition; virtualPosition = -1; } public IStream Clone() { NotImplemented(); return null; } public void Commit(int grfCommitFlags) { dataStream.Flush(); // Extend the length of the file if needed. ActualizeVirtualPosition(); } public long CopyTo(IStream pstm, long cb, long[] pcbRead) { int bufSize = 4096; IntPtr buffer = Marshal.AllocHGlobal((IntPtr)bufSize); if (buffer == IntPtr.Zero) throw new OutOfMemoryException(); long written = 0; try { while (written < cb) { int toRead = bufSize; if (written + toRead > cb) toRead = (int) (cb - written); int read = Read(buffer, toRead); if (read == 0) break; if (pstm.Write(buffer, read) != read) { throw EFail(Res.GetString(Res.IncorrectNumberOfBytes)); } written += read; } } finally { Marshal.FreeHGlobal(buffer); } if (pcbRead != null && pcbRead.Length > 0) { pcbRead[0] = written; } return written; } public Stream GetDataStream() { return dataStream; } public void LockRegion(long libOffset, long cb, int dwLockType) { } protected static ExternalException EFail(string msg) { ExternalException e = new ExternalException(msg, NativeMethods.E_FAIL); throw e; } protected static void NotImplemented() { ExternalException e = new ExternalException(Res.GetString(Res.NotImplemented), NativeMethods.E_NOTIMPL); throw e; } public int Read(IntPtr buf, int length) { byte[] buffer = new byte[length]; int count = Read(buffer, length); Marshal.Copy(buffer, 0, buf, length); return count; } public int Read(byte[] buffer, int length) { ActualizeVirtualPosition(); return dataStream.Read(buffer, 0, length); } public void Revert() { NotImplemented(); } public long Seek(long offset, int origin) { long pos = virtualPosition; if (virtualPosition == -1) { pos = dataStream.Position; } long len = dataStream.Length; switch (origin) { case NativeMethods.STREAM_SEEK_SET: if (offset <= len) { dataStream.Position = offset; virtualPosition = -1; } else { virtualPosition = offset; } break; case NativeMethods.STREAM_SEEK_END: if (offset <= 0) { dataStream.Position = len + offset; virtualPosition = -1; } else { virtualPosition = len + offset; } break; case NativeMethods.STREAM_SEEK_CUR: if (offset+pos <= len) { dataStream.Position = pos + offset; virtualPosition = -1; } else { virtualPosition = offset + pos; } break; } if (virtualPosition != -1) { return virtualPosition; } else { return dataStream.Position; } } public void SetSize(long value) { dataStream.SetLength(value); } public void Stat(IntPtr pstatstg, int grfStatFlag) { // GpStream has a partial implementation, but it's so partial rather // restrict it to use with GDI+ NotImplemented(); } public void UnlockRegion(long libOffset, long cb, int dwLockType) { } public int Write(IntPtr buf, int length) { byte[] buffer = new byte[length]; Marshal.Copy(buf, buffer, 0, length); return Write(buffer, length); } public int Write(byte[] buffer, int length) { ActualizeVirtualPosition(); dataStream.Write(buffer, 0, length); return length; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Messaging { using System.Runtime.Serialization.Formatters; using System.Runtime.InteropServices; using System.Text; using System.Runtime.Serialization; using System.Diagnostics; using System; using System.IO; using System.Globalization; using System.ComponentModel; using System.Messaging.Interop; ////// /// public class ActiveXMessageFormatter : IMessageFormatter { internal const short VT_ARRAY = 0x2000; internal const short VT_BOOL = 11; internal const short VT_BSTR = 8; internal const short VT_CLSID = 72; internal const short VT_CY = 6; internal const short VT_DATE = 7; internal const short VT_I1 = 16; internal const short VT_I2 = 2; internal const short VT_I4 = 3; internal const short VT_I8 = 20; internal const short VT_LPSTR = 30; internal const short VT_LPWSTR = 31; internal const short VT_NULL = 1; internal const short VT_R4 = 4; internal const short VT_R8 = 5; internal const short VT_STREAMED_OBJECT = 68; internal const short VT_STORED_OBJECT = 69; internal const short VT_UI1 = 17; internal const short VT_UI2 = 18; internal const short VT_UI4 = 19; internal const short VT_UI8 = 21; internal const short VT_VECTOR = 0x1000; private byte[] internalBuffer; private UnicodeEncoding unicodeEncoding; private ASCIIEncoding asciiEncoding; private char[] internalCharBuffer; ////// Formatter class that serializes and deserializes /// primitives, classes, enumeration, and other objects into and from ////// messages using binary format. /// /// /// When this method is called, the formatter will attempt to determine /// if the contents of the message are something the formatter can deal with. /// public bool CanRead(Message message) { if (message == null) throw new ArgumentNullException("message"); int variantType = message.BodyType; if (variantType != VT_BOOL && variantType != VT_CLSID && variantType != VT_CY && variantType != VT_DATE && variantType != VT_I1 && variantType != VT_UI1 && variantType != VT_I2 && variantType != VT_UI2 && variantType != VT_I4 && variantType != VT_UI4 && variantType != VT_I8 && variantType != VT_UI8 && variantType != VT_NULL && variantType != VT_R4 && variantType != VT_I8 && variantType != VT_STREAMED_OBJECT && variantType != VT_STORED_OBJECT && variantType != (VT_VECTOR | VT_UI1) && variantType != VT_LPSTR && variantType != VT_LPWSTR && variantType != VT_BSTR && variantType != VT_R8) return false; return true; } ////// /// This method is needed to improve scalability on Receive and ReceiveAsync scenarios. Not requiring /// thread safety on read and write. /// public object Clone() { return new ActiveXMessageFormatter(); } ////// /// public static void InitStreamedObject(object streamedObject) { IPersistStreamInit persistStreamInit = streamedObject as IPersistStreamInit; if (persistStreamInit != null) persistStreamInit.InitNew(); } ///[To be supplied.] ////// /// This method is used to read the contents from the given message /// and create an object. /// public object Read(Message message) { if (message == null) throw new ArgumentNullException("message"); Stream stream; byte[] bytes; byte[] newBytes; int size; int variantType = message.BodyType; switch (variantType) { case VT_LPSTR: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); size = message.properties.GetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE); if (this.internalCharBuffer == null || this.internalCharBuffer.Length < size) this.internalCharBuffer = new char[size]; if (asciiEncoding == null) this.asciiEncoding = new ASCIIEncoding(); this.asciiEncoding.GetChars(bytes, 0, size, this.internalCharBuffer, 0); return new String(this.internalCharBuffer, 0, size); case VT_BSTR: case VT_LPWSTR: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); size = message.properties.GetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE) / 2; if (this.internalCharBuffer == null || this.internalCharBuffer.Length < size) this.internalCharBuffer = new char[size]; if (unicodeEncoding == null) this.unicodeEncoding = new UnicodeEncoding(); this.unicodeEncoding.GetChars(bytes, 0, size * 2, this.internalCharBuffer, 0); return new String(this.internalCharBuffer, 0, size); case VT_VECTOR | VT_UI1: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); size = message.properties.GetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE); newBytes = new byte[size]; Array.Copy(bytes, newBytes, size); return newBytes; case VT_BOOL: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[1]; Array.Copy(bytes, newBytes, 1); if (bytes[0] != 0) return true; return false; case VT_CLSID: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[16]; Array.Copy(bytes, newBytes, 16); return new Guid(newBytes); case VT_CY: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[8]; Array.Copy(bytes, newBytes, 8); return Decimal.FromOACurrency(BitConverter.ToInt64(newBytes, 0)); case VT_DATE: bytes = message.properties.GetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY); newBytes = new byte[8]; Array.Copy(bytes, newBytes, 8); return new DateTime(BitConverter.ToInt64(newBytes, 0)); case VT_I1: case VT_UI1: stream = message.BodyStream; bytes = new byte[1]; stream.Read(bytes, 0, 1); return bytes[0]; case VT_I2: stream = message.BodyStream; bytes = new byte[2]; stream.Read(bytes, 0, 2); return BitConverter.ToInt16(bytes, 0); case VT_UI2: stream = message.BodyStream; bytes = new byte[2]; stream.Read(bytes, 0, 2); return BitConverter.ToUInt16(bytes, 0); case VT_I4: stream = message.BodyStream; bytes = new byte[4]; stream.Read(bytes, 0, 4); return BitConverter.ToInt32(bytes, 0); case VT_UI4: stream = message.BodyStream; bytes = new byte[4]; stream.Read(bytes, 0, 4); return BitConverter.ToUInt32(bytes, 0); case VT_I8: stream = message.BodyStream; bytes = new byte[8]; stream.Read(bytes, 0, 8); return BitConverter.ToInt64(bytes, 0); case VT_UI8: stream = message.BodyStream; bytes = new byte[8]; stream.Read(bytes, 0, 8); return BitConverter.ToUInt64(bytes, 0); case VT_R4: stream = message.BodyStream; bytes = new byte[4]; stream.Read(bytes, 0, 4); return BitConverter.ToSingle(bytes, 0); case VT_R8: stream = message.BodyStream; bytes = new byte[8]; stream.Read(bytes, 0, 8); return BitConverter.ToDouble(bytes, 0); case VT_NULL: return null; case VT_STREAMED_OBJECT: stream = message.BodyStream; ComStreamFromDataStream comStream = new ComStreamFromDataStream(stream); return NativeMethods.OleLoadFromStream(comStream, ref NativeMethods.IID_IUnknown); case VT_STORED_OBJECT: throw new NotSupportedException(Res.GetString(Res.StoredObjectsNotSupported)); default: throw new InvalidOperationException(Res.GetString(Res.InvalidTypeDeserialization)); } } ////// /// This method is used to write the given object into the given message. /// If the formatter cannot understand the given object, an exception is thrown. /// public void Write(Message message, object obj) { if (message == null) throw new ArgumentNullException("message"); Stream stream; int variantType; if (obj is string) { int size = ((string)obj).Length * 2; if (this.internalBuffer == null || this.internalBuffer.Length < size) this.internalBuffer = new byte[size]; if (unicodeEncoding == null) this.unicodeEncoding = new UnicodeEncoding(); this.unicodeEncoding.GetBytes(((string)obj).ToCharArray(), 0, size /2, this.internalBuffer, 0); message.properties.SetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY, this.internalBuffer); message.properties.AdjustSize(NativeMethods.MESSAGE_PROPID_BODY, size); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE, size); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_TYPE, VT_LPWSTR); return; } else if (obj is byte[]) { byte[] bytes = (byte[])obj; if (this.internalBuffer == null || this.internalBuffer.Length < bytes.Length) this.internalBuffer = new byte[bytes.Length]; Array.Copy(bytes, this.internalBuffer, bytes.Length); message.properties.SetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY, this.internalBuffer); message.properties.AdjustSize(NativeMethods.MESSAGE_PROPID_BODY, bytes.Length); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE, bytes.Length); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_TYPE, VT_UI1 | VT_VECTOR); return; } else if (obj is char[]) { char[] chars = (char[])obj; int size = chars.Length * 2; if (this.internalBuffer == null || this.internalBuffer.Length < size) this.internalBuffer = new byte[size]; if (unicodeEncoding == null) this.unicodeEncoding = new UnicodeEncoding(); this.unicodeEncoding.GetBytes(chars, 0, size /2, this.internalBuffer, 0); message.properties.SetUI1Vector(NativeMethods.MESSAGE_PROPID_BODY, this.internalBuffer); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_SIZE, size); message.properties.SetUI4(NativeMethods.MESSAGE_PROPID_BODY_TYPE, VT_LPWSTR); return; } else if (obj is byte) { stream = new MemoryStream(1); stream.Write(new byte[]{(byte)obj}, 0, 1); variantType = VT_UI1; } else if (obj is bool) { stream = new MemoryStream(1); if ((bool)obj) stream.Write(new byte[]{0xff}, 0, 1); else stream.Write(new byte[]{0x00}, 0, 1); variantType = VT_BOOL; } else if (obj is char) { stream = new MemoryStream(2); byte[] bytes = BitConverter.GetBytes((Char)obj); stream.Write(bytes, 0, 2); variantType = VT_UI2; } else if (obj is Decimal) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes(Decimal.ToOACurrency((Decimal)obj)); stream.Write(bytes, 0, 8); variantType = VT_CY; } else if (obj is DateTime) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes(((DateTime)obj).Ticks); stream.Write(bytes, 0, 8); variantType = VT_DATE; } else if (obj is Double) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes((Double)obj); stream.Write(bytes, 0, 8); variantType = VT_R8; } else if (obj is Int16) { stream = new MemoryStream(2); byte[] bytes = BitConverter.GetBytes((short)obj); stream.Write(bytes, 0, 2); variantType = VT_I2; } else if (obj is UInt16) { stream = new MemoryStream(2); byte[] bytes = BitConverter.GetBytes((UInt16)obj); stream.Write(bytes, 0, 2); variantType = VT_UI2; } else if (obj is Int32) { stream = new MemoryStream(4); byte[] bytes = BitConverter.GetBytes((int)obj); stream.Write(bytes, 0, 4); variantType = VT_I4; } else if (obj is UInt32) { stream = new MemoryStream(4); byte[] bytes = BitConverter.GetBytes((UInt32)obj); stream.Write(bytes, 0, 4); variantType = VT_UI4; } else if (obj is Int64) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes((Int64)obj); stream.Write(bytes, 0, 8); variantType = VT_I8; } else if (obj is UInt64) { stream = new MemoryStream(8); byte[] bytes = BitConverter.GetBytes((UInt64)obj); stream.Write(bytes, 0, 8); variantType = VT_UI8; } else if (obj is Single) { stream = new MemoryStream(4); byte[] bytes = BitConverter.GetBytes((float)obj); stream.Write(bytes, 0, 4); variantType = VT_R4; } else if (obj is IPersistStream) { IPersistStream pstream = (IPersistStream) obj; ComStreamFromDataStream comStream = new ComStreamFromDataStream(new MemoryStream()); NativeMethods.OleSaveToStream(pstream, comStream); stream = comStream.GetDataStream(); variantType = VT_STREAMED_OBJECT; } else if (obj == null) { stream = new MemoryStream(); variantType = VT_NULL; } else { throw new InvalidOperationException(Res.GetString(Res.InvalidTypeSerialization)); } message.BodyStream = stream; message.BodyType = variantType; } [ComVisible(false)] private class ComStreamFromDataStream : IStream { private Stream dataStream; // to support seeking ahead of the stream length... private long virtualPosition = -1; public ComStreamFromDataStream(Stream dataStream) { if (dataStream == null) throw new ArgumentNullException("dataStream"); this.dataStream = dataStream; } private void ActualizeVirtualPosition() { if (virtualPosition == -1) return; if (virtualPosition > dataStream.Length) dataStream.SetLength(virtualPosition); dataStream.Position = virtualPosition; virtualPosition = -1; } public IStream Clone() { NotImplemented(); return null; } public void Commit(int grfCommitFlags) { dataStream.Flush(); // Extend the length of the file if needed. ActualizeVirtualPosition(); } public long CopyTo(IStream pstm, long cb, long[] pcbRead) { int bufSize = 4096; IntPtr buffer = Marshal.AllocHGlobal((IntPtr)bufSize); if (buffer == IntPtr.Zero) throw new OutOfMemoryException(); long written = 0; try { while (written < cb) { int toRead = bufSize; if (written + toRead > cb) toRead = (int) (cb - written); int read = Read(buffer, toRead); if (read == 0) break; if (pstm.Write(buffer, read) != read) { throw EFail(Res.GetString(Res.IncorrectNumberOfBytes)); } written += read; } } finally { Marshal.FreeHGlobal(buffer); } if (pcbRead != null && pcbRead.Length > 0) { pcbRead[0] = written; } return written; } public Stream GetDataStream() { return dataStream; } public void LockRegion(long libOffset, long cb, int dwLockType) { } protected static ExternalException EFail(string msg) { ExternalException e = new ExternalException(msg, NativeMethods.E_FAIL); throw e; } protected static void NotImplemented() { ExternalException e = new ExternalException(Res.GetString(Res.NotImplemented), NativeMethods.E_NOTIMPL); throw e; } public int Read(IntPtr buf, int length) { byte[] buffer = new byte[length]; int count = Read(buffer, length); Marshal.Copy(buffer, 0, buf, length); return count; } public int Read(byte[] buffer, int length) { ActualizeVirtualPosition(); return dataStream.Read(buffer, 0, length); } public void Revert() { NotImplemented(); } public long Seek(long offset, int origin) { long pos = virtualPosition; if (virtualPosition == -1) { pos = dataStream.Position; } long len = dataStream.Length; switch (origin) { case NativeMethods.STREAM_SEEK_SET: if (offset <= len) { dataStream.Position = offset; virtualPosition = -1; } else { virtualPosition = offset; } break; case NativeMethods.STREAM_SEEK_END: if (offset <= 0) { dataStream.Position = len + offset; virtualPosition = -1; } else { virtualPosition = len + offset; } break; case NativeMethods.STREAM_SEEK_CUR: if (offset+pos <= len) { dataStream.Position = pos + offset; virtualPosition = -1; } else { virtualPosition = offset + pos; } break; } if (virtualPosition != -1) { return virtualPosition; } else { return dataStream.Position; } } public void SetSize(long value) { dataStream.SetLength(value); } public void Stat(IntPtr pstatstg, int grfStatFlag) { // GpStream has a partial implementation, but it's so partial rather // restrict it to use with GDI+ NotImplemented(); } public void UnlockRegion(long libOffset, long cb, int dwLockType) { } public int Write(IntPtr buf, int length) { byte[] buffer = new byte[length]; Marshal.Copy(buf, buffer, 0, length); return Write(buffer, length); } public int Write(byte[] buffer, int length) { ActualizeVirtualPosition(); dataStream.Write(buffer, 0, length); return length; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PropertyTabAttribute.cs
- RangeBase.cs
- PackagePartCollection.cs
- XmlSerializationWriter.cs
- TemplateControl.cs
- Environment.cs
- ObjectStateManagerMetadata.cs
- Debugger.cs
- ChannelSinkStacks.cs
- SecurityContext.cs
- NetWebProxyFinder.cs
- _KerberosClient.cs
- DecimalAnimationBase.cs
- DynamicValueConverter.cs
- TransformerConfigurationWizardBase.cs
- Bitmap.cs
- CommandLineParser.cs
- HttpRuntimeSection.cs
- Rules.cs
- ReadWriteObjectLock.cs
- XmlTypeMapping.cs
- SiteMapPathDesigner.cs
- UpdateTranslator.cs
- MachineKey.cs
- IsolatedStorageFileStream.cs
- DataGridItemCollection.cs
- PathSegmentCollection.cs
- QilFactory.cs
- TraceUtility.cs
- CheckPair.cs
- ApplicationFileParser.cs
- XmlSchemaImporter.cs
- _ContextAwareResult.cs
- KeyEvent.cs
- ServiceHttpHandlerFactory.cs
- ComponentCollection.cs
- BitmapSourceSafeMILHandle.cs
- XslException.cs
- GotoExpression.cs
- VisualStateGroup.cs
- AssemblyNameProxy.cs
- DataServiceQuery.cs
- DetailsViewCommandEventArgs.cs
- SQLSingle.cs
- CodeLinePragma.cs
- RoleGroupCollection.cs
- GatewayDefinition.cs
- WmpBitmapEncoder.cs
- PerfCounters.cs
- RangeValuePatternIdentifiers.cs
- Deserializer.cs
- List.cs
- ControlIdConverter.cs
- DefaultShape.cs
- UrlMappingCollection.cs
- counter.cs
- OptimisticConcurrencyException.cs
- FramingFormat.cs
- glyphs.cs
- Visitors.cs
- ValueUtilsSmi.cs
- OdbcFactory.cs
- Timer.cs
- NativeMethodsOther.cs
- ClientConfigPaths.cs
- Int32Converter.cs
- RewritingProcessor.cs
- TcpAppDomainProtocolHandler.cs
- ListenerElementsCollection.cs
- InternalsVisibleToAttribute.cs
- WebPartEditVerb.cs
- WebBrowserNavigatedEventHandler.cs
- Parser.cs
- MouseDevice.cs
- XmlSchemaValidationException.cs
- Triplet.cs
- _Semaphore.cs
- PriorityQueue.cs
- EventBookmark.cs
- EventManager.cs
- EventsTab.cs
- KnownColorTable.cs
- PagedDataSource.cs
- ContainerParaClient.cs
- CryptoHelper.cs
- BaseTemplateParser.cs
- OleDbTransaction.cs
- Size.cs
- PropertyPathConverter.cs
- DataProtection.cs
- DataGridViewCheckBoxColumn.cs
- Size.cs
- ArrayList.cs
- DependencyPropertyConverter.cs
- DataGridViewAutoSizeColumnsModeEventArgs.cs
- Rectangle.cs
- DispatcherSynchronizationContext.cs
- CodeTypeDeclarationCollection.cs
- TrustExchangeException.cs
- Wizard.cs