Example #1
0
        /// <summary>
        /// Detect the boundary between tOther and tNext in the reader.
        /// </summary>
        /// <param name="reader">The reader to analyze.</param>
        /// <param name="structure">The structure of the record we are reading.</param>
        /// <param name="columnIndex">The index of the next column to look at.</param>
        /// <param name="types">The list of types to be deserialized.</param>
        /// <param name="typeIndex">The index of the current type being deserialized.</param>
        /// <returns>The end boundary for the current object.</returns>
        private static int DetectEndColumn(
            IDataReader reader,
            IRecordStructure structure,
            int columnIndex,
            Type[] types,
            int typeIndex)
        {
            Type currentType = types[typeIndex];
            Type nextType    = (typeIndex + 1 < types.Length) ? types[typeIndex + 1] : typeof(object);

            // if the current type is atomic, it's only one column wide
            if (TypeHelper.IsAtomicType(currentType))
            {
                return(columnIndex + 1);
            }

            // if the caller specified columns to split on then use that
            var splitColumns = structure.GetSplitColumns();

            if (splitColumns != null)
            {
                // go through all of the remaining types
                for (int t = typeIndex + 1; t < types.Length; t++)
                {
                    // get the column name for the id of the next type
                    string columnName;
                    if (!splitColumns.TryGetValue(types[t], out columnName))
                    {
                        continue;
                    }

                    for (; columnIndex < reader.FieldCount; columnIndex++)
                    {
                        if (String.Compare(columnName, reader.GetName(columnIndex), StringComparison.OrdinalIgnoreCase) == 0)
                        {
                            return(columnIndex);
                        }
                    }
                }
            }

            // get the setters for the class and the next class
            // for the current set, we want to simulate what we will actually use, so we only want to use unique matches
            // for the next set, we want to find all applicable matches, so we can detect the transition to the next object
            int fieldCount  = reader.FieldCount;
            int columnsLeft = fieldCount - columnIndex;

            var currentSetters = MapColumns(currentType, reader, columnIndex, columnsLeft, structure);

            // go through the remaining types to see if anything will claim the column
            int i = 0;

            for (; columnIndex + i < fieldCount; i++)
            {
                // if there is a setter for the current column, keep going
                if (currentSetters[i] != null)
                {
                    continue;
                }

                // there isn't a setting for the column, so see if any other type can claim the column
                for (int t = typeIndex + 1; t < types.Length; t++)
                {
                    // if the next type is an atomic type, then read it
                    if (TypeHelper.IsAtomicType(types[t]))
                    {
                        return(columnIndex + i);
                    }

                    // one of the next types can claim the column, so quit now
                    var nextSetters = MapColumns(types[t], reader, columnIndex + i, 1, structure);
                    if (nextSetters[0] != null)
                    {
                        return(columnIndex + i);
                    }
                }
            }

            return(columnIndex + i);
        }
		/// <summary>
		/// Detect the boundary between tOther and tNext in the reader.
		/// </summary>
		/// <param name="reader">The reader to analyze.</param>
		/// <param name="structure">The structure of the record we are reading.</param>
		/// <param name="columnIndex">The index of the next column to look at.</param>
		/// <param name="types">The list of types to be deserialized.</param>
		/// <param name="typeIndex">The index of the current type being deserialized.</param>
		/// <returns>The end boundary for the current object.</returns>
		private static int DetectEndColumn(
			IDataReader reader,
			IRecordStructure structure,
			int columnIndex,
			Type[] types,
			int typeIndex)
		{
			Type currentType = types[typeIndex];
			Type nextType = (typeIndex + 1 < types.Length) ? types[typeIndex + 1] : typeof(object);

			// if the caller specified columns to split on then use that
			var splitColumns = structure.GetSplitColumns();
			if (splitColumns != null)
			{
				// go through all of the remaining types
				for (int t = typeIndex + 1; t < types.Length; t++)
				{
					// get the column name for the id of the next type
					string columnName;
					if (!splitColumns.TryGetValue(types[t], out columnName))
						continue;
						
					for (; columnIndex < reader.FieldCount; columnIndex++)
					{
						if (String.Compare(columnName, reader.GetName(columnIndex), StringComparison.OrdinalIgnoreCase) == 0)
							return columnIndex;
					}
				}
			}

			// get the setters for the class and the next class
			// for the current set, we want to simulate what we will actually use, so we only want to use unique matches
			// for the next set, we want to find all applicable matches, so we can detect the transition to the next object
			int fieldCount = reader.FieldCount;
			int columnsLeft = fieldCount - columnIndex;
			var currentSetters = ColumnMapping.Tables.CreateMapping(currentType, reader, null, null, structure, columnIndex, columnsLeft, true);

			// go through the remaining types to see if anything will claim the column
			int i = 0;
			for (; columnIndex + i < fieldCount; i++)
			{
				// if there is a setter for the current column, keep going
				if (currentSetters[i] != null)
					continue;

				// there isn't a setting for the column, so see if any other type can claim the column
				for (int t = typeIndex + 1; t < types.Length; t++)
				{
					// one of the next types can claim the column, so quit now
					var nextSetters = ColumnMapping.Tables.CreateMapping(types[t], reader, null, null, structure, columnIndex + i, 1, false);
					if (nextSetters[0] != null)
						return columnIndex + i;
				}
			}

			return columnIndex + i;
		}