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.

            if (boundAsUCS2)
            {
                HandleRef sourceBuffer;

                if (!metaType.IsLong)
                {
                    sourceBuffer = buffer.PtrOffset(valueOffset + (ADP.CharSize * sourceOffset));
                }
                else
                {
                    // Long values are bound out-of-line, which means we have
                    // to do this the hard way...
                    sourceBuffer = buffer.PtrOffset(valueOffset);
                    IntPtr longBuffer = Marshal.ReadIntPtr((IntPtr)sourceBuffer);

                    if (0 != sourceOffset)
                    {
                        longBuffer = new IntPtr(longBuffer.ToInt64() + (long)(ADP.CharSize * sourceOffset));
                    }

                    HandleRef newSourceBuffer = new HandleRef(sourceBuffer.Wrapper, longBuffer);
                    sourceBuffer = newSourceBuffer;
                }

                Marshal.Copy((IntPtr)sourceBuffer, 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;
            }
            GC.KeepAlive(buffer);
            return(charCount);
        }
示例#2
0
        internal void GetNames()
        {
            _lob.AssertConnectionIsOpen();

            int          charSize             = (Connection.EnvironmentHandle.IsUnicode) ? 2 : 1;
            short        directoryAliasLength = (short)(charSize * 30);
            short        fileAliasLength      = (short)(charSize * 255);
            NativeBuffer buffer = Connection.ScratchBuffer;

            Debug.Assert(buffer.Length > (directoryAliasLength + fileAliasLength), "connection's scratch buffer is too small");

            HandleRef directoryAlias = buffer.Ptr;
            HandleRef fileAlias      = buffer.PtrOffset(directoryAliasLength);

            int rc = TracedNativeMethods.OCILobFileGetName(
                Connection.EnvironmentHandle,
                ErrorHandle,
                Descriptor,
                directoryAlias,
                ref directoryAliasLength,
                fileAlias,
                ref fileAliasLength
                );

            if (0 != rc)
            {
                Connection.CheckError(ErrorHandle, rc);
            }

            _directoryAlias = Connection.GetString((IntPtr)directoryAlias, directoryAliasLength, false);
            _fileName       = Connection.GetString((IntPtr)fileAlias, fileAliasLength, false);
            GC.KeepAlive(buffer);
        }
        static internal int GetLength(
            NativeBuffer buffer,
            int lengthOffset,
            MetaType metaType
            )
        {
            // Get the length of the data bound
            int length;

            HandleRef lengthBuffer = buffer.PtrOffset(lengthOffset);

            // 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 = Marshal.ReadInt32((IntPtr)lengthBuffer);
            }
            else
            {
                length = (int)Marshal.ReadInt16((IntPtr)lengthBuffer);
            }

            return(length);
        }
示例#4
0
 // (internal) construct from a row/parameter binding
 internal OracleTimeSpan(
     NativeBuffer buffer,
     int valueOffset) : this(true)
 {
     _value = new byte[11];
     Marshal.Copy((IntPtr)buffer.PtrOffset(valueOffset), _value, 0, 11);
 }
示例#5
0
        static internal TimeSpan MarshalToTimeSpan(
            NativeBuffer buffer,
            int valueOffset)
        {
            byte[] rawValue = new byte[11];
            Marshal.Copy((IntPtr)buffer.PtrOffset(valueOffset), rawValue, 0, 11);

            TimeSpan result = ToTimeSpan(rawValue);

            return(result);
        }
        static internal int GetBytes(
            NativeBuffer buffer,
            int valueOffset,
            MetaType metaType,
            int sourceOffset,
            byte[]                          destinationBuffer,
            int destinationOffset,
            int byteCount
            )
        {
            // This static method allows the GetBytes type getter to do it's job
            // without having to marshal the entire value into managed space.
            HandleRef sourceBuffer;

            if (!metaType.IsLong)
            {
                sourceBuffer = buffer.PtrOffset(valueOffset + sourceOffset);
            }
            else
            {
                // Long values are bound out-of-line, which means we have
                // to do this the hard way...
                sourceBuffer = buffer.PtrOffset(valueOffset);
                IntPtr longBuffer = Marshal.ReadIntPtr((IntPtr)sourceBuffer);

                if (0 != sourceOffset)
                {
                    longBuffer = new IntPtr(longBuffer.ToInt64() + (long)sourceOffset);
                }

                HandleRef newSourceBuffer = new HandleRef(sourceBuffer.Wrapper, longBuffer);
                sourceBuffer = newSourceBuffer;
            }

            Marshal.Copy((IntPtr)sourceBuffer, destinationBuffer, destinationOffset, byteCount);
            GC.KeepAlive(sourceBuffer);
            return(byteCount);
        }
示例#7
0
        static internal byte[] GetBytes(
            NativeBuffer buffer,
            int valueOffset,
            MetaType metaType,
            OracleConnection connection)
        {
            // Static method to return the raw data bytes from the row/parameter
            // buffer, taking the binding type into account and adjusting it for
            // the server time zones, as appropriate.

            int ociBytes;

            OCI.DATATYPE ociType = metaType.OciType;

            switch (ociType)
            {
            case OCI.DATATYPE.DATE:
                ociBytes = x_DATE_Length;
                break;

            case OCI.DATATYPE.INT_TIMESTAMP:
                ociBytes = x_TIMESTAMP_Length;
                break;

            case OCI.DATATYPE.INT_TIMESTAMP_LTZ:
                ociBytes = x_TIMESTAMP_WITH_TIMEZONE_Length;
                break;

            default:
                Debug.Assert(OCI.DATATYPE.INT_TIMESTAMP_TZ == ociType, "unrecognized type");
                ociBytes = x_TIMESTAMP_WITH_TIMEZONE_Length;
                break;
            }

            byte[] result = new byte[ociBytes];
            Marshal.Copy((IntPtr)buffer.PtrOffset(valueOffset), result, 0, ociBytes);

            if (OCI.DATATYPE.INT_TIMESTAMP_LTZ == ociType)
            {
                TimeSpan tzadjust = connection.ServerTimeZoneAdjustmentToUTC;
                result[11] = (byte)(tzadjust.Hours + 20);
                result[12] = (byte)(tzadjust.Minutes + 60);
            }

            return(result);
        }
示例#8
0
        static internal int MarshalToInt32(
            NativeBuffer buffer,
            int valueOffset)
        {
            byte[] ociValue = new byte[5];
            Marshal.Copy((IntPtr)buffer.PtrOffset(valueOffset), ociValue, 0, 5);

            int years = (int)((long)((int)ociValue[0] << 24
                                     | (int)ociValue[1] << 16
                                     | (int)ociValue[2] << 8
                                     | (int)ociValue[3]
                                     ) - 0x80000000);

            int months = (int)ociValue[4] - 60;

            int result = (years * 12) + months;

            AssertValid(result);

            return(result);
        }
        static internal string MarshalToString(
            NativeBuffer buffer,
            int valueOffset,
            int lengthOffset,
            MetaType metaType,
            OracleConnection connection,
            bool boundAsUCS2,
            bool outputParameterBinding
            )
        {
            int    valueLength = GetLength(buffer, lengthOffset, metaType);
            IntPtr valueBuffer = (IntPtr)buffer.PtrOffset(valueOffset);

            // Long values are bound out-of-line
            if (metaType.IsLong && !outputParameterBinding)
            {
                valueBuffer = (IntPtr)Marshal.ReadIntPtr(valueBuffer);
            }

            if (boundAsUCS2 && outputParameterBinding)
            {
                valueLength /= 2;
            }

            string result;

            if (boundAsUCS2)
            {
                result = Marshal.PtrToStringUni(valueBuffer, valueLength);
            }
            else
            {
                result = connection.GetString(valueBuffer, valueLength, metaType.UsesNationalCharacterSet);
            }

            GC.KeepAlive(buffer);
            return(result);
        }
示例#10
0
        internal void Bind(
            OciHandle statementHandle,
            NativeBuffer buffer,
            OciHandle errorHandle,
            int rowBufferLength
            )
        {
            //  Binds the buffer for the column to the statement handle specified.

            OciHandle defineHandle = null;
            IntPtr    h;

            OCI.MODE mode = OCI.MODE.OCI_DEFAULT;
            int      bindSize;

            OCI.DATATYPE ociType = _metaType.OciType;

            _rowBuffer = buffer;

            if (_metaType.IsLong)
            {
                mode     = OCI.MODE.OCI_DYNAMIC_FETCH;
                bindSize = Int32.MaxValue;
            }
            else
            {
                bindSize = _size;
            }

            HandleRef indicatorLocation = ADP.NullHandleRef;
            HandleRef lengthLocation    = ADP.NullHandleRef;
            HandleRef valueLocation     = _rowBuffer.PtrOffset(_valueOffset);

            if (-1 != _indicatorOffset)
            {
                indicatorLocation = _rowBuffer.PtrOffset(_indicatorOffset);
            }

            if (-1 != _lengthOffset && !_metaType.IsLong)
            {
                lengthLocation = _rowBuffer.PtrOffset(_lengthOffset);
            }

            try
            {
                try
                {
                    int rc = TracedNativeMethods.OCIDefineByPos(
                        statementHandle,                                    // hndlp
                        out h,                                              // defnpp
                        errorHandle,                                        // errhp
                        _ordinal + 1,                                       // position
                        valueLocation,                                      // valuep
                        bindSize,                                           // value_sz
                        ociType,                                            // htype
                        indicatorLocation,                                  // indp,
                        lengthLocation,                                     // rlenp,
                        ADP.NullHandleRef,                                  // rcodep,
                        mode                                                // mode
                        );
                    if (rc != 0)
                    {
                        _connection.CheckError(errorHandle, rc);
                    }

                    defineHandle = new OciDefineHandle(statementHandle, h);

                    if (0 != rowBufferLength)
                    {
                        int valOffset = rowBufferLength;
                        int indOffset = (-1 != _indicatorOffset) ? rowBufferLength : 0;
                        int lenOffset = (-1 != _lengthOffset && !_metaType.IsLong) ? rowBufferLength : 0;

                        rc = TracedNativeMethods.OCIDefineArrayOfStruct(
                            defineHandle,
                            errorHandle,
                            valOffset,
                            indOffset,
                            lenOffset,
                            0                            // never use rcodep above...
                            );
                        if (rc != 0)
                        {
                            _connection.CheckError(errorHandle, rc);
                        }
                    }

                    if (!_connection.UnicodeEnabled)
                    {
                        if (_metaType.UsesNationalCharacterSet)
                        {
                            Debug.Assert(!_metaType.IsLong, "LONG data may never be bound as NCHAR");
                            // NOTE:    the order is important here; setting charsetForm will
                            //          reset charsetId (I found this out the hard way...)
                            defineHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, (int)OCI.CHARSETFORM.SQLCS_NCHAR, errorHandle);
                        }
                        if (_bindAsUCS2)
                        {
                            // NOTE:    the order is important here; setting charsetForm will
                            //          reset charsetId (I found this out the hard way...)
                            defineHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_ID, OCI.OCI_UCS2ID, errorHandle);
                        }
                    }
                    if (_metaType.IsLong)
                    {
                        // Initialize the longBuffer in the rowBuffer to null
                        Marshal.WriteIntPtr((IntPtr)_rowBuffer.PtrOffset(_valueOffset), IntPtr.Zero);

                        if (null != _longBuffer)
                        {
                            _longBuffer.Dispose();
                            _longBuffer = null;
                        }

                        // We require MTxOCI8 to be in the path somewhere for us to handle LONG data
                        if (!OCI.IsNewMtxOci8Installed)
#if EVERETT
                        { throw ADP.MustInstallNewMtxOciLONG(); }
#else //!EVERETT        {
                            throw ADP.MustInstallNewMtxOci();
                        }
#endif //!EVERETT
                        _callback = new OCI.Callback.OCICallbackDefine(_callback_GetColumnPiecewise);

                        rc = TracedNativeMethods.MTxOciDefineDynamic(
                            defineHandle,                               // defnp
                            errorHandle,                                // errhp
                            ADP.NullHandleRef,                          // dvoid *octxp,
                            _callback                                   // OCICallbackDefine ocbfp
                            );
                        if (rc != 0)
                        {
                            _connection.CheckError(errorHandle, rc);
                        }
                    }
                }
                finally
                {
                    // We don't need this any longer, get rid of it.
                    OciHandle.SafeDispose(ref defineHandle);
                }
            }
示例#11
0
        }                                                                                                           // This is the value used for the SchemaTable, which must be Chars...

        ////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////
        //
        // Methods
        //
        ////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////

        private int _callback_GetColumnPiecewise(
            IntPtr octxp,
            IntPtr defnp,
            int iter,
            IntPtr bufpp,                   // dvoid**
            IntPtr alenp,                   // ub4**
            IntPtr piecep,                  // ub1*
            IntPtr indpp,                   // dvoid**
            IntPtr rcodep                   // ub2**
            )
        {
            //  Callback routine for Dynamic Binding column values from Oracle: tell
            //  Oracle where to stuff the data.

            int thisChunkSize;

            // TODO: Consider creating a StringBuilder-like class (BlobBuilder?) that can store chunks of allocations, instead of a single buffer being re-allocated.

            if (null == _longBuffer)
            {
                _longBuffer        = new NativeBuffer_LongColumnData(ChunkSize);
                _longCurrentOffset = 0;
            }

            if (0 == _longNextOffset)
            {
                thisChunkSize = _longBuffer.Length;      // first read: fill the existing buffer
            }
            else
            {
                thisChunkSize = ChunkSize;
            }

            _longCurrentOffset = _longNextOffset;
            _longNextOffset    = _longCurrentOffset + thisChunkSize;
            _longBuffer.Length = _longNextOffset;

            HandleRef buffer = _longBuffer.Ptr;

//Debug.WriteLine(((IntPtr)buffer).ToInt32());

            // Stuff the longBuffer into the rowBuffer so we can get use it
            // in the type getters later (this also verifies that the allocation
            // has occured)
            Marshal.WriteIntPtr((IntPtr)_rowBuffer.PtrOffset(_valueOffset), (IntPtr)buffer);

            Marshal.WriteIntPtr(alenp, (IntPtr)_rowBuffer.PtrOffset(_lengthOffset));        // *alenp
            if (-1 != _indicatorOffset)
            {
                Marshal.WriteIntPtr(indpp, (IntPtr)_rowBuffer.PtrOffset(_indicatorOffset));     // *indpp
            }
            else
            {
                Marshal.WriteIntPtr(indpp, IntPtr.Zero);                                    // *indpp
            }
            Marshal.WriteIntPtr(bufpp, (IntPtr)_longBuffer.PtrOffset(_longCurrentOffset));  // *bufpp

            Marshal.WriteInt32((IntPtr)_rowBuffer.PtrOffset(_lengthOffset), thisChunkSize); // **alenp

            GC.KeepAlive(this);
            return((int)OCI.RETURNCODE.OCI_CONTINUE);
        }
        ////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////
        //
        // Methods
        //
        ////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////

        internal void Bind(
            OciHandle statementHandle,
            NativeBuffer parameterBuffer,
            OracleConnection connection
            )
        {
            IntPtr h;

            // Don't bother with parameters where the user asks for the default value.
            if (!IsDirection(Parameter, ParameterDirection.Output) && null == Parameter.Value)
            {
                return;
            }

            string    parameterName     = Parameter.ParameterName;
            OciHandle errorHandle       = connection.ErrorHandle;
            OciHandle environmentHandle = connection.EnvironmentHandle;

            int valueLength = 0;

            OCI.INDICATOR indicatorValue = OCI.INDICATOR.OK;
            int           bufferLength;

            OCI.DATATYPE ociType = _bindingMetaType.OciType;

            HandleRef indicatorLocation = parameterBuffer.PtrOffset(_indicatorOffset);
            HandleRef lengthLocation    = parameterBuffer.PtrOffset(_lengthOffset);
            HandleRef valueLocation     = parameterBuffer.PtrOffset(_valueOffset);

            if (IsDirection(Parameter, ParameterDirection.Input))
            {
                if (ADP.IsNull(_coercedValue))
                {
                    indicatorValue = OCI.INDICATOR.ISNULL;
                }
                else
                {
                    valueLength = PutOracleValue(
                        _coercedValue,
                        valueLocation,
                        _bindingMetaType,
                        connection);
                }
            }
            else
            {
                Debug.Assert(IsDirection(Parameter, ParameterDirection.Output), "non-output output parameter?");

                if (_bindingMetaType.IsVariableLength)
                {
                    valueLength = 0;                // Output-only values never have an input length...
                }
                else
                {
                    valueLength = _bufferLengthInBytes; // ...except when they're fixed length, to avoid ORA-01459 errors
                }
                OciLobLocator.SafeDispose(ref _locator);
                OciHandle.SafeDispose(ref _descriptor);

                switch (ociType)
                {
                case OCI.DATATYPE.BFILE:
                case OCI.DATATYPE.BLOB:
                case OCI.DATATYPE.CLOB:
                    _locator = new OciLobLocator(connection, _bindingMetaType.OracleType);
                    break;

                case OCI.DATATYPE.RSET:
                    _descriptor = new OciStatementHandle(environmentHandle);
                    break;
                }

                if (null != _locator)
                {
                    Marshal.WriteIntPtr((IntPtr)valueLocation, (IntPtr)_locator.Handle);
                }
                else if (null != _descriptor)
                {
                    Marshal.WriteIntPtr((IntPtr)valueLocation, (IntPtr)_descriptor.Handle);
                }
            }

            Marshal.WriteInt16((IntPtr)indicatorLocation, (Int16)indicatorValue);

            // Don't bind a length value for LONGVARCHAR or LONGVARRAW data, or you'll end
            // up with ORA-01098: program Interface error during Long Insert\nORA-01458: invalid length inside variable character string
            // errors.

            if (OCI.DATATYPE.LONGVARCHAR == ociType ||
                OCI.DATATYPE.LONGVARRAW == ociType)
            {
                lengthLocation = ADP.NullHandleRef;
            }
            else
            {
                // When we're binding this parameter as UCS2, the length we specify
                // must be in characters, not in bytes.
                if (_bindAsUCS2)
                {
                    Marshal.WriteInt32((IntPtr)lengthLocation, (Int32)(valueLength / ADP.CharSize));
                }
                else
                {
                    Marshal.WriteInt32((IntPtr)lengthLocation, (Int32)valueLength);
                }
            }

            if (IsDirection(Parameter, ParameterDirection.Output))
            {
                bufferLength = _bufferLengthInBytes;
            }
            else
            {
                bufferLength = valueLength;
            }

            // Finally, tell Oracle about our parameter.

            int rc = TracedNativeMethods.OCIBindByName(
                statementHandle,
                out h,
                errorHandle,
                parameterName,
                parameterName.Length,
                valueLocation,
                bufferLength,
                ociType,
                indicatorLocation,
                lengthLocation,
                ADP.NullHandleRef,
                0,
                ADP.NullHandleRef,
                OCI.MODE.OCI_DEFAULT
                );

            if (rc != 0)
            {
                _command.Connection.CheckError(errorHandle, rc);
            }

            _bindHandle = new OciBindHandle(statementHandle, h);

#if TRACEPARAMETERVALUES
            if (null != _coercedValue)
            {
                SafeNativeMethods.OutputDebugStringW("Value = '" + _coercedValue.ToString() + "'\n");
            }
#endif //TRACEPARAMETERVALUES

            // OK, character bindings have a few extra things we need to do to
            // deal with character sizes and alternate character sets.

            if (_bindingMetaType.IsCharacterType)
            {
                // To avoid problems when our buffer is larger than the maximum number
                // of characters, we use OCI_ATTR_MAXCHAR_SIZE to limit the number of
                // characters that will be used.  (Except on Oracle8i clients where it
                // isn't available)
                if (OCI.ClientVersionAtLeastOracle9i &&
                    IsDirection(Parameter, ParameterDirection.Output))
                {
                    _bindHandle.SetAttribute(OCI.ATTR.OCI_ATTR_MAXCHAR_SIZE, (int)_bufferLength, errorHandle);
                }

                if ((bufferLength > _bindingMetaType.MaxBindSize / ADP.CharSize) ||
                    (!OCI.ClientVersionAtLeastOracle9i && _bindingMetaType.UsesNationalCharacterSet))           // need to specify MAXDATA_SIZE for OCI8 UCS2 bindings to work
                {
                    _bindHandle.SetAttribute(OCI.ATTR.OCI_ATTR_MAXDATA_SIZE, (int)_bindingMetaType.MaxBindSize, errorHandle);
                }

                // NOTE:    the order is important here; setting charsetForm will
                //          reset charsetId (I found this out the hard way...)
                if (_bindingMetaType.UsesNationalCharacterSet)
                {
                    _bindHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, (int)OCI.CHARSETFORM.SQLCS_NCHAR, errorHandle);
                }

                // NOTE:    the order is important here; setting charsetForm will
                //          reset charsetId (I found this out the hard way...)
                if (_bindAsUCS2)
                {
                    _bindHandle.SetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_ID, OCI.OCI_UCS2ID, errorHandle);
                }
            }
        }
        internal object GetOutputValue(
            NativeBuffer parameterBuffer,
            OracleConnection connection,                // connection, so we can create LOB values
            bool needCLSType
            )
        {
            object result;

            //  Returns an object that contains the value of the column in the
            //  specified row buffer.  This method returns Oracle-typed objects.

            if (Marshal.ReadInt16((IntPtr)parameterBuffer.Ptr, _indicatorOffset) == (Int16)OCI.INDICATOR.ISNULL)
            {
                return(DBNull.Value);
            }

            switch (_bindingMetaType.OciType)
            {
            case OCI.DATATYPE.FLOAT:
            case OCI.DATATYPE.INTEGER:
            case OCI.DATATYPE.UNSIGNEDINT:
                result = Marshal.PtrToStructure((IntPtr)parameterBuffer.PtrOffset(_valueOffset), _bindingMetaType.BaseType);
                return(result);

            case OCI.DATATYPE.BFILE:
                result = new OracleBFile(_locator);
                return(result);

            case OCI.DATATYPE.RAW:
            case OCI.DATATYPE.LONGRAW:
            case OCI.DATATYPE.LONGVARRAW:
                result = new OracleBinary(parameterBuffer, _valueOffset, _lengthOffset, _bindingMetaType);
                if (needCLSType)
                {
                    object newresult = ((OracleBinary)result).Value;
                    result = newresult;
                }
                return(result);

            case OCI.DATATYPE.RSET:
                result = new OracleDataReader(connection, _descriptor);
                return(result);

            case OCI.DATATYPE.DATE:
            case OCI.DATATYPE.INT_TIMESTAMP:
            case OCI.DATATYPE.INT_TIMESTAMP_TZ:
            case OCI.DATATYPE.INT_TIMESTAMP_LTZ:
                result = new OracleDateTime(parameterBuffer, _valueOffset, _bindingMetaType, connection);
                if (needCLSType)
                {
                    object newresult = ((OracleDateTime)result).Value;
                    result = newresult;
                }
                return(result);

            case OCI.DATATYPE.BLOB:
            case OCI.DATATYPE.CLOB:
                result = new OracleLob(_locator);
                return(result);

            case OCI.DATATYPE.INT_INTERVAL_YM:
                result = new OracleMonthSpan(parameterBuffer, _valueOffset);
                if (needCLSType)
                {
                    object newresult = ((OracleMonthSpan)result).Value;
                    result = newresult;
                }
                return(result);

            case OCI.DATATYPE.VARNUM:
                result = new OracleNumber(parameterBuffer, _valueOffset);
                if (needCLSType)
                {
                    object newresult = ((OracleNumber)result).Value;
                    result = newresult;
                }
                return(result);

            case OCI.DATATYPE.CHAR:
            case OCI.DATATYPE.VARCHAR2:
            case OCI.DATATYPE.LONG:
            case OCI.DATATYPE.LONGVARCHAR:
                result = new OracleString(parameterBuffer,
                                          _valueOffset,
                                          _lengthOffset,
                                          _bindingMetaType,
                                          connection,
                                          _bindAsUCS2,
                                          true
                                          );
                int size = _parameter.Size;
                if (0 != size && size < ((OracleString)result).Length)
                {
                    string truncatedResult = ((OracleString)result).Value.Substring(0, size);
                    if (needCLSType)
                    {
                        result = truncatedResult;
                    }
                    else
                    {
                        result = new OracleString(truncatedResult);
                    }
                }
                else if (needCLSType)
                {
                    object newresult = ((OracleString)result).Value;
                    result = newresult;
                }
                return(result);

            case OCI.DATATYPE.INT_INTERVAL_DS:
                result = new OracleTimeSpan(parameterBuffer, _valueOffset);
                if (needCLSType)
                {
                    object newresult = ((OracleTimeSpan)result).Value;
                    result = newresult;
                }
                return(result);
            }
            throw ADP.TypeNotSupported(_bindingMetaType.OciType);
        }