Esempio n. 1
0
        // Semantics for SetChars are to modify existing value, not overwrite
        //  Use in combination with SetLength to ensure overwriting when necessary
        // valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
        //      (NVarChar and global clr collation assumed for variants)
        internal int SetChars(long fieldOffset, char[] buffer, int bufferOffset, int length)
        {
            Debug.Assert(
                SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetChars));

            // ANSI types must convert to byte[] because that's the tool we have.
            if (MetaDataUtilsSmi.IsAnsiType(_metaData.SqlDbType))
            {
                if (null == _encoder)
                {
                    _encoder = _stateObj.Parser._defaultEncoding.GetEncoder();
                }
                byte[] bytes = new byte[_encoder.GetByteCount(buffer, bufferOffset, length, false)];
                _encoder.GetBytes(buffer, bufferOffset, length, bytes, 0, false);
                SetBytesNoOffsetHandling(fieldOffset, bytes, 0, bytes.Length);
            }
            else
            {
                CheckSettingOffset(fieldOffset);

                // Send via PLP format if we can.
                if (_isPlp)
                {
                    // Handle initial PLP markers
                    if (!_plpUnknownSent)
                    {
                        _stateObj.Parser.WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, _stateObj);
                        _plpUnknownSent = true;
                    }

                    // Write chunk length
                    _stateObj.Parser.WriteInt(length * ADP.CharSize, _stateObj);
                    _stateObj.Parser.WriteCharArray(buffer, length, bufferOffset, _stateObj);
                }
                else
                {
                    // Non-plp data must be sent in one chunk for now.
#if DEBUG
                    Debug.Assert(0 == _currentOffset, "SetChars doesn't yet support chunking for non-plp data: " + _currentOffset);
#endif

                    if (SqlDbType.Variant == _metaData.SqlDbType)
                    {
                        _stateObj.Parser.WriteSqlVariantValue(new string(buffer, bufferOffset, length), length, 0, _stateObj);
                    }
                    else
                    {
                        Debug.Assert(!MetaType.GetMetaTypeFromSqlDbType(_metaData.SqlDbType, _metaData.IsMultiValued).IsLong,
                                     "We're assuming long length types are sent as PLP. SqlDbType = " + _metaData.SqlDbType);
                        _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj);
                        _stateObj.Parser.WriteCharArray(buffer, length, bufferOffset, _stateObj);
                    }
                }
            }

#if DEBUG
            _currentOffset += length;
#endif
            return(length);
        }
 internal int SetChars(long fieldOffset, char[] buffer, int bufferOffset, int length)
 {
     if (MetaDataUtilsSmi.IsAnsiType(this._metaData.SqlDbType))
     {
         if (this._encoder == null)
         {
             this._encoder = this._stateObj.Parser._defaultEncoding.GetEncoder();
         }
         byte[] bytes = new byte[this._encoder.GetByteCount(buffer, bufferOffset, length, false)];
         this._encoder.GetBytes(buffer, bufferOffset, length, bytes, 0, false);
         this.SetBytesNoOffsetHandling(fieldOffset, bytes, 0, bytes.Length);
         return(length);
     }
     if (this._isPlp)
     {
         if (!this._plpUnknownSent)
         {
             this._stateObj.Parser.WriteUnsignedLong(18446744073709551614L, this._stateObj);
             this._plpUnknownSent = true;
         }
         this._stateObj.Parser.WriteInt(length * ADP.CharSize, this._stateObj);
         this._stateObj.Parser.WriteCharArray(buffer, length, bufferOffset, this._stateObj);
         return(length);
     }
     if (SqlDbType.Variant == this._metaData.SqlDbType)
     {
         this._stateObj.Parser.WriteSqlVariantValue(new string(buffer, bufferOffset, length), length, 0, this._stateObj);
         return(length);
     }
     this._stateObj.Parser.WriteShort(length * ADP.CharSize, this._stateObj);
     this._stateObj.Parser.WriteCharArray(buffer, length, bufferOffset, this._stateObj);
     return(length);
 }
 internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md)
 {
     this._stateObj       = stateObj;
     this._metaData       = md;
     this._isPlp          = MetaDataUtilsSmi.IsPlpFormat(md);
     this._plpUnknownSent = false;
     this._encoder        = null;
 }
Esempio n. 4
0
        private int _currentOffset;                      // for chunking, verify that caller is using correct offsets
#endif

        #endregion

        #region Exposed Construct/factory methods

        internal TdsValueSetter(TdsParserStateObject stateObj, SmiMetaData md)
        {
            _stateObj       = stateObj;
            _metaData       = md;
            _isPlp          = MetaDataUtilsSmi.IsPlpFormat(md);
            _plpUnknownSent = false;
            _encoder        = null;
#if DEBUG
            _currentOffset = 0;
#endif
        }
Esempio n. 5
0
        // valid for character types: Char, VarChar, Text, NChar, NVarChar, NText
        internal void SetString(string value, int offset, int length)
        {
            Debug.Assert(
                SmiXetterAccessMap.IsSetterAccessValid(_metaData, SmiXetterTypeCode.XetString));

            // ANSI types must convert to byte[] because that's the tool we have.
            if (MetaDataUtilsSmi.IsAnsiType(_metaData.SqlDbType))
            {
                byte[] bytes;
                // Optimize for common case of writing entire string
                if (offset == 0 && value.Length <= length)
                {
                    bytes = _stateObj.Parser._defaultEncoding.GetBytes(value);
                }
                else
                {
                    char[] chars = value.ToCharArray(offset, length);
                    bytes = _stateObj.Parser._defaultEncoding.GetBytes(chars);
                }
                SetBytes(0, bytes, 0, bytes.Length);
                SetBytesLength(bytes.Length);
            }
            else if (SqlDbType.Variant == _metaData.SqlDbType)
            {
                Debug.Assert(null != _variantType && SqlDbType.NVarChar == _variantType.SqlDbType, "Invalid variant type");

                SqlCollation collation = new SqlCollation();
                collation.LCID = checked ((int)_variantType.LocaleId);
                collation.SqlCompareOptions = _variantType.CompareOptions;

                if (length * ADP.CharSize > TdsEnums.TYPE_SIZE_LIMIT)
                { // send as varchar for length greater than 4000
                    byte[] bytes;
                    // Optimize for common case of writing entire string
                    if (offset == 0 && value.Length <= length)
                    {
                        bytes = _stateObj.Parser._defaultEncoding.GetBytes(value);
                    }
                    else
                    {
                        bytes = _stateObj.Parser._defaultEncoding.GetBytes(value.ToCharArray(offset, length));
                    }
                    _stateObj.Parser.WriteSqlVariantHeader(9 + bytes.Length, TdsEnums.SQLBIGVARCHAR, 7, _stateObj);
                    _stateObj.Parser.WriteUnsignedInt(collation.info, _stateObj); // propbytes: collation.Info
                    _stateObj.WriteByte(collation.sortId);                        // propbytes: collation.SortId
                    _stateObj.Parser.WriteShort(bytes.Length, _stateObj);         // propbyte: varlen
                    _stateObj.WriteByteArray(bytes, bytes.Length, 0);
                }
                else
                {
                    _stateObj.Parser.WriteSqlVariantHeader(9 + length * ADP.CharSize, TdsEnums.SQLNVARCHAR, 7, _stateObj);
                    _stateObj.Parser.WriteUnsignedInt(collation.info, _stateObj);  // propbytes: collation.Info
                    _stateObj.WriteByte(collation.sortId);                         // propbytes: collation.SortId
                    _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj); // propbyte: varlen
                    _stateObj.Parser.WriteString(value, length, offset, _stateObj);
                }
                _variantType = null;
            }
            else if (_isPlp)
            {
                // Send the string as a complete PLP chunk.
                _stateObj.Parser.WriteLong(length * ADP.CharSize, _stateObj);   // PLP total length
                _stateObj.Parser.WriteInt(length * ADP.CharSize, _stateObj);    // Chunk length
                _stateObj.Parser.WriteString(value, length, offset, _stateObj); // Data
                if (length != 0)
                {
                    _stateObj.Parser.WriteInt(TdsEnums.SQL_PLP_CHUNK_TERMINATOR, _stateObj); // Terminator
                }
            }
            else
            {
                _stateObj.Parser.WriteShort(length * ADP.CharSize, _stateObj);
                _stateObj.Parser.WriteString(value, length, offset, _stateObj);
            }
        }
 internal void SetString(string value, int offset, int length)
 {
     if (MetaDataUtilsSmi.IsAnsiType(this._metaData.SqlDbType))
     {
         byte[] bytes;
         if ((offset == 0) && (value.Length <= length))
         {
             bytes = this._stateObj.Parser._defaultEncoding.GetBytes(value);
         }
         else
         {
             char[] chars = value.ToCharArray(offset, length);
             bytes = this._stateObj.Parser._defaultEncoding.GetBytes(chars);
         }
         this.SetBytes(0L, bytes, 0, bytes.Length);
         this.SetBytesLength((long)bytes.Length);
     }
     else if (SqlDbType.Variant == this._metaData.SqlDbType)
     {
         SqlCollation collation = new SqlCollation {
             LCID = (int)this._variantType.LocaleId,
             SqlCompareOptions = this._variantType.CompareOptions
         };
         if ((length * ADP.CharSize) > 0x1f40)
         {
             byte[] buffer;
             if ((offset == 0) && (value.Length <= length))
             {
                 buffer = this._stateObj.Parser._defaultEncoding.GetBytes(value);
             }
             else
             {
                 buffer = this._stateObj.Parser._defaultEncoding.GetBytes(value.ToCharArray(offset, length));
             }
             this._stateObj.Parser.WriteSqlVariantHeader(9 + buffer.Length, 0xa7, 7, this._stateObj);
             this._stateObj.Parser.WriteUnsignedInt(collation.info, this._stateObj);
             this._stateObj.Parser.WriteByte(collation.sortId, this._stateObj);
             this._stateObj.Parser.WriteShort(buffer.Length, this._stateObj);
             this._stateObj.Parser.WriteByteArray(buffer, buffer.Length, 0, this._stateObj);
         }
         else
         {
             this._stateObj.Parser.WriteSqlVariantHeader(9 + (length * ADP.CharSize), 0xe7, 7, this._stateObj);
             this._stateObj.Parser.WriteUnsignedInt(collation.info, this._stateObj);
             this._stateObj.Parser.WriteByte(collation.sortId, this._stateObj);
             this._stateObj.Parser.WriteShort(length * ADP.CharSize, this._stateObj);
             this._stateObj.Parser.WriteString(value, length, offset, this._stateObj);
         }
         this._variantType = null;
     }
     else if (this._isPlp)
     {
         this._stateObj.Parser.WriteLong((long)(length * ADP.CharSize), this._stateObj);
         this._stateObj.Parser.WriteInt(length * ADP.CharSize, this._stateObj);
         this._stateObj.Parser.WriteString(value, length, offset, this._stateObj);
         if (length != 0)
         {
             this._stateObj.Parser.WriteInt(0, this._stateObj);
         }
     }
     else
     {
         this._stateObj.Parser.WriteShort(length * ADP.CharSize, this._stateObj);
         this._stateObj.Parser.WriteString(value, length, offset, this._stateObj);
     }
 }