Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / Data / System / Data / ProviderBase / DbBuffer.cs / 1 / 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
- Matrix3D.cs
- OdbcFactory.cs
- ScriptingJsonSerializationSection.cs
- NameNode.cs
- SchemaNamespaceManager.cs
- RegexFCD.cs
- HMACSHA384.cs
- SchemaInfo.cs
- InfoCardPolicy.cs
- SQLInt16.cs
- XhtmlTextWriter.cs
- HybridDictionary.cs
- MobileControlsSectionHandler.cs
- JavaScriptObjectDeserializer.cs
- PageBuildProvider.cs
- OrderedParallelQuery.cs
- DependencyPropertyHelper.cs
- _FixedSizeReader.cs
- TableProvider.cs
- GridItemPattern.cs
- ContextMenu.cs
- URLAttribute.cs
- UIntPtr.cs
- OutputCacheProfileCollection.cs
- FileResponseElement.cs
- DetailsViewRow.cs
- WebPartMinimizeVerb.cs
- DataGridViewButtonColumn.cs
- PipelineModuleStepContainer.cs
- DLinqDataModelProvider.cs
- FileBasedResourceGroveler.cs
- CharacterShapingProperties.cs
- HyperLinkColumn.cs
- dataobject.cs
- PathFigure.cs
- InvalidTimeZoneException.cs
- SqlCacheDependencyDatabase.cs
- LiteralSubsegment.cs
- LiteralTextParser.cs
- DemultiplexingDispatchMessageFormatter.cs
- TrustManagerMoreInformation.cs
- BinHexDecoder.cs
- XmlWrappingReader.cs
- ADRoleFactoryConfiguration.cs
- DataGridTextBox.cs
- Variable.cs
- EllipseGeometry.cs
- Subtree.cs
- SafeNativeMethods.cs
- NativeMethods.cs
- SystemWebCachingSectionGroup.cs
- Transactions.cs
- CompModSwitches.cs
- Journal.cs
- TraceLog.cs
- InProcStateClientManager.cs
- LambdaCompiler.Logical.cs
- DirectoryNotFoundException.cs
- XmlSchemaObjectTable.cs
- PrintEvent.cs
- ScalarRestriction.cs
- webclient.cs
- SystemWebSectionGroup.cs
- PostBackOptions.cs
- OletxTransactionFormatter.cs
- AssemblyName.cs
- ImageListImageEditor.cs
- IBuiltInEvidence.cs
- ContourSegment.cs
- ComponentRenameEvent.cs
- EdmSchemaAttribute.cs
- WebPartCloseVerb.cs
- SoapUnknownHeader.cs
- TemplateAction.cs
- XmlSchemaImporter.cs
- AuthenticateEventArgs.cs
- Image.cs
- DispatcherOperation.cs
- XmlTypeMapping.cs
- ZipPackagePart.cs
- MatrixCamera.cs
- DbInsertCommandTree.cs
- ChangeInterceptorAttribute.cs
- Attributes.cs
- NonVisualControlAttribute.cs
- XamlSerializationHelper.cs
- HandledEventArgs.cs
- VectorCollectionConverter.cs
- TreeNodeConverter.cs
- DynamicMethod.cs
- LocalFileSettingsProvider.cs
- InvalidOperationException.cs
- DbConnectionPoolGroupProviderInfo.cs
- SizeConverter.cs
- GlyphRun.cs
- SoapSchemaImporter.cs
- SuppressMessageAttribute.cs
- WorkflowDefinitionDispenser.cs
- BaseAddressElementCollection.cs
- DrawingGroup.cs