public Contents(ModelLoadContext ctx, ISchema input, Func <ColumnType[], string> testTypes) { Contracts.CheckValue(ctx, nameof(ctx)); Contracts.CheckValue(input, nameof(input)); Contracts.CheckValueOrNull(testTypes); Input = input; // *** Binary format *** // int: number of added columns // for each added column // int: id of output column name // int: number of input column names // int[]: ids of input column names int cinfo = ctx.Reader.ReadInt32(); Contracts.CheckDecode(cinfo > 0); Infos = new ColInfo[cinfo]; Names = new string[cinfo]; for (int i = 0; i < cinfo; i++) { Names[i] = ctx.LoadNonEmptyString(); int csrc = ctx.Reader.ReadInt32(); Contracts.CheckDecode(csrc > 0); int[] indices = new int[csrc]; var srcTypes = new ColumnType[csrc]; int? srcSize = 0; for (int j = 0; j < csrc; j++) { string src = ctx.LoadNonEmptyString(); if (!input.TryGetColumnIndex(src, out indices[j])) { throw Contracts.Except("Source column '{0}' is required but not found", src); } srcTypes[j] = input.GetColumnType(indices[j]); var size = srcTypes[j].ValueCount; srcSize = size == 0 ? null : checked (srcSize + size); } if (testTypes != null) { string reason = testTypes(srcTypes); if (reason != null) { throw Contracts.Except("Source columns '{0}' have invalid types: {1}. Source types: '{2}'.", string.Join(", ", indices.Select(k => input.GetColumnName(k))), reason, string.Join(", ", srcTypes.Select(type => type.ToString()))); } } Infos[i] = new ColInfo(srcSize.GetValueOrDefault(), indices, srcTypes); } }
protected ManyToOneColumnBindingsBase(ManyToOneColumn[] column, ISchema input, Func <ColumnType[], string> testTypes) : base(input, true, GetNamesAndSanitize(column)) { Contracts.AssertNonEmpty(column); Contracts.Assert(column.Length == InfoCount); // In lieu of actual protections, I have the following silly asserts, so we can have some // warning if we decide to rename this argument, and so know to change the below hard-coded // standard column name. const string standardColumnArgName = "Column"; Contracts.Assert(nameof(TermTransform.Arguments.Column) == standardColumnArgName); Contracts.Assert(nameof(ConcatTransform.Arguments.Column) == standardColumnArgName); Infos = new ColInfo[InfoCount]; for (int i = 0; i < Infos.Length; i++) { var item = column[i]; Contracts.AssertNonEmpty(item.Name); Contracts.AssertNonEmpty(item.Source); var src = item.Source; var srcIndices = new int[src.Length]; var srcTypes = new ColumnType[src.Length]; int?srcSize = 0; for (int j = 0; j < src.Length; j++) { Contracts.CheckUserArg(!string.IsNullOrWhiteSpace(src[j]), nameof(ManyToOneColumn.Source)); #pragma warning disable MSML_ContractsNameUsesNameof // Unfortunately, there is no base class for the columns bindings. if (!input.TryGetColumnIndex(src[j], out srcIndices[j])) { throw Contracts.ExceptUserArg(standardColumnArgName, "Source column '{0}' not found", src[j]); } #pragma warning restore MSML_ContractsNameUsesNameof srcTypes[j] = input.GetColumnType(srcIndices[j]); var size = srcTypes[j].ValueCount; srcSize = size == 0 ? null : checked (srcSize + size); } if (testTypes != null) { string reason = testTypes(srcTypes); if (reason != null) { #pragma warning disable MSML_ContractsNameUsesNameof // Unfortunately, there is no base class for the columns bindings. throw Contracts.ExceptUserArg(standardColumnArgName, "Column '{0}' has invalid source types: {1}. Source types: '{2}'.", item.Name, reason, string.Join(", ", srcTypes.Select(type => type.ToString()))); #pragma warning restore MSML_ContractsNameUsesNameof } } Infos[i] = new ColInfo(srcSize.GetValueOrDefault(), srcIndices, srcTypes); } }