Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / whidbey / NetFxQFE / ndp / fx / src / DataOracleClient / System / Data / OracleClient / OracleString.cs / 1 / OracleString.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.OracleClient { using System; using System.Data.SqlTypes; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; //--------------------------------------------------------------------- // OracleString // // This class implements support for Oracle's CHAR, VARCHAR, NCHAR, // NVARCHAR and LONG internal data types. While some of these data // types may be retrieved as multi-byte strings from Oracle there is // no particular benefit to leaving them as multi-byte because we // would be forced to re-implement the entire String class for // multi-byte strings to avoid constant conversions. // // For that reason, this type class should simply be a wrapper class // around the CLS String data type, with the appropriate internal // constructors to allow data values to be set from the data reader. // [StructLayout(LayoutKind.Sequential)] public struct OracleString : IComparable, INullable { private string _value; public static readonly OracleString Empty = new OracleString(false); public static readonly OracleString Null = new OracleString(true); // Construct from nothing -- the value will be null or empty private OracleString(bool isNull) { _value = (isNull) ? null : String.Empty; } public OracleString (string s) { _value = s; } // (internal) construct from a row/parameter binding internal OracleString( NativeBuffer buffer, int valueOffset, int lengthOffset, MetaType metaType, OracleConnection connection, // See MDAC #78258 for reason. bool boundAsUCS2, // See MDAC #78258 for reason. bool outputParameterBinding) { // oracle has inconsistent behavior for output parameters. _value = MarshalToString(buffer, valueOffset, lengthOffset, metaType, connection, boundAsUCS2, outputParameterBinding); } public bool IsNull { get { return (null == _value); } } public int Length { get { if (IsNull) { throw ADP.DataIsNull(); } return _value.Length; } } public string Value { get { if (IsNull) { throw ADP.DataIsNull(); } return _value; } } public char this[int index] { get { if (IsNull) { throw ADP.DataIsNull(); } return _value[index]; } } public int CompareTo (object obj) { if (obj.GetType() == typeof(OracleString)) { OracleString s = (OracleString)obj; // If both values are Null, consider them equal. // Otherwise, Null is less than anything. if (IsNull) { return s.IsNull ? 0 : -1; } if (s.IsNull) { return 1; } // Neither value is null, do the comparison. return CultureInfo.CurrentCulture.CompareInfo.Compare(_value, s._value); } throw ADP.WrongType(obj.GetType(), typeof(OracleString)); } public override bool Equals(object value) { if (value is OracleString) { return (this == (OracleString)value).Value; } else { return false; } } static internal int GetChars( NativeBuffer buffer, int valueOffset, int lengthOffset, MetaType metaType, OracleConnection connection, // See MDAC #78258 for reason. bool boundAsUCS2, // See MDAC #78258 for reason. int sourceOffset, char[] destinationBuffer, int destinationOffset, int charCount) { // This static method allows the GetChars type getter to do it's job // without having to marshal the entire value into managed space. bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { buffer.DangerousAddRef(ref mustRelease); if (boundAsUCS2) { if (!metaType.IsLong) { //SQLBU:440832 -- using DangerousGetDataPtrWithBaseOffset instead of DangerousGetDataPtr Marshal.Copy(buffer.DangerousGetDataPtrWithBaseOffset(valueOffset + (ADP.CharSize * sourceOffset)), destinationBuffer, destinationOffset, charCount ); } else { // Long values are bound out-of-line, which means we have // to do this the hard way... NativeBuffer_LongColumnData.CopyOutOfLineChars(buffer.ReadIntPtr(valueOffset), sourceOffset, destinationBuffer, destinationOffset, charCount); } } else { // In the odd case that we don't have a Unicode value (see MDAC #78258 // for the reason) we have to do this the hard way -- get the full value, // then copy the data... string value = MarshalToString(buffer, valueOffset, lengthOffset, metaType, connection, boundAsUCS2, false); int valueLength = value.Length; int resultLength = (sourceOffset + charCount) > valueLength ? valueLength - sourceOffset : charCount; char[] result = value.ToCharArray(sourceOffset, resultLength); Buffer.BlockCopy(result, 0, destinationBuffer, (destinationOffset * ADP.CharSize), (resultLength * ADP.CharSize)); charCount = resultLength; } } finally { if (mustRelease) { buffer.DangerousRelease(); } } return charCount; } public override int GetHashCode() { return IsNull ? 0 : _value.GetHashCode(); } static internal int GetLength (NativeBuffer buffer, int lengthOffset, MetaType metaType) { // Get the length of the data bound int length; // Oracle only will write two bytes of length, but LONG data types // can exceed that amount; our piecewise callbacks will write a // full DWORD of length, so we need to get the full length for them, // but if we do that for all the other types, we'll be reading // un-initialized memory and bad things happen. if (metaType.IsLong) length = buffer.ReadInt32 (lengthOffset); else length = buffer.ReadInt16 (lengthOffset); GC.KeepAlive(buffer); return length; } static internal string MarshalToString( NativeBuffer buffer, int valueOffset, int lengthOffset, MetaType metaType, OracleConnection connection, bool boundAsUCS2, bool outputParameterBinding) { int valueLength = GetLength(buffer, lengthOffset, metaType); if (boundAsUCS2 && outputParameterBinding) { valueLength /= 2; } string result; bool isOutOfLine = metaType.IsLong && !outputParameterBinding; // Long column values are bound out-of-line IntPtr longBuffer = IntPtr.Zero; if (boundAsUCS2) { if (isOutOfLine) { byte[] temp = new byte[valueLength * ADP.CharSize]; NativeBuffer_LongColumnData.CopyOutOfLineBytes(buffer.ReadIntPtr(valueOffset), 0, temp, 0, valueLength * ADP.CharSize); result = System.Text.Encoding.Unicode.GetString(temp); } else { result = buffer.PtrToStringUni (valueOffset, valueLength); } } else { byte[] temp; if (isOutOfLine) { temp = new byte[valueLength]; NativeBuffer_LongColumnData.CopyOutOfLineBytes(buffer.ReadIntPtr(valueOffset), 0, temp, 0, valueLength); } else { temp = buffer.ReadBytes(valueOffset, valueLength); } result = connection.GetString (temp, metaType.UsesNationalCharacterSet); } GC.KeepAlive(buffer); return result; } static internal int MarshalToNative( object value, int offset, int size, NativeBuffer buffer, int bufferOffset, OCI.DATATYPE ociType, bool bindAsUCS2) { Encoding encoding = (bindAsUCS2) ? System.Text.Encoding.Unicode : System.Text.Encoding.UTF8; string from; string fromString; // Get the actual CLR String value from the object if ( value is OracleString ) from = ((OracleString)value)._value; else from = (string)value; // Pick out the substring they've asked for with offset and size if (0 == offset && 0 == size) fromString = from; else if (0 == size || (offset+size) > from.Length) fromString = from.Substring(offset); else fromString = from.Substring(offset,size); byte[] frombytes = encoding.GetBytes(fromString); int dataSize = frombytes.Length; int bytesWritten = dataSize; if (0 != dataSize) { int charCount = dataSize; if (bindAsUCS2) { Debug.Assert (0 == (dataSize & 0x1), "odd number of bytes in a Unicode string?"); charCount /= 2; // Need to adjust for number of UCS2 characters } if (OCI.DATATYPE.LONGVARCHAR == ociType) { buffer.WriteInt32 (bufferOffset, charCount); bufferOffset = checked((int)bufferOffset + 4) ; bytesWritten += 4; } else { // assert for size only if the data type is not LONG Debug.Assert (ociType == OCI.DATATYPE.LONG || ociType == OCI.DATATYPE.LONGVARCHAR || dataSize <= short.MaxValue, "invalid size for non-LONG data?"); } buffer.WriteBytes (bufferOffset, frombytes, 0, dataSize); } return bytesWritten; } public override string ToString() { if (IsNull) { return ADP.NullString; } return _value; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // // Operators // //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// public static OracleString Concat(OracleString x, OracleString y) { // Alternative method for operator + return (x + y); } public static OracleBoolean Equals(OracleString x, OracleString y) { // Alternative method for operator == return (x == y); } public static OracleBoolean GreaterThan(OracleString x, OracleString y) { // Alternative method for operator > return (x > y); } public static OracleBoolean GreaterThanOrEqual(OracleString x, OracleString y) { // Alternative method for operator >= return (x >= y); } public static OracleBoolean LessThan(OracleString x, OracleString y) { // Alternative method for operator < return (x < y); } public static OracleBoolean LessThanOrEqual(OracleString x, OracleString y) { // Alternative method for operator <= return (x <= y); } public static OracleBoolean NotEquals(OracleString x, OracleString y) { // Alternative method for operator != return (x != y); } public static implicit operator OracleString(string s) { return new OracleString(s); } public static explicit operator String(OracleString x) { return x.Value; } public static OracleString operator+ (OracleString x, OracleString y) { if (x.IsNull || y.IsNull) { return Null; } OracleString result = new OracleString(x._value + y._value); return result; } public static OracleBoolean operator== (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) == 0); } public static OracleBoolean operator> (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) > 0); } public static OracleBoolean operator>= (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) >= 0); } public static OracleBoolean operator< (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) < 0); } public static OracleBoolean operator<= (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) <= 0); } public static OracleBoolean operator!= (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) != 0); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //[....] //----------------------------------------------------------------------------- namespace System.Data.OracleClient { using System; using System.Data.SqlTypes; using System.Data.Common; using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; //--------------------------------------------------------------------- // OracleString // // This class implements support for Oracle's CHAR, VARCHAR, NCHAR, // NVARCHAR and LONG internal data types. While some of these data // types may be retrieved as multi-byte strings from Oracle there is // no particular benefit to leaving them as multi-byte because we // would be forced to re-implement the entire String class for // multi-byte strings to avoid constant conversions. // // For that reason, this type class should simply be a wrapper class // around the CLS String data type, with the appropriate internal // constructors to allow data values to be set from the data reader. // [StructLayout(LayoutKind.Sequential)] public struct OracleString : IComparable, INullable { private string _value; public static readonly OracleString Empty = new OracleString(false); public static readonly OracleString Null = new OracleString(true); // Construct from nothing -- the value will be null or empty private OracleString(bool isNull) { _value = (isNull) ? null : String.Empty; } public OracleString (string s) { _value = s; } // (internal) construct from a row/parameter binding internal OracleString( NativeBuffer buffer, int valueOffset, int lengthOffset, MetaType metaType, OracleConnection connection, // See MDAC #78258 for reason. bool boundAsUCS2, // See MDAC #78258 for reason. bool outputParameterBinding) { // oracle has inconsistent behavior for output parameters. _value = MarshalToString(buffer, valueOffset, lengthOffset, metaType, connection, boundAsUCS2, outputParameterBinding); } public bool IsNull { get { return (null == _value); } } public int Length { get { if (IsNull) { throw ADP.DataIsNull(); } return _value.Length; } } public string Value { get { if (IsNull) { throw ADP.DataIsNull(); } return _value; } } public char this[int index] { get { if (IsNull) { throw ADP.DataIsNull(); } return _value[index]; } } public int CompareTo (object obj) { if (obj.GetType() == typeof(OracleString)) { OracleString s = (OracleString)obj; // If both values are Null, consider them equal. // Otherwise, Null is less than anything. if (IsNull) { return s.IsNull ? 0 : -1; } if (s.IsNull) { return 1; } // Neither value is null, do the comparison. return CultureInfo.CurrentCulture.CompareInfo.Compare(_value, s._value); } throw ADP.WrongType(obj.GetType(), typeof(OracleString)); } public override bool Equals(object value) { if (value is OracleString) { return (this == (OracleString)value).Value; } else { return false; } } static internal int GetChars( NativeBuffer buffer, int valueOffset, int lengthOffset, MetaType metaType, OracleConnection connection, // See MDAC #78258 for reason. bool boundAsUCS2, // See MDAC #78258 for reason. int sourceOffset, char[] destinationBuffer, int destinationOffset, int charCount) { // This static method allows the GetChars type getter to do it's job // without having to marshal the entire value into managed space. bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { buffer.DangerousAddRef(ref mustRelease); if (boundAsUCS2) { if (!metaType.IsLong) { //SQLBU:440832 -- using DangerousGetDataPtrWithBaseOffset instead of DangerousGetDataPtr Marshal.Copy(buffer.DangerousGetDataPtrWithBaseOffset(valueOffset + (ADP.CharSize * sourceOffset)), destinationBuffer, destinationOffset, charCount ); } else { // Long values are bound out-of-line, which means we have // to do this the hard way... NativeBuffer_LongColumnData.CopyOutOfLineChars(buffer.ReadIntPtr(valueOffset), sourceOffset, destinationBuffer, destinationOffset, charCount); } } else { // In the odd case that we don't have a Unicode value (see MDAC #78258 // for the reason) we have to do this the hard way -- get the full value, // then copy the data... string value = MarshalToString(buffer, valueOffset, lengthOffset, metaType, connection, boundAsUCS2, false); int valueLength = value.Length; int resultLength = (sourceOffset + charCount) > valueLength ? valueLength - sourceOffset : charCount; char[] result = value.ToCharArray(sourceOffset, resultLength); Buffer.BlockCopy(result, 0, destinationBuffer, (destinationOffset * ADP.CharSize), (resultLength * ADP.CharSize)); charCount = resultLength; } } finally { if (mustRelease) { buffer.DangerousRelease(); } } return charCount; } public override int GetHashCode() { return IsNull ? 0 : _value.GetHashCode(); } static internal int GetLength (NativeBuffer buffer, int lengthOffset, MetaType metaType) { // Get the length of the data bound int length; // Oracle only will write two bytes of length, but LONG data types // can exceed that amount; our piecewise callbacks will write a // full DWORD of length, so we need to get the full length for them, // but if we do that for all the other types, we'll be reading // un-initialized memory and bad things happen. if (metaType.IsLong) length = buffer.ReadInt32 (lengthOffset); else length = buffer.ReadInt16 (lengthOffset); GC.KeepAlive(buffer); return length; } static internal string MarshalToString( NativeBuffer buffer, int valueOffset, int lengthOffset, MetaType metaType, OracleConnection connection, bool boundAsUCS2, bool outputParameterBinding) { int valueLength = GetLength(buffer, lengthOffset, metaType); if (boundAsUCS2 && outputParameterBinding) { valueLength /= 2; } string result; bool isOutOfLine = metaType.IsLong && !outputParameterBinding; // Long column values are bound out-of-line IntPtr longBuffer = IntPtr.Zero; if (boundAsUCS2) { if (isOutOfLine) { byte[] temp = new byte[valueLength * ADP.CharSize]; NativeBuffer_LongColumnData.CopyOutOfLineBytes(buffer.ReadIntPtr(valueOffset), 0, temp, 0, valueLength * ADP.CharSize); result = System.Text.Encoding.Unicode.GetString(temp); } else { result = buffer.PtrToStringUni (valueOffset, valueLength); } } else { byte[] temp; if (isOutOfLine) { temp = new byte[valueLength]; NativeBuffer_LongColumnData.CopyOutOfLineBytes(buffer.ReadIntPtr(valueOffset), 0, temp, 0, valueLength); } else { temp = buffer.ReadBytes(valueOffset, valueLength); } result = connection.GetString (temp, metaType.UsesNationalCharacterSet); } GC.KeepAlive(buffer); return result; } static internal int MarshalToNative( object value, int offset, int size, NativeBuffer buffer, int bufferOffset, OCI.DATATYPE ociType, bool bindAsUCS2) { Encoding encoding = (bindAsUCS2) ? System.Text.Encoding.Unicode : System.Text.Encoding.UTF8; string from; string fromString; // Get the actual CLR String value from the object if ( value is OracleString ) from = ((OracleString)value)._value; else from = (string)value; // Pick out the substring they've asked for with offset and size if (0 == offset && 0 == size) fromString = from; else if (0 == size || (offset+size) > from.Length) fromString = from.Substring(offset); else fromString = from.Substring(offset,size); byte[] frombytes = encoding.GetBytes(fromString); int dataSize = frombytes.Length; int bytesWritten = dataSize; if (0 != dataSize) { int charCount = dataSize; if (bindAsUCS2) { Debug.Assert (0 == (dataSize & 0x1), "odd number of bytes in a Unicode string?"); charCount /= 2; // Need to adjust for number of UCS2 characters } if (OCI.DATATYPE.LONGVARCHAR == ociType) { buffer.WriteInt32 (bufferOffset, charCount); bufferOffset = checked((int)bufferOffset + 4) ; bytesWritten += 4; } else { // assert for size only if the data type is not LONG Debug.Assert (ociType == OCI.DATATYPE.LONG || ociType == OCI.DATATYPE.LONGVARCHAR || dataSize <= short.MaxValue, "invalid size for non-LONG data?"); } buffer.WriteBytes (bufferOffset, frombytes, 0, dataSize); } return bytesWritten; } public override string ToString() { if (IsNull) { return ADP.NullString; } return _value; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // // Operators // //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// public static OracleString Concat(OracleString x, OracleString y) { // Alternative method for operator + return (x + y); } public static OracleBoolean Equals(OracleString x, OracleString y) { // Alternative method for operator == return (x == y); } public static OracleBoolean GreaterThan(OracleString x, OracleString y) { // Alternative method for operator > return (x > y); } public static OracleBoolean GreaterThanOrEqual(OracleString x, OracleString y) { // Alternative method for operator >= return (x >= y); } public static OracleBoolean LessThan(OracleString x, OracleString y) { // Alternative method for operator < return (x < y); } public static OracleBoolean LessThanOrEqual(OracleString x, OracleString y) { // Alternative method for operator <= return (x <= y); } public static OracleBoolean NotEquals(OracleString x, OracleString y) { // Alternative method for operator != return (x != y); } public static implicit operator OracleString(string s) { return new OracleString(s); } public static explicit operator String(OracleString x) { return x.Value; } public static OracleString operator+ (OracleString x, OracleString y) { if (x.IsNull || y.IsNull) { return Null; } OracleString result = new OracleString(x._value + y._value); return result; } public static OracleBoolean operator== (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) == 0); } public static OracleBoolean operator> (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) > 0); } public static OracleBoolean operator>= (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) >= 0); } public static OracleBoolean operator< (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) < 0); } public static OracleBoolean operator<= (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) <= 0); } public static OracleBoolean operator!= (OracleString x, OracleString y) { return (x.IsNull || y.IsNull) ? OracleBoolean.Null : new OracleBoolean(x.CompareTo(y) != 0); } } } // 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
- ControlBuilderAttribute.cs
- DecimalAnimation.cs
- DataSourceControlBuilder.cs
- StringConcat.cs
- x509utils.cs
- TraceProvider.cs
- DetailsViewPageEventArgs.cs
- Socket.cs
- BuildProvider.cs
- TripleDESCryptoServiceProvider.cs
- EFAssociationProvider.cs
- ListViewItemMouseHoverEvent.cs
- GridView.cs
- CacheHelper.cs
- Menu.cs
- SerializationSectionGroup.cs
- DirectoryLocalQuery.cs
- EnvironmentPermission.cs
- IERequestCache.cs
- ButtonStandardAdapter.cs
- UTF8Encoding.cs
- ProxyAssemblyNotLoadedException.cs
- ListMarkerSourceInfo.cs
- DynamicUpdateCommand.cs
- PolyBezierSegment.cs
- SecureStringHasher.cs
- ImageInfo.cs
- Solver.cs
- Tokenizer.cs
- XmlExpressionDumper.cs
- DataGridTablesFactory.cs
- WebPartAddingEventArgs.cs
- ServiceDescriptions.cs
- BoundColumn.cs
- ProfileBuildProvider.cs
- StrongNameKeyPair.cs
- WmlPhoneCallAdapter.cs
- SignatureHelper.cs
- KnownBoxes.cs
- _SpnDictionary.cs
- IdentityNotMappedException.cs
- SmiGettersStream.cs
- CompressEmulationStream.cs
- ClassHandlersStore.cs
- ZipIOFileItemStream.cs
- Thickness.cs
- COAUTHIDENTITY.cs
- CodeGenHelper.cs
- EntityTypeBase.cs
- WebScriptEnablingElement.cs
- ConfigErrorGlyph.cs
- DivideByZeroException.cs
- AtomMaterializer.cs
- ConnectionStringsSection.cs
- DataGridViewCellValueEventArgs.cs
- ArrayTypeMismatchException.cs
- WindowCollection.cs
- ColorBlend.cs
- XmlAutoDetectWriter.cs
- SmiEventSink_Default.cs
- RowCache.cs
- WsdlHelpGeneratorElement.cs
- DynamicDataManager.cs
- InsufficientMemoryException.cs
- ItemsChangedEventArgs.cs
- ScriptServiceAttribute.cs
- RegexReplacement.cs
- TemplateApplicationHelper.cs
- autovalidator.cs
- CacheRequest.cs
- HwndMouseInputProvider.cs
- UriSectionReader.cs
- Triangle.cs
- PhonemeEventArgs.cs
- ImageConverter.cs
- XmlSchemaGroupRef.cs
- UniqueConstraint.cs
- Events.cs
- GeometryConverter.cs
- GridViewRow.cs
- CodeAssignStatement.cs
- ColorConverter.cs
- TimelineCollection.cs
- TextEffectResolver.cs
- PreDigestedSignedInfo.cs
- ModelItemDictionary.cs
- PartialArray.cs
- MultipleViewProviderWrapper.cs
- StrokeRenderer.cs
- ResourceDescriptionAttribute.cs
- BinHexDecoder.cs
- GlyphsSerializer.cs
- UserControlParser.cs
- CacheDict.cs
- ObjectAssociationEndMapping.cs
- DetailsViewInsertedEventArgs.cs
- RijndaelManaged.cs
- DispatcherObject.cs
- glyphs.cs
- AlignmentYValidation.cs