Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Data / System / Data / ProviderBase / DbBuffer.cs / 1305376 / DbBuffer.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.ProviderBase { using System; using System.Data.Common; #if ORACLE using System.Data.OracleClient; #endif // ORACLE using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Threading; // DbBuffer is abstract to require derived class to exist // so that when debugging, we can tell the difference between one DbBuffer and another internal abstract class DbBuffer : SafeHandle { internal const int LMEM_FIXED = 0x0000; internal const int LMEM_MOVEABLE = 0x0002; internal const int LMEM_ZEROINIT = 0x0040; private readonly int _bufferLength; #if ORACLE private int _baseOffset; #endif #if ORACLE protected #else private #endif DbBuffer(int initialSize, bool zeroBuffer) : base(IntPtr.Zero, true) { if (0 < initialSize) { int flags = ((zeroBuffer) ? LMEM_ZEROINIT : LMEM_FIXED); _bufferLength = initialSize; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { base.handle = SafeNativeMethods.LocalAlloc(flags, (IntPtr)initialSize); } if (IntPtr.Zero == base.handle) { throw new OutOfMemoryException(); } } } protected DbBuffer(int initialSize) : this(initialSize, true) { } #if !ORACLE protected DbBuffer(IntPtr invalidHandleValue, bool ownsHandle) : base(invalidHandleValue, ownsHandle) { } private int BaseOffset { get { return 0; } } #else protected int BaseOffset { get { return _baseOffset; } set { _baseOffset = value; } } #endif public override bool IsInvalid { get { return (IntPtr.Zero == base.handle); } } internal int Length { get { return _bufferLength; } } internal string PtrToStringUni(int offset) { offset += BaseOffset; Validate(offset, 2); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); string value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); int length = UnsafeNativeMethods.lstrlenW(ptr); Validate(offset, (2*(length+1))); value = Marshal.PtrToStringUni(ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } return value; } internal String PtrToStringUni(int offset, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); string value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); value = Marshal.PtrToStringUni(ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal byte ReadByte(int offset) { offset += BaseOffset; ValidateCheck(offset, 1); Debug.Assert(0 == offset%4, "invalid alignment"); byte value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadByte(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #endif internal byte[] ReadBytes(int offset, int length) { byte[] value = new byte[length]; return ReadBytes(offset, value, 0, length); } internal byte[] ReadBytes(int offset, byte[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } return destination; } #if !ORACLE internal Char ReadChar(int offset) { short value = ReadInt16(offset); return unchecked((char)value); } internal char[] ReadChars(int offset, char[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } return destination; } internal Double ReadDouble(int offset) { Int64 value = ReadInt64(offset); return BitConverter.Int64BitsToDouble(value); } #endif internal Int16 ReadInt16(int offset) { offset += BaseOffset; ValidateCheck(offset, 2); Debug.Assert(0 == offset%2, "invalid alignment"); short value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadInt16(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal void ReadInt16Array(int offset, short[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal Int32 ReadInt32(int offset) { offset += BaseOffset; ValidateCheck(offset, 4); Debug.Assert(0 == offset%4, "invalid alignment"); int value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadInt32(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal void ReadInt32Array(int offset, int[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, 4*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } } internal Int64 ReadInt64(int offset) { offset += BaseOffset; ValidateCheck(offset, 8); Debug.Assert(0 == offset%IntPtr.Size, "invalid alignment"); long value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadInt64(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #endif internal IntPtr ReadIntPtr(int offset) { offset += BaseOffset; ValidateCheck(offset, IntPtr.Size); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); IntPtr value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadIntPtr(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal unsafe Single ReadSingle(int offset) { Int32 value = ReadInt32(offset); return *(Single*)&value; } #endif override protected bool ReleaseHandle() { // NOTE: The SafeHandle class guarantees this will be called exactly once. IntPtr ptr = base.handle; base.handle = IntPtr.Zero; if (IntPtr.Zero != ptr) { SafeNativeMethods.LocalFree(ptr); } return true; } #if ORACLE internal #else private #endif void StructureToPtr(int offset, object structure) { Debug.Assert(null != structure, "null structure"); offset += BaseOffset; ValidateCheck(offset, Marshal.SizeOf(structure.GetType())); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.StructureToPtr(structure, ptr, false/*fDeleteOld*/); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteByte(int offset, byte value) { offset += BaseOffset; ValidateCheck(offset, 1); Debug.Assert(0 == offset%4, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteByte(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal void WriteBytes(int offset, byte[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteCharArray(int offset, char[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } internal void WriteDouble(int offset, Double value) { WriteInt64(offset, BitConverter.DoubleToInt64Bits(value)); } #endif internal void WriteInt16(int offset, short value) { offset += BaseOffset; ValidateCheck(offset, 2); Debug.Assert(0 == offset%2, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteInt16(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteInt16Array(int offset, short[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal void WriteInt32(int offset, int value) { offset += BaseOffset; ValidateCheck(offset, 4); Debug.Assert(0 == offset%4, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteInt32(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteInt32Array(int offset, int[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, 4*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } internal void WriteInt64(int offset, long value) { offset += BaseOffset; ValidateCheck(offset, 8); Debug.Assert(0 == offset%IntPtr.Size, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteInt64(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal void WriteIntPtr(int offset, IntPtr value) { offset += BaseOffset; ValidateCheck(offset, IntPtr.Size); Debug.Assert(0 == offset%IntPtr.Size, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteIntPtr(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal unsafe void WriteSingle(int offset, Single value) { WriteInt32(offset, *(Int32*)&value); } internal void ZeroMemory() { bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); SafeNativeMethods.ZeroMemory(ptr, (IntPtr)Length); } finally { if (mustRelease) { DangerousRelease(); } } } internal Guid ReadGuid(int offset) { // faster than Marshal.PtrToStructure(offset, typeof(Guid)) byte[] buffer = new byte[16]; ReadBytes(offset, buffer, 0, 16); return new Guid(buffer); } internal void WriteGuid(int offset, Guid value) { // faster than Marshal.Copy(value.GetByteArray() StructureToPtr(offset, value); } internal DateTime ReadDate(int offset) { short[] buffer = new short[3]; ReadInt16Array(offset, buffer, 0, 3); return new DateTime( unchecked((ushort)buffer[0]), // Year unchecked((ushort)buffer[1]), // Month unchecked((ushort)buffer[2])); // Day } internal void WriteDate(int offset, DateTime value) { short[] buffer = new short[3] { unchecked((short)value.Year), unchecked((short)value.Month), unchecked((short)value.Day), }; WriteInt16Array(offset, buffer, 0, 3); } internal TimeSpan ReadTime(int offset) { short[] buffer = new short[3]; ReadInt16Array(offset, buffer, 0, 3); return new TimeSpan( unchecked((ushort)buffer[0]), // Hours unchecked((ushort)buffer[1]), // Minutes unchecked((ushort)buffer[2])); // Seconds } internal void WriteTime(int offset, TimeSpan value) { short[] buffer = new short[3] { unchecked((short)value.Hours), unchecked((short)value.Minutes), unchecked((short)value.Seconds), }; WriteInt16Array(offset, buffer, 0, 3); } internal DateTime ReadDateTime(int offset) { short[] buffer = new short[6]; ReadInt16Array(offset, buffer, 0, 6); int ticks = ReadInt32(offset + 12); DateTime value = new DateTime( unchecked((ushort)buffer[0]), // Year unchecked((ushort)buffer[1]), // Month unchecked((ushort)buffer[2]), // Day unchecked((ushort)buffer[3]), // Hours unchecked((ushort)buffer[4]), // Minutes unchecked((ushort)buffer[5])); // Seconds return value.AddTicks(ticks / 100); } internal void WriteDateTime(int offset, DateTime value) { int ticks = (int)(value.Ticks % 10000000L)*100; short[] buffer = new short[6] { unchecked((short)value.Year), unchecked((short)value.Month), unchecked((short)value.Day), unchecked((short)value.Hour), unchecked((short)value.Minute), unchecked((short)value.Second), }; WriteInt16Array(offset, buffer, 0, 6); WriteInt32(offset + 12, ticks); } internal Decimal ReadNumeric(int offset) { byte[] bits = new byte[20]; ReadBytes(offset, bits, 1, 19); int[] buffer = new int[4]; buffer[3] = ((int) bits[2]) << 16; // scale if (0 == bits[3]) { buffer[3] |= unchecked((int)0x80000000); //sign } buffer[0] = BitConverter.ToInt32(bits, 4); // low buffer[1] = BitConverter.ToInt32(bits, 8); // mid buffer[2] = BitConverter.ToInt32(bits, 12); // high if (0 != BitConverter.ToInt32(bits, 16)) { throw ADP.NumericToDecimalOverflow(); } return new Decimal(buffer); } internal void WriteNumeric(int offset, Decimal value, byte precision) { int[] tmp = Decimal.GetBits(value); byte[] buffer = new byte[20]; buffer[1] = precision; Buffer.BlockCopy(tmp, 14, buffer, 2, 2); // copy sign and scale buffer[3] = (Byte) ((0 == buffer[3]) ? 1 : 0); // flip sign for native Buffer.BlockCopy(tmp, 0, buffer, 4, 12); buffer[16] = 0; buffer[17] = 0; buffer[18] = 0; buffer[19] = 0; WriteBytes(offset, buffer, 1, 19); } #endif [ConditionalAttribute("DEBUG")] protected void ValidateCheck(int offset, int count) { Validate(offset, count); } protected void Validate(int offset, int count) { if ((offset < 0) || (count < 0) || (Length < checked(offset + count))) { throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer); } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.ProviderBase { using System; using System.Data.Common; #if ORACLE using System.Data.OracleClient; #endif // ORACLE using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security; using System.Security.Permissions; using System.Threading; // DbBuffer is abstract to require derived class to exist // so that when debugging, we can tell the difference between one DbBuffer and another internal abstract class DbBuffer : SafeHandle { internal const int LMEM_FIXED = 0x0000; internal const int LMEM_MOVEABLE = 0x0002; internal const int LMEM_ZEROINIT = 0x0040; private readonly int _bufferLength; #if ORACLE private int _baseOffset; #endif #if ORACLE protected #else private #endif DbBuffer(int initialSize, bool zeroBuffer) : base(IntPtr.Zero, true) { if (0 < initialSize) { int flags = ((zeroBuffer) ? LMEM_ZEROINIT : LMEM_FIXED); _bufferLength = initialSize; RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { base.handle = SafeNativeMethods.LocalAlloc(flags, (IntPtr)initialSize); } if (IntPtr.Zero == base.handle) { throw new OutOfMemoryException(); } } } protected DbBuffer(int initialSize) : this(initialSize, true) { } #if !ORACLE protected DbBuffer(IntPtr invalidHandleValue, bool ownsHandle) : base(invalidHandleValue, ownsHandle) { } private int BaseOffset { get { return 0; } } #else protected int BaseOffset { get { return _baseOffset; } set { _baseOffset = value; } } #endif public override bool IsInvalid { get { return (IntPtr.Zero == base.handle); } } internal int Length { get { return _bufferLength; } } internal string PtrToStringUni(int offset) { offset += BaseOffset; Validate(offset, 2); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); string value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); int length = UnsafeNativeMethods.lstrlenW(ptr); Validate(offset, (2*(length+1))); value = Marshal.PtrToStringUni(ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } return value; } internal String PtrToStringUni(int offset, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); string value = null; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); value = Marshal.PtrToStringUni(ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal byte ReadByte(int offset) { offset += BaseOffset; ValidateCheck(offset, 1); Debug.Assert(0 == offset%4, "invalid alignment"); byte value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadByte(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #endif internal byte[] ReadBytes(int offset, int length) { byte[] value = new byte[length]; return ReadBytes(offset, value, 0, length); } internal byte[] ReadBytes(int offset, byte[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } return destination; } #if !ORACLE internal Char ReadChar(int offset) { short value = ReadInt16(offset); return unchecked((char)value); } internal char[] ReadChars(int offset, char[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } return destination; } internal Double ReadDouble(int offset) { Int64 value = ReadInt64(offset); return BitConverter.Int64BitsToDouble(value); } #endif internal Int16 ReadInt16(int offset) { offset += BaseOffset; ValidateCheck(offset, 2); Debug.Assert(0 == offset%2, "invalid alignment"); short value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadInt16(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal void ReadInt16Array(int offset, short[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal Int32 ReadInt32(int offset) { offset += BaseOffset; ValidateCheck(offset, 4); Debug.Assert(0 == offset%4, "invalid alignment"); int value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadInt32(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal void ReadInt32Array(int offset, int[] destination, int startIndex, int length) { offset += BaseOffset; Validate(offset, 4*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != destination, "null destination"); Debug.Assert(startIndex + length <= destination.Length, "destination too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(ptr, destination, startIndex, length); } finally { if (mustRelease) { DangerousRelease(); } } } internal Int64 ReadInt64(int offset) { offset += BaseOffset; ValidateCheck(offset, 8); Debug.Assert(0 == offset%IntPtr.Size, "invalid alignment"); long value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadInt64(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #endif internal IntPtr ReadIntPtr(int offset) { offset += BaseOffset; ValidateCheck(offset, IntPtr.Size); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); IntPtr value; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); value = Marshal.ReadIntPtr(ptr, offset); } finally { if (mustRelease) { DangerousRelease(); } } return value; } #if !ORACLE internal unsafe Single ReadSingle(int offset) { Int32 value = ReadInt32(offset); return *(Single*)&value; } #endif override protected bool ReleaseHandle() { // NOTE: The SafeHandle class guarantees this will be called exactly once. IntPtr ptr = base.handle; base.handle = IntPtr.Zero; if (IntPtr.Zero != ptr) { SafeNativeMethods.LocalFree(ptr); } return true; } #if ORACLE internal #else private #endif void StructureToPtr(int offset, object structure) { Debug.Assert(null != structure, "null structure"); offset += BaseOffset; ValidateCheck(offset, Marshal.SizeOf(structure.GetType())); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.StructureToPtr(structure, ptr, false/*fDeleteOld*/); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteByte(int offset, byte value) { offset += BaseOffset; ValidateCheck(offset, 1); Debug.Assert(0 == offset%4, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteByte(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal void WriteBytes(int offset, byte[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteCharArray(int offset, char[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } internal void WriteDouble(int offset, Double value) { WriteInt64(offset, BitConverter.DoubleToInt64Bits(value)); } #endif internal void WriteInt16(int offset, short value) { offset += BaseOffset; ValidateCheck(offset, 2); Debug.Assert(0 == offset%2, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteInt16(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteInt16Array(int offset, short[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, 2*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal void WriteInt32(int offset, int value) { offset += BaseOffset; ValidateCheck(offset, 4); Debug.Assert(0 == offset%4, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteInt32(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal void WriteInt32Array(int offset, int[] source, int startIndex, int length) { offset += BaseOffset; Validate(offset, 4*length); Debug.Assert(0 == offset%ADP.PtrSize, "invalid alignment"); Debug.Assert(null != source, "null source"); Debug.Assert(startIndex + length <= source.Length, "source too small"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = ADP.IntPtrOffset(DangerousGetHandle(), offset); Marshal.Copy(source, startIndex, ptr, length); } finally { if (mustRelease) { DangerousRelease(); } } } internal void WriteInt64(int offset, long value) { offset += BaseOffset; ValidateCheck(offset, 8); Debug.Assert(0 == offset%IntPtr.Size, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteInt64(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #endif internal void WriteIntPtr(int offset, IntPtr value) { offset += BaseOffset; ValidateCheck(offset, IntPtr.Size); Debug.Assert(0 == offset%IntPtr.Size, "invalid alignment"); bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); Marshal.WriteIntPtr(ptr, offset, value); } finally { if (mustRelease) { DangerousRelease(); } } } #if !ORACLE internal unsafe void WriteSingle(int offset, Single value) { WriteInt32(offset, *(Int32*)&value); } internal void ZeroMemory() { bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); IntPtr ptr = DangerousGetHandle(); SafeNativeMethods.ZeroMemory(ptr, (IntPtr)Length); } finally { if (mustRelease) { DangerousRelease(); } } } internal Guid ReadGuid(int offset) { // faster than Marshal.PtrToStructure(offset, typeof(Guid)) byte[] buffer = new byte[16]; ReadBytes(offset, buffer, 0, 16); return new Guid(buffer); } internal void WriteGuid(int offset, Guid value) { // faster than Marshal.Copy(value.GetByteArray() StructureToPtr(offset, value); } internal DateTime ReadDate(int offset) { short[] buffer = new short[3]; ReadInt16Array(offset, buffer, 0, 3); return new DateTime( unchecked((ushort)buffer[0]), // Year unchecked((ushort)buffer[1]), // Month unchecked((ushort)buffer[2])); // Day } internal void WriteDate(int offset, DateTime value) { short[] buffer = new short[3] { unchecked((short)value.Year), unchecked((short)value.Month), unchecked((short)value.Day), }; WriteInt16Array(offset, buffer, 0, 3); } internal TimeSpan ReadTime(int offset) { short[] buffer = new short[3]; ReadInt16Array(offset, buffer, 0, 3); return new TimeSpan( unchecked((ushort)buffer[0]), // Hours unchecked((ushort)buffer[1]), // Minutes unchecked((ushort)buffer[2])); // Seconds } internal void WriteTime(int offset, TimeSpan value) { short[] buffer = new short[3] { unchecked((short)value.Hours), unchecked((short)value.Minutes), unchecked((short)value.Seconds), }; WriteInt16Array(offset, buffer, 0, 3); } internal DateTime ReadDateTime(int offset) { short[] buffer = new short[6]; ReadInt16Array(offset, buffer, 0, 6); int ticks = ReadInt32(offset + 12); DateTime value = new DateTime( unchecked((ushort)buffer[0]), // Year unchecked((ushort)buffer[1]), // Month unchecked((ushort)buffer[2]), // Day unchecked((ushort)buffer[3]), // Hours unchecked((ushort)buffer[4]), // Minutes unchecked((ushort)buffer[5])); // Seconds return value.AddTicks(ticks / 100); } internal void WriteDateTime(int offset, DateTime value) { int ticks = (int)(value.Ticks % 10000000L)*100; short[] buffer = new short[6] { unchecked((short)value.Year), unchecked((short)value.Month), unchecked((short)value.Day), unchecked((short)value.Hour), unchecked((short)value.Minute), unchecked((short)value.Second), }; WriteInt16Array(offset, buffer, 0, 6); WriteInt32(offset + 12, ticks); } internal Decimal ReadNumeric(int offset) { byte[] bits = new byte[20]; ReadBytes(offset, bits, 1, 19); int[] buffer = new int[4]; buffer[3] = ((int) bits[2]) << 16; // scale if (0 == bits[3]) { buffer[3] |= unchecked((int)0x80000000); //sign } buffer[0] = BitConverter.ToInt32(bits, 4); // low buffer[1] = BitConverter.ToInt32(bits, 8); // mid buffer[2] = BitConverter.ToInt32(bits, 12); // high if (0 != BitConverter.ToInt32(bits, 16)) { throw ADP.NumericToDecimalOverflow(); } return new Decimal(buffer); } internal void WriteNumeric(int offset, Decimal value, byte precision) { int[] tmp = Decimal.GetBits(value); byte[] buffer = new byte[20]; buffer[1] = precision; Buffer.BlockCopy(tmp, 14, buffer, 2, 2); // copy sign and scale buffer[3] = (Byte) ((0 == buffer[3]) ? 1 : 0); // flip sign for native Buffer.BlockCopy(tmp, 0, buffer, 4, 12); buffer[16] = 0; buffer[17] = 0; buffer[18] = 0; buffer[19] = 0; WriteBytes(offset, buffer, 1, 19); } #endif [ConditionalAttribute("DEBUG")] protected void ValidateCheck(int offset, int count) { Validate(offset, count); } protected void Validate(int offset, int count) { if ((offset < 0) || (count < 0) || (Length < checked(offset + count))) { throw ADP.InternalError(ADP.InternalErrorCode.InvalidBuffer); } } } } // 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
- InkCanvasFeedbackAdorner.cs
- SoapExtension.cs
- TextEditorTables.cs
- CloudCollection.cs
- PnrpPermission.cs
- SqlCacheDependencySection.cs
- SoapIgnoreAttribute.cs
- ManifestResourceInfo.cs
- DesignParameter.cs
- SafeLibraryHandle.cs
- PageAsyncTask.cs
- DelegateHelpers.Generated.cs
- SQLResource.cs
- WebPartConnectionsCloseVerb.cs
- LeftCellWrapper.cs
- StylusTip.cs
- PersonalizationAdministration.cs
- CompoundFileReference.cs
- LinkButton.cs
- TreeNodeBinding.cs
- WebReferencesBuildProvider.cs
- NestedContainer.cs
- URIFormatException.cs
- AdRotator.cs
- CodeVariableDeclarationStatement.cs
- Error.cs
- Inflater.cs
- SHA256.cs
- OptimalBreakSession.cs
- SpeakProgressEventArgs.cs
- StoreItemCollection.cs
- IntSecurity.cs
- SafeRegistryHandle.cs
- AppDomainProtocolHandler.cs
- SQLMoney.cs
- WindowsPen.cs
- _ListenerResponseStream.cs
- COM2IVsPerPropertyBrowsingHandler.cs
- XmlDataSource.cs
- Journal.cs
- IPHostEntry.cs
- graph.cs
- XmlUnspecifiedAttribute.cs
- XpsFilter.cs
- StreamGeometryContext.cs
- EventHandlersStore.cs
- relpropertyhelper.cs
- FSWPathEditor.cs
- DataGridAutoFormatDialog.cs
- FilterEventArgs.cs
- CookieParameter.cs
- DependencyPropertyConverter.cs
- HtmlAnchor.cs
- DataGridViewCellValidatingEventArgs.cs
- BaseTemplateBuildProvider.cs
- PlacementWorkspace.cs
- TextBox.cs
- DrawingServices.cs
- AllMembershipCondition.cs
- X509SubjectKeyIdentifierClause.cs
- OdbcReferenceCollection.cs
- XmlnsDictionary.cs
- ResizeGrip.cs
- TraceContext.cs
- SelectionBorderGlyph.cs
- PageSettings.cs
- CodeNamespaceCollection.cs
- DisposableCollectionWrapper.cs
- TreeNodeSelectionProcessor.cs
- CodeDomConfigurationHandler.cs
- FieldBuilder.cs
- ContentControl.cs
- SchemaElementDecl.cs
- TabPanel.cs
- TypeSystemHelpers.cs
- ResourceFallbackManager.cs
- PerformanceCounterNameAttribute.cs
- AuthenticationSection.cs
- WebPartTransformerCollection.cs
- documentsequencetextview.cs
- StringSorter.cs
- DBParameter.cs
- ViewKeyConstraint.cs
- HyperLinkColumn.cs
- QuotedPairReader.cs
- Operators.cs
- DbBuffer.cs
- TreeNodeCollection.cs
- ScriptControlDescriptor.cs
- RelatedCurrencyManager.cs
- PropertyEmitterBase.cs
- CacheSection.cs
- ReferenceList.cs
- BaseDataList.cs
- DataGridViewRowContextMenuStripNeededEventArgs.cs
- UnionExpr.cs
- UnsafeNativeMethodsMilCoreApi.cs
- BooleanConverter.cs
- ThreadStartException.cs
- ObjectReaderCompiler.cs