internal virtual void CopyFrom(SqlMetaDataPriv original) { this.type = original.type; this.tdsType = original.tdsType; this.precision = original.precision; this.scale = original.scale; this.length = original.length; this.collation = original.collation; this.codePage = original.codePage; this.encoding = original.encoding; this.isNullable = original.isNullable; this.isMultiValued = original.isMultiValued; this.udtDatabaseName = original.udtDatabaseName; this.udtSchemaName = original.udtSchemaName; this.udtTypeName = original.udtTypeName; this.udtAssemblyQualifiedName = original.udtAssemblyQualifiedName; this.udtType = original.udtType; this.xmlSchemaCollectionDatabase = original.xmlSchemaCollectionDatabase; this.xmlSchemaCollectionOwningSchema = original.xmlSchemaCollectionOwningSchema; this.xmlSchemaCollectionName = original.xmlSchemaCollectionName; this.metaType = original.metaType; this.structuredTypeDatabaseName = original.structuredTypeDatabaseName; this.structuredTypeSchemaName = original.structuredTypeSchemaName; this.structuredTypeName = original.structuredTypeName; this.structuredFields = original.structuredFields; }
public void Reset() { _database = null; _collation = null; _language = null; if (_deltaDirty) { _delta = new SessionStateRecord[_maxNumberOfSessionStates]; _deltaDirty = false; } _unrecoverableStatesCount = 0; }
internal static bool AreSame(SqlCollation a, SqlCollation b) { if (a == null || b == null) { return(a == b); } else { return(a.info == b.info && a.sortId == b.sortId); } }
public SessionData(SessionData recoveryData) { _initialDatabase = recoveryData._initialDatabase; _initialCollation = recoveryData._initialCollation; _initialLanguage = recoveryData._initialLanguage; _resolvedAliases = recoveryData._resolvedAliases; for (int i = 0; i < _maxNumberOfSessionStates; i++) { if (recoveryData._initialState[i] != null) { _initialState[i] = (byte[])recoveryData._initialState[i].Clone(); } } }
internal virtual void CopyFrom(SqlMetaDataPriv original) { this.type = original.type; this.tdsType = original.tdsType; this.precision = original.precision; this.scale = original.scale; this.length = original.length; this.collation = original.collation; this.codePage = original.codePage; this.encoding = original.encoding; this.isNullable = original.isNullable; this.xmlSchemaCollectionDatabase = original.xmlSchemaCollectionDatabase; this.xmlSchemaCollectionOwningSchema = original.xmlSchemaCollectionOwningSchema; this.xmlSchemaCollectionName = original.xmlSchemaCollectionName; this.metaType = original.metaType; }
internal void Clear() { type = 0; oldLength = 0; newLength = 0; length = 0; newValue = null; oldValue = null; if (newBinValue != null) { Array.Clear(newBinValue, 0, newBinValue.Length); if (newBinRented) { ArrayPool <byte> .Shared.Return(newBinValue); } newBinValue = null; } if (oldBinValue != null) { Array.Clear(oldBinValue, 0, oldBinValue.Length); if (oldBinRented) { ArrayPool <byte> .Shared.Return(oldBinValue); } oldBinValue = null; } newBinRented = false; oldBinRented = false; newLongValue = 0; oldLongValue = 0; newCollation = null; oldCollation = null; newRoutingInfo = null; Next = null; }
// This is in its own method to avoid always allocating the lambda in WriteBulkCopyValue private Task WriteBulkCopyValueSetupContinuation(Task internalWriteTask, Encoding saveEncoding, SqlCollation saveCollation, int saveCodePage, int saveLCID) { return internalWriteTask.ContinueWith<Task>(t => { _defaultEncoding = saveEncoding; _defaultCollation = saveCollation; _defaultCodePage = saveCodePage; _defaultLCID = saveLCID; return t; }, TaskScheduler.Default).Unwrap(); }
internal Task WriteBulkCopyValue(object value, SqlMetaDataPriv metadata, TdsParserStateObject stateObj, bool isSqlType, bool isDataFeed, bool isNull) { Debug.Assert(!isSqlType || value is INullable, "isSqlType is true, but value can not be type cast to an INullable"); Debug.Assert(!isDataFeed ^ value is DataFeed, "Incorrect value for isDataFeed"); Encoding saveEncoding = _defaultEncoding; SqlCollation saveCollation = _defaultCollation; int saveCodePage = _defaultCodePage; int saveLCID = _defaultLCID; Task resultTask = null; Task internalWriteTask = null; if (!(State == TdsParserState.OpenNotLoggedIn || State == TdsParserState.OpenLoggedIn)) { throw ADP.ClosedConnectionError(); } try { if (metadata.encoding != null) { _defaultEncoding = metadata.encoding; } if (metadata.collation != null) { _defaultCollation = metadata.collation; _defaultLCID = _defaultCollation.LCID; } _defaultCodePage = metadata.codePage; MetaType metatype = metadata.metaType; int ccb = 0; int ccbStringBytes = 0; if (isNull) { // For UDT, remember we treat as binary even though it is a PLP if (metatype.IsPlp && (metatype.NullableType != TdsEnums.SQLUDT || metatype.IsLong)) { WriteLong(unchecked((long)TdsEnums.SQL_PLP_NULL), stateObj); } else if (!metatype.IsFixed && !metatype.IsLong && !metatype.IsVarTime) { WriteShort(TdsEnums.VARNULL, stateObj); } else { stateObj.WriteByte(TdsEnums.FIXEDNULL); } return resultTask; } if (!isDataFeed) { switch (metatype.NullableType) { case TdsEnums.SQLBIGBINARY: case TdsEnums.SQLBIGVARBINARY: case TdsEnums.SQLIMAGE: case TdsEnums.SQLUDT: ccb = (isSqlType) ? ((SqlBinary)value).Length : ((byte[])value).Length; break; case TdsEnums.SQLUNIQUEID: ccb = GUID_SIZE; // that's a constant for guid break; case TdsEnums.SQLBIGCHAR: case TdsEnums.SQLBIGVARCHAR: case TdsEnums.SQLTEXT: if (null == _defaultEncoding) { ThrowUnsupportedCollationEncountered(null); // stateObject only when reading } string stringValue = null; if (isSqlType) { stringValue = ((SqlString)value).Value; } else { stringValue = (string)value; } ccb = stringValue.Length; ccbStringBytes = _defaultEncoding.GetByteCount(stringValue); break; case TdsEnums.SQLNCHAR: case TdsEnums.SQLNVARCHAR: case TdsEnums.SQLNTEXT: ccb = ((isSqlType) ? ((SqlString)value).Value.Length : ((string)value).Length) * 2; break; case TdsEnums.SQLXMLTYPE: // Value here could be string or XmlReader if (value is XmlReader) { value = MetaType.GetStringFromXml((XmlReader)value); } ccb = ((isSqlType) ? ((SqlString)value).Value.Length : ((string)value).Length) * 2; break; default: ccb = metadata.length; break; } } else { Debug.Assert(metatype.IsLong && ((metatype.SqlDbType == SqlDbType.VarBinary && value is StreamDataFeed) || ((metatype.SqlDbType == SqlDbType.VarChar || metatype.SqlDbType == SqlDbType.NVarChar) && value is TextDataFeed) || (metatype.SqlDbType == SqlDbType.Xml && value is XmlDataFeed)), "Stream data feed should only be assigned to VarBinary(max), Text data feed should only be assigned to [N]VarChar(max), Xml data feed should only be assigned to XML(max)"); } // Expected the text length in data stream for bulk copy of text, ntext, or image data. // if (metatype.IsLong) { switch (metatype.SqlDbType) { case SqlDbType.Text: case SqlDbType.NText: case SqlDbType.Image: stateObj.WriteByteArray(s_longDataHeader, s_longDataHeader.Length, 0); WriteTokenLength(metadata.tdsType, ccbStringBytes == 0 ? ccb : ccbStringBytes, stateObj); break; case SqlDbType.VarChar: case SqlDbType.NVarChar: case SqlDbType.VarBinary: case SqlDbType.Xml: case SqlDbType.Udt: // plp data WriteUnsignedLong(TdsEnums.SQL_PLP_UNKNOWNLEN, stateObj); break; } } else { WriteTokenLength(metadata.tdsType, ccbStringBytes == 0 ? ccb : ccbStringBytes, stateObj); } if (isSqlType) { internalWriteTask = WriteSqlValue(value, metatype, ccb, ccbStringBytes, 0, stateObj); } else if (metatype.SqlDbType != SqlDbType.Udt || metatype.IsLong) { internalWriteTask = WriteValue(value, metatype, metadata.scale, ccb, ccbStringBytes, 0, stateObj, metadata.length, isDataFeed); if ((internalWriteTask == null) && (_asyncWrite)) { internalWriteTask = stateObj.WaitForAccumulatedWrites(); } Debug.Assert(_asyncWrite || stateObj.WaitForAccumulatedWrites() == null, "Should not have accumulated writes when writing sync"); } else { WriteShort(ccb, stateObj); internalWriteTask = stateObj.WriteByteArray((byte[])value, ccb, 0); } #if DEBUG //In DEBUG mode, when SetAlwaysTaskOnWrite is true, we create a task. Allows us to verify async execution paths. if (_asyncWrite && internalWriteTask == null && SqlBulkCopy.SetAlwaysTaskOnWrite == true) { internalWriteTask = Task.FromResult<object>(null); } #endif if (internalWriteTask != null) { //i.e. the write was async. resultTask = WriteBulkCopyValueSetupContinuation(internalWriteTask, saveEncoding, saveCollation, saveCodePage, saveLCID); } } finally { if (internalWriteTask == null) { _defaultEncoding = saveEncoding; _defaultCollation = saveCollation; _defaultCodePage = saveCodePage; _defaultLCID = saveLCID; } } return resultTask; }
internal int GetCodePage(SqlCollation collation, TdsParserStateObject stateObj) { int codePage = 0; if (0 != collation.sortId) { codePage = TdsEnums.CODE_PAGE_FROM_SORT_ID[collation.sortId]; Debug.Assert(0 != codePage, "GetCodePage accessed codepage array and produced 0!, sortID =" + ((Byte)(collation.sortId)).ToString((IFormatProvider)null)); } else { int cultureId = collation.LCID; bool success = false; try { codePage = LocaleInterop.GetCodePageForLcid(cultureId); // SqlHot 50001398: CodePage can be zero, but we should defer such errors until // we actually MUST use the code page (i.e. don't error if no ANSI data is sent). success = true; } catch (ArgumentException) { } // If we failed, it is quite possible this is because certain culture id's // were removed in Win2k and beyond, however Sql Server still supports them. // In this case we will mask off the sort id (the leading 1). If that fails, // or we have a culture id other than the cases below, we throw an error and // throw away the rest of the results. // Sometimes GetCultureInfo will return CodePage 0 instead of throwing. // This should be treated as an error and functionality switches into the following logic. if (!success || codePage == 0) { switch (cultureId) { case 0x10404: // zh-TW case 0x10804: // zh-CN case 0x10c04: // zh-HK case 0x11004: // zh-SG case 0x11404: // zh-MO case 0x10411: // ja-JP case 0x10412: // ko-KR // If one of the following special cases, mask out sortId and // retry. cultureId = cultureId & 0x03fff; try { codePage = LocaleInterop.GetCodePageForLcid(cultureId); success = true; } catch (ArgumentException) { } break; case 0x827: // Mapping Non-supported Lithuanian code page to supported Lithuanian. try { codePage = LocaleInterop.GetCodePageForLcid(0x427); success = true; } catch (ArgumentException) { } break; default: break; } if (!success) { ThrowUnsupportedCollationEncountered(stateObj); } Debug.Assert(codePage >= 0, string.Format("Invalid code page. codePage: {0}. cultureId: {1}", codePage, cultureId)); } } return codePage; }
private void WriteCollation(SqlCollation collation, TdsParserStateObject stateObj) { if (collation == null) { _physicalStateObj.WriteByte(0); } else { _physicalStateObj.WriteByte(sizeof(UInt32) + sizeof(byte)); WriteUnsignedInt(collation.info, _physicalStateObj); _physicalStateObj.WriteByte(collation.sortId); } }
internal bool TryProcessCollation(TdsParserStateObject stateObj, out SqlCollation collation) { SqlCollation newCollation = new SqlCollation(); if (!stateObj.TryReadUInt32(out newCollation.info)) { collation = null; return false; } if (!stateObj.TryReadByte(out newCollation.sortId)) { collation = null; return false; } collation = newCollation; return true; }
private bool TryProcessEnvChange(int tokenLength, TdsParserStateObject stateObj, out SqlEnvChange[] sqlEnvChange) { // There could be multiple environment change messages following this token. byte byteLength; int processedLength = 0; int nvalues = 0; SqlEnvChange[] envarray = new SqlEnvChange[3]; // Why is this hardcoded to 3? sqlEnvChange = null; while (tokenLength > processedLength) { if (nvalues >= envarray.Length) { // This is a rare path. Most of the time we will have 1 or 2 envchange data streams. SqlEnvChange[] newenvarray = new SqlEnvChange[envarray.Length + 3]; for (int ii = 0; ii < envarray.Length; ii++) newenvarray[ii] = envarray[ii]; envarray = newenvarray; } SqlEnvChange env = new SqlEnvChange(); if (!stateObj.TryReadByte(out env.type)) { return false; } envarray[nvalues] = env; nvalues++; switch (env.type) { case TdsEnums.ENV_DATABASE: case TdsEnums.ENV_LANG: if (!TryReadTwoStringFields(env, stateObj)) { return false; } break; case TdsEnums.ENV_CHARSET: // we copied this behavior directly from luxor - see charset envchange // section from sqlctokn.c if (!TryReadTwoStringFields(env, stateObj)) { return false; } if (env.newValue == TdsEnums.DEFAULT_ENGLISH_CODE_PAGE_STRING) { _defaultCodePage = TdsEnums.DEFAULT_ENGLISH_CODE_PAGE_VALUE; _defaultEncoding = System.Text.Encoding.GetEncoding(_defaultCodePage); } else { Debug.Assert(env.newValue.Length > TdsEnums.CHARSET_CODE_PAGE_OFFSET, "TdsParser.ProcessEnvChange(): charset value received with length <=10"); string stringCodePage = env.newValue.Substring(TdsEnums.CHARSET_CODE_PAGE_OFFSET); _defaultCodePage = Int32.Parse(stringCodePage, NumberStyles.Integer, CultureInfo.InvariantCulture); _defaultEncoding = System.Text.Encoding.GetEncoding(_defaultCodePage); } break; case TdsEnums.ENV_PACKETSIZE: // take care of packet size right here Debug.Assert(stateObj._syncOverAsync, "Should not attempt pends in a synchronous call"); if (!TryReadTwoStringFields(env, stateObj)) { // Changing packet size does not support retry, should not pend" throw SQL.SynchronousCallMayNotPend(); } // Only set on physical state object - this should only occur on LoginAck prior // to MARS initialization! Int32 packetSize = Int32.Parse(env.newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); if (_physicalStateObj.SetPacketSize(packetSize)) { // If packet size changed, we need to release our SNIPackets since // those are tied to packet size of connection. _physicalStateObj.ClearAllWritePackets(); // Update SNI ConsumerInfo value to be resulting packet size UInt32 unsignedPacketSize = (UInt32)packetSize; UInt32 result = SNINativeMethodWrapper.SNISetInfo(_physicalStateObj.Handle, SNINativeMethodWrapper.QTypes.SNI_QUERY_CONN_BUFSIZE, ref unsignedPacketSize); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SNISetInfo"); } break; case TdsEnums.ENV_LOCALEID: if (!TryReadTwoStringFields(env, stateObj)) { return false; } _defaultLCID = Int32.Parse(env.newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); break; case TdsEnums.ENV_COMPFLAGS: if (!TryReadTwoStringFields(env, stateObj)) { return false; } break; case TdsEnums.ENV_COLLATION: Debug.Assert(env.newLength == 5 || env.newLength == 0, "Improper length in new collation!"); if (!stateObj.TryReadByte(out byteLength)) { return false; } env.newLength = byteLength; if (env.newLength == 5) { if (!TryProcessCollation(stateObj, out env.newCollation)) { return false; } // give the parser the new collation values in case parameters don't specify one _defaultCollation = env.newCollation; int newCodePage = GetCodePage(env.newCollation, stateObj); if (newCodePage != _defaultCodePage) { _defaultCodePage = newCodePage; _defaultEncoding = System.Text.Encoding.GetEncoding(_defaultCodePage); } _defaultLCID = env.newCollation.LCID; } if (!stateObj.TryReadByte(out byteLength)) { return false; } env.oldLength = byteLength; Debug.Assert(env.oldLength == 5 || env.oldLength == 0, "Improper length in old collation!"); if (env.oldLength == 5) { if (!TryProcessCollation(stateObj, out env.oldCollation)) { return false; } } env.length = 3 + env.newLength + env.oldLength; break; case TdsEnums.ENV_BEGINTRAN: case TdsEnums.ENV_COMMITTRAN: case TdsEnums.ENV_ROLLBACKTRAN: if (!stateObj.TryReadByte(out byteLength)) { return false; } env.newLength = byteLength; Debug.Assert(env.newLength == 0 || env.newLength == 8, "Improper length for new transaction id!"); if (env.newLength > 0) { if (!stateObj.TryReadInt64(out env.newLongValue)) { return false; } Debug.Assert(env.newLongValue != SqlInternalTransaction.NullTransactionId, "New transaction id is null?"); // the server guarantees that zero is an invalid transaction id. } else { env.newLongValue = SqlInternalTransaction.NullTransactionId; // the server guarantees that zero is an invalid transaction id. } if (!stateObj.TryReadByte(out byteLength)) { return false; } env.oldLength = byteLength; Debug.Assert(env.oldLength == 0 || env.oldLength == 8, "Improper length for old transaction id!"); if (env.oldLength > 0) { if (!stateObj.TryReadInt64(out env.oldLongValue)) { return false; } Debug.Assert(env.oldLongValue != SqlInternalTransaction.NullTransactionId, "Old transaction id is null?"); // the server guarantees that zero is an invalid transaction id. } else { env.oldLongValue = SqlInternalTransaction.NullTransactionId; // the server guarantees that zero is an invalid transaction id. } // env.length includes 1 byte type token env.length = 3 + env.newLength + env.oldLength; break; case TdsEnums.ENV_LOGSHIPNODE: // env.newBinValue is secondary node, env.oldBinValue is witness node // comes before LoginAck so we can't assert this if (!TryReadTwoStringFields(env, stateObj)) { return false; } break; case TdsEnums.ENV_SPRESETCONNECTIONACK: if (!TryReadTwoBinaryFields(env, stateObj)) { return false; } break; case TdsEnums.ENV_USERINSTANCE: if (!TryReadTwoStringFields(env, stateObj)) { return false; } break; case TdsEnums.ENV_ROUTING: ushort newLength; if (!stateObj.TryReadUInt16(out newLength)) { return false; } env.newLength = newLength; byte protocol; if (!stateObj.TryReadByte(out protocol)) { return false; } ushort port; if (!stateObj.TryReadUInt16(out port)) { return false; } UInt16 serverLen; if (!stateObj.TryReadUInt16(out serverLen)) { return false; } string serverName; if (!stateObj.TryReadString(serverLen, out serverName)) { return false; } env.newRoutingInfo = new RoutingInfo(protocol, port, serverName); UInt16 oldLength; if (!stateObj.TryReadUInt16(out oldLength)) { return false; } if (!stateObj.TrySkipBytes(oldLength)) { return false; } env.length = env.newLength + oldLength + 5; // 5=2*sizeof(UInt16)+sizeof(byte) [token+newLength+oldLength] break; // ENVCHANGE tokens not supported by CoreCLR case TdsEnums.ENV_ENLISTDTC: case TdsEnums.ENV_DEFECTDTC: case TdsEnums.ENV_TRANSACTIONENDED: case TdsEnums.ENV_PROMOTETRANSACTION: case TdsEnums.ENV_TRANSACTIONMANAGERADDRESS: throw SQL.UnsupportedFeatureAndToken(_connHandler, ((TdsEnums.EnvChangeType)env.type).ToString()); default: Debug.Assert(false, "Unknown environment change token: " + env.type); break; } processedLength += env.length; } sqlEnvChange = envarray; return true; }
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); } }
internal int GetCodePage(SqlCollation collation, TdsParserStateObject stateObj) { int aNSICodePage = 0; if (collation.sortId != 0) { return TdsEnums.CODE_PAGE_FROM_SORT_ID[collation.sortId]; } int lCID = collation.LCID; bool flag = false; try { aNSICodePage = CultureInfo.GetCultureInfo(lCID).TextInfo.ANSICodePage; flag = true; } catch (ArgumentException exception3) { ADP.TraceExceptionWithoutRethrow(exception3); } if (!flag || (aNSICodePage == 0)) { CultureInfo info = null; switch (lCID) { case 0x10411: case 0x10412: case 0x10404: case 0x11004: case 0x11404: case 0x10804: case 0x10c04: lCID &= 0x3fff; try { info = new CultureInfo(lCID); flag = true; } catch (ArgumentException exception2) { ADP.TraceExceptionWithoutRethrow(exception2); } break; case 0x827: try { info = new CultureInfo(0x427); flag = true; } catch (ArgumentException exception) { ADP.TraceExceptionWithoutRethrow(exception); } break; } if (!flag) { this.ThrowUnsupportedCollationEncountered(stateObj); } if (info != null) { aNSICodePage = info.TextInfo.ANSICodePage; } } return aNSICodePage; }
static internal bool AreSame(SqlCollation a, SqlCollation b) { if (a == null || b == null) { return a == b; } else { return a.info == b.info && a.sortId == b.sortId; } }
internal virtual void CopyFrom(SqlMetaDataPriv original) { this.type = original.type; this.tdsType = original.tdsType; this.precision = original.precision; this.scale = original.scale; this.length = original.length; this.collation = original.collation; this.codePage = original.codePage; this.encoding = original.encoding; this.isNullable = original.isNullable; this.isMultiValued = original.isMultiValued; this.udtDatabaseName = original.udtDatabaseName; this.udtSchemaName = original.udtSchemaName; this.udtTypeName = original.udtTypeName; this.udtAssemblyQualifiedName = original.udtAssemblyQualifiedName; this.udtType = original.udtType; this.xmlSchemaCollectionDatabase = original.xmlSchemaCollectionDatabase; this.xmlSchemaCollectionOwningSchema = original.xmlSchemaCollectionOwningSchema; this.xmlSchemaCollectionName = original.xmlSchemaCollectionName; this.metaType = original.metaType; // this.structuredTypeDatabaseName = original.structuredTypeDatabaseName; this.structuredTypeSchemaName = original.structuredTypeSchemaName; this.structuredTypeName = original.structuredTypeName; this.structuredFields = original.structuredFields; }
// 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 int GetCodePage(SqlCollation collation, TdsParserStateObject stateObj) { int codePage = 0; if (0 != collation.sortId) { codePage = TdsEnums.CODE_PAGE_FROM_SORT_ID[collation.sortId]; Debug.Assert(0 != codePage, "GetCodePage accessed codepage array and produced 0!, sortID =" + ((Byte)(collation.sortId)).ToString((IFormatProvider)null)); } else { int cultureId = collation.LCID; bool success = false; try { codePage = CultureInfo.GetCultureInfo(cultureId).TextInfo.ANSICodePage; // SqlHot 50001398: CodePage can be zero, but we should defer such errors until // we actually MUST use the code page (i.e. don't error if no ANSI data is sent). success = true; } catch (ArgumentException e) { ADP.TraceExceptionWithoutRethrow(e); } // If we failed, it is quite possible this is because certain culture id's // were removed in Win2k and beyond, however Sql Server still supports them. // There is a workaround for the culture id's listed below, which is to mask // off the sort id (the leading 1). If that fails, or we have a culture id // other than the special cases below, we throw an error and throw away the // rest of the results. For additional info, see MDAC 65963. // SqlHot 50001398: Sometimes GetCultureInfo will return CodePage 0 instead of throwing. // treat this as an error also, and switch into the special-case logic. if (!success || codePage == 0) { CultureInfo ci = null; switch (cultureId) { case 0x10404: // zh-TW case 0x10804: // zh-CN case 0x10c04: // zh-HK case 0x11004: // zh-SG case 0x11404: // zh-MO case 0x10411: // ja-JP case 0x10412: // ko-KR // If one of the following special cases, mask out sortId and // retry. cultureId = cultureId & 0x03fff; try { ci = new CultureInfo(cultureId); success = true; } catch (ArgumentException e) { ADP.TraceExceptionWithoutRethrow(e); } break; case 0x827: // Non-supported Lithuanian code page, map it to supported Lithuanian. try { ci = new CultureInfo(0x427); success = true; } catch (ArgumentException e) { ADP.TraceExceptionWithoutRethrow(e); } break; default: break; } // I don't believe we should still be in failure case, but just in case. if (!success) { ThrowUnsupportedCollationEncountered(stateObj); } if (null != ci) { codePage = ci.TextInfo.ANSICodePage; } } } return codePage; }
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); } }
// 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); } }
private SqlEnvChange[] ProcessEnvChange(int tokenLength, TdsParserStateObject stateObj) { int num4 = 0; int index = 0; SqlEnvChange[] changeArray = new SqlEnvChange[3]; while (tokenLength > num4) { int num3; ushort num5; if (index >= changeArray.Length) { SqlEnvChange[] changeArray2 = new SqlEnvChange[changeArray.Length + 3]; for (int i = 0; i < changeArray.Length; i++) { changeArray2[i] = changeArray[i]; } changeArray = changeArray2; } SqlEnvChange env = new SqlEnvChange { type = stateObj.ReadByte() }; changeArray[index] = env; index++; switch (env.type) { case 1: case 2: this.ReadTwoStringFields(env, stateObj); goto Label_03E0; case 3: this.ReadTwoStringFields(env, stateObj); if (!(env.newValue == "iso_1")) { break; } this._defaultCodePage = 0x4e4; this._defaultEncoding = Encoding.GetEncoding(this._defaultCodePage); goto Label_03E0; case 4: { this.ReadTwoStringFields(env, stateObj); int size = int.Parse(env.newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); if (this._physicalStateObj.SetPacketSize(size)) { this._physicalStateObj._sniPacket.Dispose(); uint qInfo = (uint) size; SNINativeMethodWrapper.SNISetInfo(this._physicalStateObj.Handle, SNINativeMethodWrapper.QTypes.SNI_QUERY_CONN_BUFSIZE, ref qInfo); this._physicalStateObj._sniPacket = new SNIPacket(this._physicalStateObj.Handle); } goto Label_03E0; } case 5: this.ReadTwoStringFields(env, stateObj); this._defaultLCID = int.Parse(env.newValue, NumberStyles.Integer, CultureInfo.InvariantCulture); goto Label_03E0; case 6: this.ReadTwoStringFields(env, stateObj); goto Label_03E0; case 7: env.newLength = stateObj.ReadByte(); if (env.newLength == 5) { env.newCollation = this.ProcessCollation(stateObj); this._defaultCollation = env.newCollation; int codePage = this.GetCodePage(env.newCollation, stateObj); if (codePage != this._defaultCodePage) { this._defaultCodePage = codePage; this._defaultEncoding = Encoding.GetEncoding(this._defaultCodePage); } this._defaultLCID = env.newCollation.LCID; } env.oldLength = stateObj.ReadByte(); if (env.oldLength == 5) { env.oldCollation = this.ProcessCollation(stateObj); } env.length = (3 + env.newLength) + env.oldLength; goto Label_03E0; case 8: case 9: case 10: case 11: case 12: case 0x11: env.newLength = stateObj.ReadByte(); if (env.newLength <= 0) { goto Label_02B0; } env.newLongValue = stateObj.ReadInt64(); goto Label_02B8; case 13: this.ReadTwoStringFields(env, stateObj); goto Label_03E0; case 15: env.newLength = stateObj.ReadInt32(); env.newBinValue = new byte[env.newLength]; stateObj.ReadByteArray(env.newBinValue, 0, env.newLength); env.oldLength = stateObj.ReadByte(); env.length = 5 + env.newLength; goto Label_03E0; case 0x10: case 0x12: this.ReadTwoBinaryFields(env, stateObj); goto Label_03E0; case 0x13: this.ReadTwoStringFields(env, stateObj); goto Label_03E0; case 20: { env.newLength = stateObj.ReadUInt16(); byte protocol = stateObj.ReadByte(); ushort port = stateObj.ReadUInt16(); ushort length = stateObj.ReadUInt16(); string servername = stateObj.ReadString(length); env.newRoutingInfo = new RoutingInfo(protocol, port, servername); num5 = stateObj.ReadUInt16(); num3 = 0; goto Label_03C9; } default: goto Label_03E0; } string s = env.newValue.Substring(2); this._defaultCodePage = int.Parse(s, NumberStyles.Integer, CultureInfo.InvariantCulture); this._defaultEncoding = Encoding.GetEncoding(this._defaultCodePage); goto Label_03E0; Label_02B0: env.newLongValue = 0L; Label_02B8: env.oldLength = stateObj.ReadByte(); if (env.oldLength > 0) { env.oldLongValue = stateObj.ReadInt64(); } else { env.oldLongValue = 0L; } env.length = (3 + env.newLength) + env.oldLength; goto Label_03E0; Label_03BC: stateObj.ReadByte(); num3++; Label_03C9: if (num3 < num5) { goto Label_03BC; } env.length = (env.newLength + num5) + 5; Label_03E0: num4 += env.length; } return changeArray; }