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
- _NegoStream.cs
- BaseValidator.cs
- ConfigurationValidatorAttribute.cs
- HttpCapabilitiesEvaluator.cs
- BitmapEffectOutputConnector.cs
- Permission.cs
- WebPartZoneBase.cs
- TypedRowGenerator.cs
- DataGridViewRowStateChangedEventArgs.cs
- KeyValueInternalCollection.cs
- ClientTargetSection.cs
- manifestimages.cs
- EditorBrowsableAttribute.cs
- WhileDesigner.cs
- CollectionViewGroupRoot.cs
- OperandQuery.cs
- XmlSchemaImport.cs
- RangeBase.cs
- NativeMethods.cs
- DragDrop.cs
- UndoManager.cs
- SpeechSeg.cs
- ClientApiGenerator.cs
- SoundPlayer.cs
- VisualStateGroup.cs
- FamilyTypeface.cs
- PrimitiveCodeDomSerializer.cs
- DataRelationPropertyDescriptor.cs
- SplitterCancelEvent.cs
- KeyNotFoundException.cs
- SchemaComplexType.cs
- TextTreePropertyUndoUnit.cs
- DataMisalignedException.cs
- DataSourceXmlTextReader.cs
- RectangleGeometry.cs
- PageThemeBuildProvider.cs
- SortFieldComparer.cs
- Manipulation.cs
- PageBreakRecord.cs
- UnsafeNativeMethods.cs
- EllipticalNodeOperations.cs
- ToolStripContentPanel.cs
- DesignerUtility.cs
- CatalogPartChrome.cs
- ManifestBasedResourceGroveler.cs
- RichTextBox.cs
- ConnectionInterfaceCollection.cs
- ActivityCodeGenerator.cs
- Overlapped.cs
- PointF.cs
- Column.cs
- NativeObjectSecurity.cs
- JsonServiceDocumentSerializer.cs
- ConnectionStringsSection.cs
- SqlHelper.cs
- RadioButtonFlatAdapter.cs
- BinaryObjectReader.cs
- CroppedBitmap.cs
- CompilerResults.cs
- BreakRecordTable.cs
- Cursor.cs
- SrgsElementList.cs
- SqlAggregateChecker.cs
- SqlUtil.cs
- Label.cs
- DetailsViewUpdateEventArgs.cs
- XmlSecureResolver.cs
- StateRuntime.cs
- ExpressionWriter.cs
- RequestCachePolicyConverter.cs
- Selection.cs
- SrgsRulesCollection.cs
- DeferredRunTextReference.cs
- LambdaCompiler.ControlFlow.cs
- EntityModelBuildProvider.cs
- Double.cs
- ScriptReference.cs
- precedingquery.cs
- Compiler.cs
- GeneratedContractType.cs
- querybuilder.cs
- AnnotationHighlightLayer.cs
- WindowsEditBox.cs
- GcSettings.cs
- AsymmetricAlgorithm.cs
- TimeSpanMinutesConverter.cs
- FilterEventArgs.cs
- Profiler.cs
- Matrix.cs
- ExpressionBuilderContext.cs
- EventLogHandle.cs
- StorageTypeMapping.cs
- ComponentEvent.cs
- XmlReturnWriter.cs
- Int64AnimationUsingKeyFrames.cs
- _SecureChannel.cs
- SizeConverter.cs
- UITypeEditor.cs
- XPathNavigatorKeyComparer.cs
- XmlUrlResolver.cs