private SqlBuffer(SqlBuffer value)
 {
     this._isNull = value._isNull;
     this._type   = value._type;
     this._value  = value._value;
     this._object = value._object;
 }
 private SqlBuffer(SqlBuffer value)
 {
     this._isNull = value._isNull;
     this._type = value._type;
     this._value = value._value;
     this._object = value._object;
 }
 internal static SqlBuffer[] CreateBufferArray(int length)
 {
     SqlBuffer[] bufferArray = new SqlBuffer[length];
     for (int i = 0; i < bufferArray.Length; i++)
     {
         bufferArray[i] = new SqlBuffer();
     }
     return(bufferArray);
 }
 internal static SqlBuffer[] CloneBufferArray(SqlBuffer[] values)
 {
     SqlBuffer[] bufferArray = new SqlBuffer[values.Length];
     for (int i = 0; i < values.Length; i++)
     {
         bufferArray[i] = new SqlBuffer(values[i]);
     }
     return bufferArray;
 }
 internal static SqlBuffer[] CreateBufferArray(int length)
 {
     SqlBuffer[] bufferArray = new SqlBuffer[length];
     for (int i = 0; i < bufferArray.Length; i++)
     {
         bufferArray[i] = new SqlBuffer();
     }
     return bufferArray;
 }
示例#6
0
 internal static SqlBuffer[] CreateBufferArray(int length)
 {
     SqlBuffer[] buffers = new SqlBuffer[length];
     for (int i = 0; i < buffers.Length; ++i)
     {
         buffers[i] = new SqlBuffer();
     }
     return(buffers);
 }
示例#7
0
 internal static SqlBuffer[] CloneBufferArray(SqlBuffer[] values)
 {
     SqlBuffer[] copy = new SqlBuffer[values.Length];
     for (int i = 0; i < values.Length; i++)
     {
         copy[i] = new SqlBuffer(values[i]);
     }
     return(copy);
 }
示例#8
0
 private SqlBuffer(SqlBuffer value)
 { // Clone
     // value types
     _isNull = value._isNull;
     _type   = value._type;
     // ref types - should also be read only unless at some point we allow this data
     // to be mutable, then we will need to copy
     _value  = value._value;
     _object = value._object;
 }
 internal static void Clear(SqlBuffer[] values)
 {
     if (values != null)
     {
         for (int i = 0; i < values.Length; i++)
         {
             values[i].Clear();
         }
     }
 }
示例#10
0
        private bool TryReadSqlStringValue(SqlBuffer value, byte type, int length, Encoding encoding, bool isPlp, TdsParserStateObject stateObj)
        {
            switch (type)
            {
                case TdsEnums.SQLCHAR:
                case TdsEnums.SQLBIGCHAR:
                case TdsEnums.SQLVARCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                case TdsEnums.SQLTEXT:
                    // If bigvarchar(max), we only read the first chunk here,
                    // expecting the caller to read the rest
                    if (encoding == null)
                    {
                        // if hitting 7.0 server, encoding will be null in metadata for columns or return values since
                        // 7.0 has no support for multiple code pages in data - single code page support only
                        encoding = _defaultEncoding;
                    }
                    string stringValue;
                    if (!stateObj.TryReadStringWithEncoding(length, encoding, isPlp, out stringValue))
                    {
                        return false;
                    }
                    value.SetToString(stringValue);
                    break;

                case TdsEnums.SQLNCHAR:
                case TdsEnums.SQLNVARCHAR:
                case TdsEnums.SQLNTEXT:
                    {
                        String s = null;

                        if (isPlp)
                        {
                            char[] cc = null;

                            if (!TryReadPlpUnicodeChars(ref cc, 0, length >> 1, stateObj, out length))
                            {
                                return false;
                            }
                            if (length > 0)
                            {
                                s = new String(cc, 0, length);
                            }
                            else
                            {
                                s = ADP.StrEmpty;
                            }
                        }
                        else
                        {
                            if (!stateObj.TryReadString(length >> 1, out s))
                            {
                                return false;
                            }
                        }

                        value.SetToString(s);
                        break;
                    }

                default:
                    Debug.Assert(false, "Unknown tds type for SqlString!" + type.ToString(CultureInfo.InvariantCulture));
                    break;
            }

            return true;
        }
示例#11
0
        internal bool TryReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, int length, TdsParserStateObject stateObj)
        {
            bool isPlp = md.metaType.IsPlp;
            byte tdsType = md.tdsType;

            Debug.Assert(isPlp || !IsNull(md.metaType, (ulong)length), "null value should not get here!");
            if (isPlp)
            {
                // We must read the column value completely, no matter what length is passed in
                length = Int32.MaxValue;
            }
            switch (tdsType)
            {
                case TdsEnums.SQLDECIMALN:
                case TdsEnums.SQLNUMERICN:
                    if (!TryReadSqlDecimal(value, length, md.precision, md.scale, stateObj))
                    {
                        return false;
                    }
                    break;

                case TdsEnums.SQLUDT:
                    throw SQL.UnsupportedFeatureAndToken(_connHandler, SqlDbType.Udt.ToString());
                case TdsEnums.SQLBINARY:
                case TdsEnums.SQLBIGBINARY:
                case TdsEnums.SQLBIGVARBINARY:
                case TdsEnums.SQLVARBINARY:
                case TdsEnums.SQLIMAGE:
                    byte[] b = null;

                    // If varbinary(max), we only read the first chunk here, expecting the caller to read the rest
                    if (isPlp)
                    {
                        // If we are given -1 for length, then we read the entire value,
                        // otherwise only the requested amount, usually first chunk.
                        int ignored;
                        if (!stateObj.TryReadPlpBytes(ref b, 0, length, out ignored))
                        {
                            return false;
                        }
                    }
                    else
                    {
                        //Debug.Assert(length > 0 && length < (long)(Int32.MaxValue), "Bad length for column");
                        b = new byte[length];
                        if (!stateObj.TryReadByteArray(b, 0, length))
                        {
                            return false;
                        }
                    }

                    value.SqlBinary = new SqlBinary(b, true);   // doesn't copy the byte array

                    break;

                case TdsEnums.SQLCHAR:
                case TdsEnums.SQLBIGCHAR:
                case TdsEnums.SQLVARCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                case TdsEnums.SQLTEXT:
                case TdsEnums.SQLNCHAR:
                case TdsEnums.SQLNVARCHAR:
                case TdsEnums.SQLNTEXT:
                    if (!TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj))
                    {
                        return false;
                    }
                    break;

                case TdsEnums.SQLXMLTYPE:
                    // We store SqlCachedBuffer here, so that we can return either SqlBinary, SqlString or SqlXmlReader.
                    SqlCachedBuffer sqlBuf;
                    if (!SqlCachedBuffer.TryCreate(md, this, stateObj, out sqlBuf))
                    {
                        return false;
                    }

                    value.SqlCachedBuffer = sqlBuf;
                    break;

                case TdsEnums.SQLDATE:
                case TdsEnums.SQLTIME:
                case TdsEnums.SQLDATETIME2:
                case TdsEnums.SQLDATETIMEOFFSET:
                    if (!TryReadSqlDateTime(value, tdsType, length, md.scale, stateObj))
                    {
                        return false;
                    }
                    break;

                default:
                    Debug.Assert(!isPlp, "ReadSqlValue calling ReadSqlValueInternal with plp data");
                    if (!TryReadSqlValueInternal(value, tdsType, length, stateObj))
                    {
                        return false;
                    }
                    break;
            }

            Debug.Assert((stateObj._longlen == 0) && (stateObj._longlenleft == 0), "ReadSqlValue did not read plp field completely, longlen =" + stateObj._longlen.ToString((IFormatProvider)null) + ",longlenleft=" + stateObj._longlenleft.ToString((IFormatProvider)null));
            return true;
        }
示例#12
0
        // Used internally by BulkCopy only
        private bool TryProcessRow(_SqlMetaDataSet columns, object[] buffer, int[] map, TdsParserStateObject stateObj)
        {
            SqlBuffer data = new SqlBuffer();

            for (int i = 0; i < columns.Length; i++)
            {
                _SqlMetaData md = columns[i];
                Debug.Assert(md != null, "_SqlMetaData should not be null for column " + i.ToString(CultureInfo.InvariantCulture));

                bool isNull;
                ulong len;
                if (!TryProcessColumnHeader(md, stateObj, i, out isNull, out len))
                {
                    return false;
                }

                if (isNull)
                {
                    GetNullSqlValue(data, md);
                    buffer[map[i]] = data.SqlValue;
                }
                else
                {
                    // We only read up to 2Gb. Throw if data is larger. Very large data
                    // should be read in chunks in sequential read mode
                    // For Plp columns, we may have gotten only the length of the first chunk
                    if (!TryReadSqlValue(data, md, md.metaType.IsPlp ? (Int32.MaxValue) : (int)len, stateObj))
                    {
                        return false;
                    }
                    buffer[map[i]] = data.SqlValue;
                    if (stateObj._longlen != 0)
                    {
                        throw new SqlTruncateException(Res.GetString(Res.SqlMisc_TruncationMaxDataMessage));
                    }
                }
                data.Clear();
            }

            return true;
        }
示例#13
0
        internal object GetNullSqlValue(SqlBuffer nullVal, SqlMetaDataPriv md)
        {
            switch (md.type)
            {
                case SqlDbType.Real:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Single);
                    break;

                case SqlDbType.Float:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Double);
                    break;

                case SqlDbType.Udt:
                case SqlDbType.Binary:
                case SqlDbType.VarBinary:
                case SqlDbType.Image:
                    nullVal.SqlBinary = SqlBinary.Null;
                    break;

                case SqlDbType.UniqueIdentifier:
                    nullVal.SqlGuid = SqlGuid.Null;
                    break;

                case SqlDbType.Bit:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Boolean);
                    break;

                case SqlDbType.TinyInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Byte);
                    break;

                case SqlDbType.SmallInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int16);
                    break;

                case SqlDbType.Int:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int32);
                    break;

                case SqlDbType.BigInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int64);
                    break;

                case SqlDbType.Char:
                case SqlDbType.VarChar:
                case SqlDbType.NChar:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.NText:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.String);
                    break;

                case SqlDbType.Decimal:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Decimal);
                    break;

                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime);
                    break;

                case SqlDbType.Money:
                case SqlDbType.SmallMoney:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Money);
                    break;

                case SqlDbType.Variant:
                    // DBNull.Value will have to work here
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Empty);
                    break;

                case SqlDbType.Xml:
                    nullVal.SqlCachedBuffer = SqlCachedBuffer.Null;
                    break;

                case SqlDbType.Date:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Date);
                    break;

                case SqlDbType.Time:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Time);
                    break;

                case SqlDbType.DateTime2:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime2);
                    break;

                case SqlDbType.DateTimeOffset:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTimeOffset);
                    break;

                case SqlDbType.Timestamp:
                    break;

                default:
                    Debug.Assert(false, "unknown null sqlType!" + md.type.ToString());
                    break;
            }

            return nullVal;
        }
示例#14
0
        // UDTs and null variants come back via return value, all else is via targetBuffer.
        //  implements SqlClient 2.0-compatible output parameter semantics
        internal static object GetOutputParameterV3Smi(
            SmiEventSink_Default    sink,                   // event sink for errors
            ITypedGettersV3         getters,                // getters interface to grab value from
            int                     ordinal,                // parameter within getters
            SmiMetaData             metaData,               // Getter's type for this ordinal
            SmiContext              context,                // used to obtain scratch streams
            SqlBuffer               targetBuffer            // destination
            ) {
            object result = null;   // Workaround for UDT hack in non-Smi code paths.
            if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
            }
            else {
                switch( metaData.SqlDbType )
                    {
                    case SqlDbType.BigInt:
                        targetBuffer.Int64 = GetInt64_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.Binary:
                    case SqlDbType.Image:
                    case SqlDbType.Timestamp:
                    case SqlDbType.VarBinary:
                        targetBuffer.SqlBinary = GetSqlBinary_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.Bit:
                        targetBuffer.Boolean = GetBoolean_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.NChar:
                    case SqlDbType.NText:
                    case SqlDbType.NVarChar:
                    case SqlDbType.Char:
                    case SqlDbType.VarChar:
                    case SqlDbType.Text:
                        targetBuffer.SetToString( GetString_Unchecked( sink, getters, ordinal ) );
                        break;
                    case SqlDbType.DateTime:
                    case SqlDbType.SmallDateTime: {
                        SqlDateTime dt = new SqlDateTime( GetDateTime_Unchecked( sink, getters, ordinal ) );
                        targetBuffer.SetToDateTime( dt.DayTicks, dt.TimeTicks );
                        break;
                    }
                    case SqlDbType.Decimal: {
                        SqlDecimal dec = GetSqlDecimal_Unchecked( sink, getters, ordinal );
                        targetBuffer.SetToDecimal( dec.Precision, dec.Scale, dec.IsPositive, dec.Data );
                        break;
                    }
                    case SqlDbType.Float:
                        targetBuffer.Double = GetDouble_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.Int:
                        targetBuffer.Int32 = GetInt32_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.Money:
                    case SqlDbType.SmallMoney:
                        targetBuffer.SetToMoney( GetInt64_Unchecked( sink, getters, ordinal) );
                        break;
                    case SqlDbType.Real:
                        targetBuffer.Single = GetSingle_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.UniqueIdentifier:
                        targetBuffer.SqlGuid = new SqlGuid( GetGuid_Unchecked( sink, getters, ordinal ) );
                        break;
                    case SqlDbType.SmallInt:
                        targetBuffer.Int16 = GetInt16_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.TinyInt:
                        targetBuffer.Byte = GetByte_Unchecked( sink, getters, ordinal );
                        break;
                    case SqlDbType.Variant:
                        // For variants, recur using the current value's sqldbtype
                        metaData = getters.GetVariantType( sink, ordinal );
                        sink.ProcessMessagesAndThrow();
                        Debug.Assert( SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!" );
                        GetOutputParameterV3Smi( sink, getters, ordinal, metaData, context, targetBuffer );
                        break;
                    case SqlDbType.Udt:
                        result = GetUdt_LengthChecked( sink, getters, ordinal, metaData );
        				break;
        			case SqlDbType.Xml:
                        targetBuffer.SqlXml = GetSqlXml_Unchecked( sink, getters, ordinal, null );
                        break;
                    default:
                        Debug.Assert( false, "Unexpected SqlDbType" );
                        break;
                    }
            }

            return result;
        }
示例#15
0
        internal bool TryReadSqlValue(SqlBuffer value,
                                      SqlMetaDataPriv md,
                                      int length,
                                      TdsParserStateObject stateObj,
                                      SqlCommandColumnEncryptionSetting columnEncryptionOverride, 
                                      string columnName) {
            bool isPlp = md.metaType.IsPlp;
            byte tdsType = md.tdsType;

            Debug.Assert(isPlp || !IsNull(md.metaType, (ulong)length), "null value should not get here!");
            if (isPlp) {
                // We must read the column value completely, no matter what length is passed in
                length = Int32.MaxValue;
            }

            //DEVNOTE: When modifying the following routines (for deserialization) please pay attention to 
            // deserialization code in DecryptWithKey () method and modify it accordingly.
            switch (tdsType) {
                case TdsEnums.SQLDECIMALN:
                case TdsEnums.SQLNUMERICN:
                    if (!TryReadSqlDecimal(value, length, md.precision, md.scale, stateObj)) {
                        return false;
                    }
                    break;

                case TdsEnums.SQLUDT:
                case TdsEnums.SQLBINARY:
                case TdsEnums.SQLBIGBINARY:
                case TdsEnums.SQLBIGVARBINARY:
                case TdsEnums.SQLVARBINARY:
                case TdsEnums.SQLIMAGE:
                    byte[] b = null;

                    // If varbinary(max), we only read the first chunk here, expecting the caller to read the rest
                    if (isPlp) {
                        // If we are given -1 for length, then we read the entire value,
                        // otherwise only the requested amount, usually first chunk.
                        int ignored;
                        if (!stateObj.TryReadPlpBytes(ref b, 0, length, out ignored)) {
                            return false;
                        }
                    }
                    else {
                        //Debug.Assert(length > 0 && length < (long)(Int32.MaxValue), "Bad length for column");
                        b = new byte[length];
                        if (!stateObj.TryReadByteArray(b, 0, length)) {
                            return false;
                        }
                    }

                    if (md.isEncrypted 
                        && ((columnEncryptionOverride == SqlCommandColumnEncryptionSetting.Enabled
                            || columnEncryptionOverride == SqlCommandColumnEncryptionSetting.ResultSetOnly)
                            || (columnEncryptionOverride == SqlCommandColumnEncryptionSetting.UseConnectionSetting
                                && _connHandler != null && _connHandler.ConnectionOptions != null
                                && _connHandler.ConnectionOptions.ColumnEncryptionSetting == SqlConnectionColumnEncryptionSetting.Enabled))) {
                        try {
                            // CipherInfo is present, decrypt and read
                            byte[] unencryptedBytes = SqlSecurityUtility.DecryptWithKey(b, md.cipherMD, _connHandler.ConnectionOptions.DataSource);

                            if (unencryptedBytes != null) {
                                DeserializeUnencryptedValue(value, unencryptedBytes, md, stateObj, md.NormalizationRuleVersion);
                            }
                        }
                        catch (Exception e) {
                            throw SQL.ColumnDecryptionFailed(columnName, null, e);
                        }
                    }
                    else {
                        value.SqlBinary = new SqlBinary(b, true);   // doesn't copy the byte array
                    }
                    break;

                case TdsEnums.SQLCHAR:
                case TdsEnums.SQLBIGCHAR:
                case TdsEnums.SQLVARCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                case TdsEnums.SQLTEXT:
                case TdsEnums.SQLNCHAR:
                case TdsEnums.SQLNVARCHAR:
                case TdsEnums.SQLNTEXT:
                    if (!TryReadSqlStringValue(value, tdsType, length, md.encoding, isPlp, stateObj)) {
                        return false;
                    }
                    break;

                case TdsEnums.SQLXMLTYPE:
                    // We store SqlCachedBuffer here, so that we can return either SqlBinary, SqlString or SqlXmlReader.
                    SqlCachedBuffer sqlBuf;
                    if (!SqlCachedBuffer.TryCreate(md, this, stateObj, out sqlBuf)) {
                        return false;
                    }

                    value.SqlCachedBuffer = sqlBuf;
                    break;

                case TdsEnums.SQLDATE:
                case TdsEnums.SQLTIME: 
                case TdsEnums.SQLDATETIME2:
                case TdsEnums.SQLDATETIMEOFFSET:
                    if (!TryReadSqlDateTime(value, tdsType, length, md.scale, stateObj)) {
                        return false;
                    }
                    break;
                    
                default:
                    Debug.Assert(!isPlp, "ReadSqlValue calling ReadSqlValueInternal with plp data");
                    if (!TryReadSqlValueInternal(value, tdsType, length, stateObj)) {
                        return false;
                    }
                    break;
            }

            Debug.Assert((stateObj._longlen == 0) && (stateObj._longlenleft == 0), "ReadSqlValue did not read plp field completely, longlen =" + stateObj._longlen.ToString((IFormatProvider)null) + ",longlenleft=" + stateObj._longlenleft.ToString((IFormatProvider)null));
            return true;
        }
示例#16
0
 private SqlBuffer(SqlBuffer value)
 { // Clone
     // value types
     _isNull = value._isNull;
     _type = value._type;
     // ref types - should also be read only unless at some point we allow this data
     // to be mutable, then we will need to copy
     _value = value._value;
     _object = value._object;
 }
示例#17
0
 internal static void Clear(SqlBuffer[] values)
 {
     if (null != values)
     {
         for (int i = 0; i < values.Length; ++i)
         {
             values[i].Clear();
         }
     }
 }
示例#18
0
        private bool TryReadSqlDateTime(SqlBuffer value, byte tdsType, int length, byte scale, TdsParserStateObject stateObj)
        {
            byte[] datetimeBuffer = new byte[length];

            if (!stateObj.TryReadByteArray(datetimeBuffer, 0, length))
            {
                return false;
            }

            switch (tdsType)
            {
                case TdsEnums.SQLDATE:
                    Debug.Assert(length == 3, "invalid length for date type!");
                    value.SetToDate(datetimeBuffer);
                    break;

                case TdsEnums.SQLTIME:
                    Debug.Assert(3 <= length && length <= 5, "invalid length for time type!");
                    value.SetToTime(datetimeBuffer, length, scale);
                    break;

                case TdsEnums.SQLDATETIME2:
                    Debug.Assert(6 <= length && length <= 8, "invalid length for datetime2 type!");
                    value.SetToDateTime2(datetimeBuffer, length, scale);
                    break;

                case TdsEnums.SQLDATETIMEOFFSET:
                    Debug.Assert(8 <= length && length <= 10, "invalid length for datetimeoffset type!");
                    value.SetToDateTimeOffset(datetimeBuffer, length, scale);
                    break;

                default:
                    Debug.Assert(false, "ReadSqlDateTime is called with the wrong tdsType");
                    break;
            }

            return true;
        }
示例#19
0
        //
        // Read in a SQLVariant
        //
        // SQLVariant looks like:
        // struct
        // {
        //      BYTE TypeTag
        //      BYTE cbPropBytes
        //      BYTE[] Properties
        //      BYTE[] DataVal
        // }
        internal bool TryReadSqlVariant(SqlBuffer value, int lenTotal, TdsParserStateObject stateObj)
        {
            // get the SQLVariant type
            byte type;
            if (!stateObj.TryReadByte(out type))
            {
                return false;
            }
            ushort lenMax = 0; // maximum lenData of value inside variant

            // read cbPropBytes
            byte cbPropsActual;
            if (!stateObj.TryReadByte(out cbPropsActual))
            {
                return false;
            }
            MetaType mt = MetaType.GetSqlDataType(type, 0 /*no user datatype*/, 0 /* no lenData, non-nullable type */);
            byte cbPropsExpected = mt.PropBytes;

            int lenConsumed = TdsEnums.SQLVARIANT_SIZE + cbPropsActual; // type, count of propBytes, and actual propBytes
            int lenData = lenTotal - lenConsumed; // length of actual data

            // read known properties and skip unknown properties
            Debug.Assert(cbPropsActual >= cbPropsExpected, "cbPropsActual is less that cbPropsExpected!");

            //
            // now read the value
            //
            switch (type)
            {
                case TdsEnums.SQLBIT:
                case TdsEnums.SQLINT1:
                case TdsEnums.SQLINT2:
                case TdsEnums.SQLINT4:
                case TdsEnums.SQLINT8:
                case TdsEnums.SQLFLT4:
                case TdsEnums.SQLFLT8:
                case TdsEnums.SQLMONEY:
                case TdsEnums.SQLMONEY4:
                case TdsEnums.SQLDATETIME:
                case TdsEnums.SQLDATETIM4:
                case TdsEnums.SQLUNIQUEID:
                    if (!TryReadSqlValueInternal(value, type, lenData, stateObj))
                    {
                        return false;
                    }
                    break;

                case TdsEnums.SQLDECIMALN:
                case TdsEnums.SQLNUMERICN:
                    {
                        Debug.Assert(cbPropsExpected == 2, "SqlVariant: invalid PropBytes for decimal/numeric type!");

                        byte precision;
                        if (!stateObj.TryReadByte(out precision))
                        {
                            return false;
                        }
                        byte scale;
                        if (!stateObj.TryReadByte(out scale))
                        {
                            return false;
                        }

                        // skip over unknown properties
                        if (cbPropsActual > cbPropsExpected)
                        {
                            if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected))
                            {
                                return false;
                            }
                        }

                        if (!TryReadSqlDecimal(value, TdsEnums.MAX_NUMERIC_LEN, precision, scale, stateObj))
                        {
                            return false;
                        }
                        break;
                    }

                case TdsEnums.SQLBIGBINARY:
                case TdsEnums.SQLBIGVARBINARY:
                    //Debug.Assert(TdsEnums.VARNULL == lenData, "SqlVariant: data length for Binary indicates null?");
                    Debug.Assert(cbPropsExpected == 2, "SqlVariant: invalid PropBytes for binary type!");

                    if (!stateObj.TryReadUInt16(out lenMax))
                    {
                        return false;
                    }
                    Debug.Assert(lenMax != TdsEnums.SQL_USHORTVARMAXLEN, "bigvarbinary(max) in a sqlvariant");

                    // skip over unknown properties
                    if (cbPropsActual > cbPropsExpected)
                    {
                        if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected))
                        {
                            return false;
                        }
                    }

                    goto case TdsEnums.SQLBIT;

                case TdsEnums.SQLBIGCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                case TdsEnums.SQLNCHAR:
                case TdsEnums.SQLNVARCHAR:
                    {
                        Debug.Assert(cbPropsExpected == 7, "SqlVariant: invalid PropBytes for character type!");

                        SqlCollation collation;
                        if (!TryProcessCollation(stateObj, out collation))
                        {
                            return false;
                        }

                        if (!stateObj.TryReadUInt16(out lenMax))
                        {
                            return false;
                        }
                        Debug.Assert(lenMax != TdsEnums.SQL_USHORTVARMAXLEN, "bigvarchar(max) or nvarchar(max) in a sqlvariant");

                        // skip over unknown properties
                        if (cbPropsActual > cbPropsExpected)
                        {
                            if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected))
                            {
                                return false;
                            }
                        }

                        Encoding encoding = Encoding.GetEncoding(GetCodePage(collation, stateObj));
                        if (!TryReadSqlStringValue(value, type, lenData, encoding, false, stateObj))
                        {
                            return false;
                        }
                        break;
                    }
                case TdsEnums.SQLDATE:
                    if (!TryReadSqlDateTime(value, type, lenData, 0, stateObj))
                    {
                        return false;
                    }
                    break;

                case TdsEnums.SQLTIME:
                case TdsEnums.SQLDATETIME2:
                case TdsEnums.SQLDATETIMEOFFSET:
                    {
                        Debug.Assert(cbPropsExpected == 1, "SqlVariant: invalid PropBytes for time/datetime2/datetimeoffset type!");

                        byte scale;
                        if (!stateObj.TryReadByte(out scale))
                        {
                            return false;
                        }

                        // skip over unknown properties
                        if (cbPropsActual > cbPropsExpected)
                        {
                            if (!stateObj.TrySkipBytes(cbPropsActual - cbPropsExpected))
                            {
                                return false;
                            }
                        }

                        if (!TryReadSqlDateTime(value, type, lenData, scale, stateObj))
                        {
                            return false;
                        }
                        break;
                    }

                default:
                    Debug.Assert(false, "Unknown tds type in SqlVariant!" + type.ToString(CultureInfo.InvariantCulture));
                    break;
            } // switch

            return true;
        }
 private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result)
 {
     if (SqlDbType.Udt == metaData.SqlDbType)
     {
         result = NullUdtInstance(metaData);
     }
     else
     {
         SqlBuffer.StorageType storageType = __dbTypeToStorageType[(int) metaData.SqlDbType];
         if (storageType == SqlBuffer.StorageType.Empty)
         {
             result = DBNull.Value;
         }
         else if (SqlBuffer.StorageType.SqlBinary == storageType)
         {
             targetBuffer.SqlBinary = SqlBinary.Null;
         }
         else if (SqlBuffer.StorageType.SqlGuid == storageType)
         {
             targetBuffer.SqlGuid = SqlGuid.Null;
         }
         else
         {
             targetBuffer.SetToNullOfType(storageType);
         }
     }
 }
        internal static object GetOutputParameterV200Smi(SmiEventSink_Default sink, SmiTypedGetterSetter getters, int ordinal, SmiMetaData metaData, SmiContext context, SqlBuffer targetBuffer)
        {
            object result = null;
            if (IsDBNull_Unchecked(sink, getters, ordinal))
            {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
                return result;
            }
            switch (metaData.SqlDbType)
            {
                case SqlDbType.Date:
                    targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal));
                    return result;

                case SqlDbType.Time:
                    targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale);
                    return result;

                case SqlDbType.DateTime2:
                    targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale);
                    return result;

                case SqlDbType.DateTimeOffset:
                    targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale);
                    return result;

                case SqlDbType.Variant:
                    metaData = getters.GetVariantType(sink, ordinal);
                    sink.ProcessMessagesAndThrow();
                    GetOutputParameterV200Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    return result;
            }
            return GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
        }
 internal void OnParameterAvailableSmi(SmiParameterMetaData metaData, ITypedGettersV3 parameterValues, int ordinal)
 {
     if (ParameterDirection.Input != metaData.Direction)
     {
         string paramName = null;
         if (ParameterDirection.ReturnValue != metaData.Direction)
         {
             paramName = metaData.Name;
         }
         SqlParameterCollection currentParameterCollection = this.GetCurrentParameterCollection();
         int parameterCount = this.GetParameterCount(currentParameterCollection);
         SqlParameter parameter = this.GetParameterForOutputValueExtraction(currentParameterCollection, paramName, parameterCount);
         if (parameter != null)
         {
             object obj2;
             parameter.LocaleId = (int) metaData.LocaleId;
             parameter.CompareInfo = metaData.CompareOptions;
             SqlBuffer targetBuffer = new SqlBuffer();
             if (this._activeConnection.IsKatmaiOrNewer)
             {
                 obj2 = ValueUtilsSmi.GetOutputParameterV200Smi(this.OutParamEventSink, (SmiTypedGetterSetter) parameterValues, ordinal, metaData, this._smiRequestContext, targetBuffer);
             }
             else
             {
                 obj2 = ValueUtilsSmi.GetOutputParameterV3Smi(this.OutParamEventSink, parameterValues, ordinal, metaData, this._smiRequestContext, targetBuffer);
             }
             if (obj2 != null)
             {
                 parameter.Value = obj2;
             }
             else
             {
                 parameter.SetSqlBuffer(targetBuffer);
             }
         }
     }
 }
示例#23
0
 internal void SetSqlBuffer(SqlBuffer buff)
 {
     _sqlBufferReturnValue = buff;
     _value = null;
     _coercedValue = null;
     _isNull = _sqlBufferReturnValue.IsNull;
     _coercedValueIsDataFeed = false;
     _coercedValueIsSqlType = false;
     _actualSize = -1;
 }
        internal static object GetOutputParameterV3Smi(SmiEventSink_Default sink, ITypedGettersV3 getters, int ordinal, SmiMetaData metaData, SmiContext context, SqlBuffer targetBuffer)
        {
            object result = null;
            if (IsDBNull_Unchecked(sink, getters, ordinal))
            {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
                return result;
            }
            switch (metaData.SqlDbType)
            {
                case SqlDbType.BigInt:
                    targetBuffer.Int64 = GetInt64_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.Binary:
                case SqlDbType.Image:
                case SqlDbType.Timestamp:
                case SqlDbType.VarBinary:
                    targetBuffer.SqlBinary = GetSqlBinary_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.Bit:
                    targetBuffer.Boolean = GetBoolean_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.Char:
                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.VarChar:
                    targetBuffer.SetToString(GetString_Unchecked(sink, getters, ordinal));
                    return result;

                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                {
                    SqlDateTime time = new SqlDateTime(GetDateTime_Unchecked(sink, getters, ordinal));
                    targetBuffer.SetToDateTime(time.DayTicks, time.TimeTicks);
                    return result;
                }
                case SqlDbType.Decimal:
                {
                    SqlDecimal num = GetSqlDecimal_Unchecked(sink, getters, ordinal);
                    targetBuffer.SetToDecimal(num.Precision, num.Scale, num.IsPositive, num.Data);
                    return result;
                }
                case SqlDbType.Float:
                    targetBuffer.Double = GetDouble_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.Int:
                    targetBuffer.Int32 = GetInt32_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.Money:
                case SqlDbType.SmallMoney:
                    targetBuffer.SetToMoney(GetInt64_Unchecked(sink, getters, ordinal));
                    return result;

                case SqlDbType.Real:
                    targetBuffer.Single = GetSingle_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.UniqueIdentifier:
                    targetBuffer.SqlGuid = new SqlGuid(GetGuid_Unchecked(sink, getters, ordinal));
                    return result;

                case SqlDbType.SmallInt:
                    targetBuffer.Int16 = GetInt16_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.TinyInt:
                    targetBuffer.Byte = GetByte_Unchecked(sink, getters, ordinal);
                    return result;

                case SqlDbType.Variant:
                    metaData = getters.GetVariantType(sink, ordinal);
                    sink.ProcessMessagesAndThrow();
                    GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                    return result;

                case (SqlDbType.SmallInt | SqlDbType.Int):
                case (SqlDbType.Text | SqlDbType.Int):
                case (SqlDbType.Xml | SqlDbType.Bit):
                case (SqlDbType.TinyInt | SqlDbType.Int):
                    return result;

                case SqlDbType.Xml:
                    targetBuffer.SqlXml = GetSqlXml_Unchecked(sink, getters, ordinal, null);
                    return result;

                case SqlDbType.Udt:
                    return GetUdt_LengthChecked(sink, getters, ordinal, metaData);
            }
            return result;
        }
示例#25
0
        internal bool TryReadSqlValueInternal(SqlBuffer value, byte tdsType, int length, TdsParserStateObject stateObj)
        {
            switch (tdsType)
            {
                case TdsEnums.SQLBIT:
                case TdsEnums.SQLBITN:
                    Debug.Assert(length == 1, "invalid length for SqlBoolean type!");
                    byte byteValue;
                    if (!stateObj.TryReadByte(out byteValue))
                    {
                        return false;
                    }
                    value.Boolean = (byteValue != 0);
                    break;

                case TdsEnums.SQLINTN:
                    if (length == 1)
                    {
                        goto case TdsEnums.SQLINT1;
                    }
                    else if (length == 2)
                    {
                        goto case TdsEnums.SQLINT2;
                    }
                    else if (length == 4)
                    {
                        goto case TdsEnums.SQLINT4;
                    }
                    else
                    {
                        goto case TdsEnums.SQLINT8;
                    }

                case TdsEnums.SQLINT1:
                    Debug.Assert(length == 1, "invalid length for SqlByte type!");
                    if (!stateObj.TryReadByte(out byteValue))
                    {
                        return false;
                    }
                    value.Byte = byteValue;
                    break;

                case TdsEnums.SQLINT2:
                    Debug.Assert(length == 2, "invalid length for SqlInt16 type!");
                    short shortValue;
                    if (!stateObj.TryReadInt16(out shortValue))
                    {
                        return false;
                    }
                    value.Int16 = shortValue;
                    break;

                case TdsEnums.SQLINT4:
                    Debug.Assert(length == 4, "invalid length for SqlInt32 type!");
                    int intValue;
                    if (!stateObj.TryReadInt32(out intValue))
                    {
                        return false;
                    }
                    value.Int32 = intValue;
                    break;

                case TdsEnums.SQLINT8:
                    Debug.Assert(length == 8, "invalid length for SqlInt64 type!");
                    long longValue;
                    if (!stateObj.TryReadInt64(out longValue))
                    {
                        return false;
                    }
                    value.Int64 = longValue;
                    break;

                case TdsEnums.SQLFLTN:
                    if (length == 4)
                    {
                        goto case TdsEnums.SQLFLT4;
                    }
                    else
                    {
                        goto case TdsEnums.SQLFLT8;
                    }

                case TdsEnums.SQLFLT4:
                    Debug.Assert(length == 4, "invalid length for SqlSingle type!");
                    float singleValue;
                    if (!stateObj.TryReadSingle(out singleValue))
                    {
                        return false;
                    }
                    value.Single = singleValue;
                    break;

                case TdsEnums.SQLFLT8:
                    Debug.Assert(length == 8, "invalid length for SqlDouble type!");
                    double doubleValue;
                    if (!stateObj.TryReadDouble(out doubleValue))
                    {
                        return false;
                    }
                    value.Double = doubleValue;
                    break;

                case TdsEnums.SQLMONEYN:
                    if (length == 4)
                    {
                        goto case TdsEnums.SQLMONEY4;
                    }
                    else
                    {
                        goto case TdsEnums.SQLMONEY;
                    }

                case TdsEnums.SQLMONEY:
                    {
                        int mid;
                        uint lo;

                        if (!stateObj.TryReadInt32(out mid))
                        {
                            return false;
                        }
                        if (!stateObj.TryReadUInt32(out lo))
                        {
                            return false;
                        }

                        long l = (((long)mid) << 0x20) + ((long)lo);

                        value.SetToMoney(l);
                        break;
                    }

                case TdsEnums.SQLMONEY4:
                    if (!stateObj.TryReadInt32(out intValue))
                    {
                        return false;
                    }
                    value.SetToMoney(intValue);
                    break;

                case TdsEnums.SQLDATETIMN:
                    if (length == 4)
                    {
                        goto case TdsEnums.SQLDATETIM4;
                    }
                    else
                    {
                        goto case TdsEnums.SQLDATETIME;
                    }

                case TdsEnums.SQLDATETIM4:
                    ushort daypartShort, timepartShort;
                    if (!stateObj.TryReadUInt16(out daypartShort))
                    {
                        return false;
                    }
                    if (!stateObj.TryReadUInt16(out timepartShort))
                    {
                        return false;
                    }
                    value.SetToDateTime(daypartShort, timepartShort * SqlDateTime.SQLTicksPerMinute);
                    break;

                case TdsEnums.SQLDATETIME:
                    int daypart;
                    uint timepart;
                    if (!stateObj.TryReadInt32(out daypart))
                    {
                        return false;
                    }
                    if (!stateObj.TryReadUInt32(out timepart))
                    {
                        return false;
                    }
                    value.SetToDateTime(daypart, (int)timepart);
                    break;

                case TdsEnums.SQLUNIQUEID:
                    {
                        Debug.Assert(length == 16, "invalid length for SqlGuid type!");

                        byte[] b = new byte[length];

                        if (!stateObj.TryReadByteArray(b, 0, length))
                        {
                            return false;
                        }
                        value.SqlGuid = new SqlGuid(b, true);   // doesn't copy the byte array
                        break;
                    }

                case TdsEnums.SQLBINARY:
                case TdsEnums.SQLBIGBINARY:
                case TdsEnums.SQLBIGVARBINARY:
                case TdsEnums.SQLVARBINARY:
                case TdsEnums.SQLIMAGE:
                    {
                        // Note: Better not come here with plp data!!
                        Debug.Assert(length <= TdsEnums.MAXSIZE);
                        byte[] b = new byte[length];
                        if (!stateObj.TryReadByteArray(b, 0, length))
                        {
                            return false;
                        }
                        value.SqlBinary = new SqlBinary(b, true);   // doesn't copy the byte array

                        break;
                    }

                case TdsEnums.SQLVARIANT:
                    if (!TryReadSqlVariant(value, length, stateObj))
                    {
                        return false;
                    }
                    break;

                default:
                    Debug.Assert(false, "Unknown SqlType!" + tdsType.ToString(CultureInfo.InvariantCulture));
                    break;
            } // switch

            return true;
        }
示例#26
0
        internal static object GetNullSqlValue(
                SqlBuffer nullVal, 
                SqlMetaDataPriv md, 
                SqlCommandColumnEncryptionSetting columnEncryptionSetting,
                SqlInternalConnectionTds connection) {
            SqlDbType type = md.type;

            if (type == SqlDbType.VarBinary && // if its a varbinary
                md.isEncrypted &&// and encrypted
                ShouldHonorTceForRead(columnEncryptionSetting, connection)){
                type = md.baseTI.type; // the use the actual (plaintext) type
            }

            switch (type) {
                case SqlDbType.Real:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Single);
                    break;

                case SqlDbType.Float:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Double);
                    break;

                case SqlDbType.Udt:
                case SqlDbType.Binary:
                case SqlDbType.VarBinary:
                case SqlDbType.Image:
                    nullVal.SqlBinary = SqlBinary.Null;
                    break;

                case SqlDbType.UniqueIdentifier:
                    nullVal.SqlGuid = SqlGuid.Null;
                    break;

                case SqlDbType.Bit:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Boolean);
                    break;

                case SqlDbType.TinyInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Byte);
                    break;

                case SqlDbType.SmallInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int16);
                    break;

                case SqlDbType.Int:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int32);
                    break;

                case SqlDbType.BigInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int64);
                    break;

                case SqlDbType.Char:
                case SqlDbType.VarChar:
                case SqlDbType.NChar:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.NText:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.String);
                    break;

                case SqlDbType.Decimal:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Decimal);
                    break;

                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime);
                    break;

                case SqlDbType.Money:
                case SqlDbType.SmallMoney:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Money);
                    break;

                case SqlDbType.Variant:
                    // DBNull.Value will have to work here
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Empty);
                    break;

                case SqlDbType.Xml:
                    nullVal.SqlCachedBuffer = SqlCachedBuffer.Null;
                    break;

                case SqlDbType.Date:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Date);
                    break;

                case SqlDbType.Time:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Time);
                    break;
                    
                case SqlDbType.DateTime2:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime2);
                    break;
                    
                case SqlDbType.DateTimeOffset:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTimeOffset);
                    break;

                case SqlDbType.Timestamp:
                    // Dev10 Bug #479607 - this should have been the same as SqlDbType.Binary, but it's a rejected breaking change
                    // Dev10 Bug #752790 - don't assert when it does happen
                    break;

                default:
                    Debug.Assert(false, "unknown null sqlType!" + md.type.ToString());
                    break;
            }

            return nullVal;
        }
示例#27
0
        private bool TryReadSqlDecimal(SqlBuffer value, int length, byte precision, byte scale, TdsParserStateObject stateObj)
        {
            byte byteValue;
            if (!stateObj.TryReadByte(out byteValue))
            {
                return false;
            }
            bool fPositive = (1 == byteValue);

            length = checked((int)length - 1);

            int[] bits;
            if (!TryReadDecimalBits(length, stateObj, out bits))
            {
                return false;
            }

            value.SetToDecimal(precision, scale, fPositive, bits);
            return true;
        }
示例#28
0
        // VSTFDevDiv#479681 - Data corruption when sending Katmai Date types to the server via TVP
        // Ensures proper handling on DateTime2 sub type for Sql_Variants and TVPs.
        internal static void SetCompatibleValueV200(
            SmiEventSink_Default sink,
            SmiTypedGetterSetter setters,
            int ordinal,
            SmiMetaData metaData,
            object value,
            ExtendedClrTypeCode typeCode,
            int offset,
            int length,
            ParameterPeekAheadValue peekAhead,
            SqlBuffer.StorageType storageType
            )
        {
            // Ensure caller validated compatibility for types handled directly in this method
            Debug.Assert((ExtendedClrTypeCode.DataTable != typeCode &&
                            ExtendedClrTypeCode.DbDataReader != typeCode &&
                            ExtendedClrTypeCode.IEnumerableOfSqlDataRecord != typeCode) ||
                        CanAccessSetterDirectly(metaData, typeCode), "Un-validated type '" + typeCode + "' for metaData: " + metaData.SqlDbType);

            if (typeCode == ExtendedClrTypeCode.DateTime)
            {
                if (storageType == SqlBuffer.StorageType.DateTime2)
                    SetDateTime2_Checked(sink, setters, ordinal, metaData, (DateTime)value);
                else if (storageType == SqlBuffer.StorageType.Date)
                    SetDate_Checked(sink, setters, ordinal, metaData, (DateTime)value);
                else
                    SetDateTime_Checked(sink, setters, ordinal, metaData, (DateTime)value);
            }
            else
            {
                SetCompatibleValueV200(sink, setters, ordinal, metaData, value, typeCode, offset, length, peekAhead);
            }
        }
示例#29
0
 internal static SqlBuffer[] CreateBufferArray(int length)
 {
     SqlBuffer[] buffers = new SqlBuffer[length];
     for (int i = 0; i < buffers.Length; ++i)
     {
         buffers[i] = new SqlBuffer();
     }
     return buffers;
 }
 internal void SetSqlBuffer(SqlBuffer buff)
 {
     this._sqlBufferReturnValue = buff;
     this._value = null;
     this._coercedValue = null;
     this._udtLoadError = null;
 }
示例#31
0
 private static void GetNullOutputParameterSmi(SmiMetaData metaData, SqlBuffer targetBuffer, ref object result) {
     if (SqlDbType.Udt == metaData.SqlDbType) {
         result = NullUdtInstance(metaData);
     }
     else {
         SqlBuffer.StorageType stype = SqlDbTypeToStorageType(metaData.SqlDbType);
         if ( SqlBuffer.StorageType.Empty == stype ) {
             result = DBNull.Value;
         }
         else if (SqlBuffer.StorageType.SqlBinary == stype) {
             // special case SqlBinary, 'cause tds parser never sets SqlBuffer to null, just to empty!
             targetBuffer.SqlBinary = SqlBinary.Null;
         }
         else if (SqlBuffer.StorageType.SqlGuid == stype) {
             targetBuffer.SqlGuid = SqlGuid.Null;
         }
         else {
             targetBuffer.SetToNullOfType( stype );
         }
     }
 }
示例#32
0
 internal SqlReturnValue() : base()
 {
     value = new SqlBuffer();
 }
示例#33
0
        // UDTs and null variants come back via return value, all else is via targetBuffer.
        //  implements SqlClient 1.1-compatible output parameter semantics
        internal static object GetOutputParameterV200Smi(
            SmiEventSink_Default    sink,                   // event sink for errors
            SmiTypedGetterSetter    getters,                // getters interface to grab value from
            int                     ordinal,                // parameter within getters
            SmiMetaData             metaData,               // Getter's type for this ordinal
            SmiContext              context,                // used to obtain scratch streams
            SqlBuffer               targetBuffer            // destination
            ) {
            object result = null;   // Workaround for UDT hack in non-Smi code paths.
            if ( IsDBNull_Unchecked( sink, getters, ordinal ) ) {
                GetNullOutputParameterSmi(metaData, targetBuffer, ref result);
            }
            else {
                switch(metaData.SqlDbType) {
                    // new types go here
                    case SqlDbType.Variant: // Handle variants specifically for v200, since they could contain v200 types
                        // For variants, recur using the current value's sqldbtype
                        metaData = getters.GetVariantType( sink, ordinal );
                        sink.ProcessMessagesAndThrow();
                        Debug.Assert( SqlDbType.Variant != metaData.SqlDbType, "Variant-within-variant not supposed to be possible!" );
                        GetOutputParameterV200Smi( sink, getters, ordinal, metaData, context, targetBuffer );
                        break;
                    case SqlDbType.Date:
                        targetBuffer.SetToDate(GetDateTime_Unchecked(sink, getters, ordinal));
                        break;
                    case SqlDbType.DateTime2:
                        targetBuffer.SetToDateTime2(GetDateTime_Unchecked(sink, getters, ordinal), metaData.Scale);
                        break;
                    case SqlDbType.Time:
                        targetBuffer.SetToTime(GetTimeSpan_Unchecked(sink, getters, ordinal), metaData.Scale);
                        break;
                    case SqlDbType.DateTimeOffset:
                        targetBuffer.SetToDateTimeOffset(GetDateTimeOffset_Unchecked(sink, getters, ordinal), metaData.Scale);
                        break;
                    default:
                        result = GetOutputParameterV3Smi(sink, getters, ordinal, metaData, context, targetBuffer);
                        break;
                }
            }

            return result;
        }
示例#34
0
        /// <summary>
        /// Deserializes the unencrypted bytes into a value based on the target type info.
        /// </summary>
        internal bool DeserializeUnencryptedValue (SqlBuffer value, byte[] unencryptedBytes, SqlMetaDataPriv md, TdsParserStateObject stateObj, byte normalizationVersion) {
            if (normalizationVersion != 0x01) {
                throw SQL.UnsupportedNormalizationVersion(normalizationVersion);
            }

            byte tdsType = md.baseTI.tdsType;
            int length = unencryptedBytes.Length;

            // For normalized types, the length and scale of the actual type might be different than the value's.
            int denormalizedLength = md.baseTI.length;
            byte denormalizedScale = md.baseTI.scale;

            Debug.Assert (false == md.baseTI.isEncrypted, "Double encryption detected");
            switch (tdsType) {
                // We normalize to allow conversion across data types. All data types below are serialized into a BIGINT.
                case TdsEnums.SQLBIT:
                case TdsEnums.SQLBITN:
                case TdsEnums.SQLINTN:
                case TdsEnums.SQLINT1:
                case TdsEnums.SQLINT2:
                case TdsEnums.SQLINT4:
                case TdsEnums.SQLINT8:
                    Debug.Assert(length == 8, "invalid length for SqlInt64 type!");
                    byte byteValue;
                    long longValue;

                    if (unencryptedBytes.Length != 8) {
                        return false;
                    }

                    longValue = BitConverter.ToInt64(unencryptedBytes, 0);

                    if (tdsType == TdsEnums.SQLBIT ||
                        tdsType == TdsEnums.SQLBITN) {
                        value.Boolean = (longValue != 0);
                        break;
                    }

                    if (tdsType == TdsEnums.SQLINT1 || denormalizedLength == 1)
                        value.Byte = (byte)longValue;
                    else if (tdsType == TdsEnums.SQLINT2 || denormalizedLength == 2)
                        value.Int16 = (Int16)longValue;
                    else if (tdsType == TdsEnums.SQLINT4 || denormalizedLength == 4)
                        value.Int32 = (Int32)longValue;
                    else
                        value.Int64 = longValue;

                    break;

                case TdsEnums.SQLFLTN:
                    if (length == 4) {
                        goto case TdsEnums.SQLFLT4;
                    }
                    else {
                        goto case TdsEnums.SQLFLT8;
                    }

                case TdsEnums.SQLFLT4:
                    Debug.Assert(length == 4, "invalid length for SqlSingle type!");
                    float singleValue;
                    if (unencryptedBytes.Length != 4) {
                        return false;
                    }

                    singleValue = BitConverter.ToSingle(unencryptedBytes, 0);
                    value.Single = singleValue;
                    break;

                case TdsEnums.SQLFLT8:
                    double doubleValue;
                    if (unencryptedBytes.Length != 8) {
                        return false;
                    }

                    doubleValue = BitConverter.ToDouble(unencryptedBytes, 0);
                    value.Double = doubleValue;
                    break;

                // We normalize to allow conversion across data types. SMALLMONEY is serialized into a MONEY.
                case TdsEnums.SQLMONEYN:
                case TdsEnums.SQLMONEY4:
                case TdsEnums.SQLMONEY:
                {
                    int mid;
                    uint lo;

                    if (unencryptedBytes.Length != 8) {
                        return false;
                    }

                    mid = BitConverter.ToInt32(unencryptedBytes, 0);
                    lo = BitConverter.ToUInt32(unencryptedBytes, 4);

                    long l = (((long)mid) << 0x20) + ((long)lo);
                    value.SetToMoney(l);
                    break;
                }

                case TdsEnums.SQLDATETIMN:
                    if (length == 4) {
                        goto case TdsEnums.SQLDATETIM4;
                    }
                    else {
                        goto case TdsEnums.SQLDATETIME;
                    }

                case TdsEnums.SQLDATETIM4:
                    ushort daypartShort, timepartShort;
                    if (unencryptedBytes.Length != 4) {
                        return false;
                    }

                    daypartShort = (UInt16)((unencryptedBytes[1] << 8) + unencryptedBytes[0]);
                    timepartShort = (UInt16)((unencryptedBytes[3] << 8) + unencryptedBytes[2]);
                    value.SetToDateTime(daypartShort, timepartShort * SqlDateTime.SQLTicksPerMinute);
                    break;

                case TdsEnums.SQLDATETIME:
                    int daypart;
                    uint timepart;
                    if (unencryptedBytes.Length != 8) {
                        return false;
                    }

                    daypart = BitConverter.ToInt32(unencryptedBytes, 0);
                    timepart = BitConverter.ToUInt32(unencryptedBytes, 4);
                    value.SetToDateTime(daypart, (int)timepart);
                    break;

                case TdsEnums.SQLUNIQUEID:
                {
                    Debug.Assert(length == 16, "invalid length for SqlGuid type!");
                    value.SqlGuid = new SqlGuid(unencryptedBytes, true);   // doesn't copy the byte array
                    break;
                }

                case TdsEnums.SQLBINARY:
                case TdsEnums.SQLBIGBINARY:
                case TdsEnums.SQLBIGVARBINARY:
                case TdsEnums.SQLVARBINARY:
                case TdsEnums.SQLIMAGE:
                {
                    // Note: Better not come here with plp data!!
                    Debug.Assert(length <= TdsEnums.MAXSIZE, "Plp data decryption attempted");

                    // If this is a fixed length type, pad with zeros to get to the fixed length size.
                    if (tdsType == TdsEnums.SQLBINARY || tdsType == TdsEnums.SQLBIGBINARY) {
                        byte[] bytes = new byte[md.baseTI.length];
                        Buffer.BlockCopy(unencryptedBytes, 0, bytes, 0, unencryptedBytes.Length);
                        unencryptedBytes = bytes;
                    }

                    value.SqlBinary = new SqlBinary(unencryptedBytes, true);   // doesn't copy the byte array
                    break;
                }

                case TdsEnums.SQLDECIMALN:
                case TdsEnums.SQLNUMERICN:
                    // Check the sign from the first byte.
                    int index = 0;
                    byteValue = unencryptedBytes[index++];
                    bool fPositive = (1 == byteValue);

                    // Now read the 4 next integers which contain the actual value.
                    length = checked((int)length-1);
                    int[] bits = new int[4];
                    int decLength = length>>2;
                    for (int i = 0; i < decLength; i++) {
                        // up to 16 bytes of data following the sign byte
                        bits[i] = BitConverter.ToInt32(unencryptedBytes, index);
                        index += 4;
                    }
                    value.SetToDecimal (md.baseTI.precision, md.baseTI.scale, fPositive, bits);
                    break;

                case TdsEnums.SQLCHAR:
                case TdsEnums.SQLBIGCHAR:
                case TdsEnums.SQLVARCHAR:
                case TdsEnums.SQLBIGVARCHAR:
                case TdsEnums.SQLTEXT:
                    {
                        System.Text.Encoding encoding = md.baseTI.encoding;

                        if (null == encoding) {
                            encoding = _defaultEncoding;
                        }

                        if (null == encoding) {
                            ThrowUnsupportedCollationEncountered(stateObj);
                        }

                        string strValue = encoding.GetString(unencryptedBytes, 0, length);

                        // If this is a fixed length type, pad with spaces to get to the fixed length size.
                        if (tdsType == TdsEnums.SQLCHAR || tdsType == TdsEnums.SQLBIGCHAR) {
                            strValue = strValue.PadRight(md.baseTI.length);
                        }

                        value.SetToString(strValue);
                        break;
                    }

                case TdsEnums.SQLNCHAR:
                case TdsEnums.SQLNVARCHAR:
                case TdsEnums.SQLNTEXT:
                    {
                        string strValue = System.Text.Encoding.Unicode.GetString(unencryptedBytes, 0, length);

                        // If this is a fixed length type, pad with spaces to get to the fixed length size.
                        if (tdsType == TdsEnums.SQLNCHAR) {
                            strValue = strValue.PadRight(md.baseTI.length / ADP.CharSize);
                        }

                        value.SetToString(strValue);
                        break;
                    }

                case TdsEnums.SQLDATE:
                    Debug.Assert(length == 3, "invalid length for date type!");
                    value.SetToDate(unencryptedBytes);
                    break;

                case TdsEnums.SQLTIME:
                    // We normalize to maximum precision to allow conversion across different precisions.
                    Debug.Assert(length == 5, "invalid length for time type!");
                    value.SetToTime(unencryptedBytes, length, TdsEnums.MAX_TIME_SCALE, denormalizedScale);
                    break;

                case TdsEnums.SQLDATETIME2:
                    // We normalize to maximum precision to allow conversion across different precisions.
                    Debug.Assert(length == 8, "invalid length for datetime2 type!");
                    value.SetToDateTime2(unencryptedBytes, length, TdsEnums.MAX_TIME_SCALE, denormalizedScale);
                    break;

                case TdsEnums.SQLDATETIMEOFFSET:
                    // We normalize to maximum precision to allow conversion across different precisions.
                    Debug.Assert(length == 10, "invalid length for datetimeoffset type!");
                    value.SetToDateTimeOffset(unencryptedBytes, length, TdsEnums.MAX_TIME_SCALE, denormalizedScale);
                    break;

                default:
                    MetaType metaType = md.baseTI.metaType;

                    // If we don't have a metatype already, construct one to get the proper type name.
                    if (metaType == null) {
                        metaType = MetaType.GetSqlDataType(tdsType, userType:0, length:length);
                    }

                    throw SQL.UnsupportedDatatypeEncryption(metaType.TypeName);
            }

            return true;
        }
 internal SqlReturnValue() : base()
 {
     value = new SqlBuffer();
 }
        internal object GetNullSqlValue(SqlBuffer nullVal, SqlMetaDataPriv md)
        {
            switch (md.type)
            {
                case SqlDbType.BigInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int64);
                    return nullVal;

                case SqlDbType.Binary:
                case SqlDbType.Image:
                case SqlDbType.VarBinary:
                case SqlDbType.Udt:
                    nullVal.SqlBinary = SqlBinary.Null;
                    return nullVal;

                case SqlDbType.Bit:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Boolean);
                    return nullVal;

                case SqlDbType.Char:
                case SqlDbType.NChar:
                case SqlDbType.NText:
                case SqlDbType.NVarChar:
                case SqlDbType.Text:
                case SqlDbType.VarChar:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.String);
                    return nullVal;

                case SqlDbType.DateTime:
                case SqlDbType.SmallDateTime:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime);
                    return nullVal;

                case SqlDbType.Decimal:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Decimal);
                    return nullVal;

                case SqlDbType.Float:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Double);
                    return nullVal;

                case SqlDbType.Int:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int32);
                    return nullVal;

                case SqlDbType.Money:
                case SqlDbType.SmallMoney:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Money);
                    return nullVal;

                case SqlDbType.Real:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Single);
                    return nullVal;

                case SqlDbType.UniqueIdentifier:
                    nullVal.SqlGuid = SqlGuid.Null;
                    return nullVal;

                case SqlDbType.SmallInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Int16);
                    return nullVal;

                case SqlDbType.Timestamp:
                case (SqlDbType.SmallInt | SqlDbType.Int):
                case (SqlDbType.Text | SqlDbType.Int):
                case (SqlDbType.Xml | SqlDbType.Bit):
                case (SqlDbType.TinyInt | SqlDbType.Int):
                case SqlDbType.Structured:
                    return nullVal;

                case SqlDbType.TinyInt:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Byte);
                    return nullVal;

                case SqlDbType.Variant:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Empty);
                    return nullVal;

                case SqlDbType.Xml:
                    nullVal.SqlCachedBuffer = SqlCachedBuffer.Null;
                    return nullVal;

                case SqlDbType.Date:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Date);
                    return nullVal;

                case SqlDbType.Time:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.Time);
                    return nullVal;

                case SqlDbType.DateTime2:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTime2);
                    return nullVal;

                case SqlDbType.DateTimeOffset:
                    nullVal.SetToNullOfType(SqlBuffer.StorageType.DateTimeOffset);
                    return nullVal;
            }
            return nullVal;
        }