Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / 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
- DbException.cs
- BindValidator.cs
- Activity.cs
- ApplicationContext.cs
- NameTable.cs
- PaperSize.cs
- DocumentGrid.cs
- ExpressionConverter.cs
- InputBuffer.cs
- SessionStateModule.cs
- UdpUtility.cs
- MappingMetadataHelper.cs
- TemplatingOptionsDialog.cs
- SecurityKeyIdentifier.cs
- MaskInputRejectedEventArgs.cs
- StringValidatorAttribute.cs
- RayHitTestParameters.cs
- WebServiceEnumData.cs
- LockRecoveryTask.cs
- XmlSchemaGroupRef.cs
- RequestCacheEntry.cs
- NativeWrapper.cs
- MSG.cs
- GeneralTransform3DGroup.cs
- Token.cs
- NoneExcludedImageIndexConverter.cs
- BitmapData.cs
- ServicesExceptionNotHandledEventArgs.cs
- Dump.cs
- Property.cs
- SourceFilter.cs
- HierarchicalDataSourceControl.cs
- NetStream.cs
- CallSiteBinder.cs
- TemplatedEditableDesignerRegion.cs
- Point4DValueSerializer.cs
- SqlDataSourceTableQuery.cs
- AlphaSortedEnumConverter.cs
- RemotingConfiguration.cs
- AddInProcess.cs
- ProcessModelSection.cs
- Crc32Helper.cs
- NamedServiceModelExtensionCollectionElement.cs
- RelatedEnd.cs
- NotImplementedException.cs
- RoutedUICommand.cs
- WindowsStatusBar.cs
- WebEventCodes.cs
- HttpWebRequestElement.cs
- BrushConverter.cs
- JsonSerializer.cs
- XmlSchemaAttribute.cs
- MessageDesigner.cs
- TextSpan.cs
- VirtualDirectoryMappingCollection.cs
- X509SubjectKeyIdentifierClause.cs
- DataService.cs
- Underline.cs
- FixUpCollection.cs
- HttpRequestCacheValidator.cs
- ToolTipAutomationPeer.cs
- wgx_render.cs
- VideoDrawing.cs
- ConfigXmlElement.cs
- OleAutBinder.cs
- TriggerBase.cs
- SmtpNetworkElement.cs
- ByteStreamMessageEncoder.cs
- XmlSchemaElement.cs
- Filter.cs
- MatrixTransform.cs
- SQLRoleProvider.cs
- PersonalizableAttribute.cs
- NextPreviousPagerField.cs
- HtmlContainerControl.cs
- PlanCompilerUtil.cs
- RuntimeHandles.cs
- ContractComponent.cs
- AnnotationAdorner.cs
- DataGridPagerStyle.cs
- EventTrigger.cs
- DbConnectionFactory.cs
- ListViewDataItem.cs
- BindingOperations.cs
- AuthenticateEventArgs.cs
- StatusBarPanelClickEvent.cs
- TabControlDesigner.cs
- SwitchElementsCollection.cs
- TypeHelper.cs
- DataDocumentXPathNavigator.cs
- GuidelineSet.cs
- DynamicResourceExtensionConverter.cs
- ModelVisual3D.cs
- EditorPartChrome.cs
- StrongNameMembershipCondition.cs
- ResourceWriter.cs
- Nullable.cs
- ThrowOnMultipleAssignment.cs
- DescendantQuery.cs
- EventTrigger.cs