public static KeyRange Parse(string str) { Contracts.AssertValue(str); var res = new KeyRange(); if (res.TryParse(str)) { return(res); } return(null); }
public ConvertTransform(IHostEnvironment env, Arguments args, IDataView input) : base(env, RegistrationName, env.CheckRef(args, nameof(args)).Column, input, null) { Host.AssertNonEmpty(Infos); Host.Assert(Infos.Length == Utils.Size(args.Column)); _exes = new ColInfoEx[Infos.Length]; for (int i = 0; i < _exes.Length; i++) { DataKind kind; KeyRange range; var col = args.Column[i]; if (col.ResultType != null) { kind = col.ResultType.Value; range = !string.IsNullOrEmpty(col.Range) ? KeyRange.Parse(col.Range) : col.KeyRange; } else if (col.KeyRange != null || !string.IsNullOrEmpty(col.Range)) { kind = Infos[i].TypeSrc.IsKey ? Infos[i].TypeSrc.RawKind : DataKind.U4; range = col.KeyRange ?? KeyRange.Parse(col.Range); } else if (args.ResultType != null) { kind = args.ResultType.Value; range = !string.IsNullOrEmpty(args.Range) ? KeyRange.Parse(args.Range) : args.KeyRange; } else if (args.KeyRange != null || !string.IsNullOrEmpty(args.Range)) { kind = Infos[i].TypeSrc.IsKey ? Infos[i].TypeSrc.RawKind : DataKind.U4; range = args.KeyRange ?? KeyRange.Parse(args.Range); } else { kind = DataKind.Num; range = null; } Host.CheckUserArg(Enum.IsDefined(typeof(DataKind), kind), nameof(args.ResultType)); PrimitiveType itemType; if (!TryCreateEx(Host, Infos[i], kind, range, out itemType, out _exes[i])) { throw Host.ExceptUserArg(nameof(args.Column), "source column '{0}' with item type '{1}' is not compatible with destination type '{2}'", input.Schema.GetColumnName(Infos[i].Source), Infos[i].TypeSrc.ItemType, itemType); } } SetMetadata(); }
private ConvertTransform(IHost host, ModelLoadContext ctx, IDataView input) : base(host, ctx, input, null) { Host.AssertValue(ctx); // *** Binary format *** // <prefix handled in static Create method> // <base> // for each added column // byte: data kind, with high bit set if there is a key range // if there is a key range // ulong: min // int: count (0 for unspecified) // byte: contiguous Host.AssertNonEmpty(Infos); _exes = new ColInfoEx[Infos.Length]; for (int i = 0; i < _exes.Length; i++) { byte b = ctx.Reader.ReadByte(); var kind = (DataKind)(b & 0x7F); Host.CheckDecode(Enum.IsDefined(typeof(DataKind), kind)); KeyRange range = null; if ((b & 0x80) != 0) { range = new KeyRange(); range.Min = ctx.Reader.ReadUInt64(); int count = ctx.Reader.ReadInt32(); if (count != 0) { if (count < 0 || (ulong)(count - 1) > ulong.MaxValue - range.Min) { throw Host.ExceptDecode(); } range.Max = range.Min + (ulong)(count - 1); } range.Contiguous = ctx.Reader.ReadBoolByte(); } PrimitiveType itemType; if (!TryCreateEx(Host, Infos[i], kind, range, out itemType, out _exes[i])) { throw Host.ExceptParam(nameof(input), "source column '{0}' is not of compatible type", input.Schema.GetColumnName(Infos[i].Source)); } } SetMetadata(); }
/// <summary> /// Attempt to parse the string into a data kind and (optionally) a key range. This method does not check whether /// the returned <see cref="DataKind"/> can really be made into a key with the specified <paramref name="keyRange"/>. /// </summary> /// <param name="str">The string to parse.</param> /// <param name="dataKind">The parsed data kind.</param> /// <param name="keyRange">The parsed key range, or null if there's no key specification.</param> /// <returns>Whether the parsing succeeded or not.</returns> public static bool TryParseDataKind(string str, out DataKind dataKind, out KeyRange keyRange) { Contracts.CheckValue(str, nameof(str)); keyRange = null; dataKind = default(DataKind); int ich = str.IndexOf('['); if (ich >= 0) { if (str[str.Length - 1] != ']') { return(false); } keyRange = KeyRange.Parse(str.Substring(ich + 1, str.Length - ich - 2)); if (keyRange == null) { return(false); } if (ich == 0) { return(true); } str = str.Substring(0, ich); } DataKind kind; if (!Enum.TryParse <DataKind>(str, true, out kind)) { return(false); } dataKind = kind; return(true); }
private static bool TryCreateEx(IExceptionContext ectx, ColInfo info, DataKind kind, KeyRange range, out PrimitiveType itemType, out ColInfoEx ex) { ectx.AssertValue(info); ectx.Assert(Enum.IsDefined(typeof(DataKind), kind)); ex = null; var typeSrc = info.TypeSrc; if (range != null) { itemType = TypeParsingUtils.ConstructKeyType(kind, range); if (!typeSrc.ItemType.IsKey && !typeSrc.ItemType.IsText) { return(false); } } else if (!typeSrc.ItemType.IsKey) { itemType = PrimitiveType.FromKind(kind); } else if (!KeyType.IsValidDataKind(kind)) { itemType = PrimitiveType.FromKind(kind); return(false); } else { var key = typeSrc.ItemType.AsKey; ectx.Assert(KeyType.IsValidDataKind(key.RawKind)); int count = key.Count; // Technically, it's an error for the counts not to match, but we'll let the Conversions // code return false below. There's a possibility we'll change the standard conversions to // map out of bounds values to zero, in which case, this is the right thing to do. ulong max = kind.ToMaxInt(); if ((ulong)count > max) { count = (int)max; } itemType = new KeyType(kind, key.Min, count, key.Contiguous); } // Ensure that the conversion is legal. We don't actually cache the delegate here. It will get // re-fetched by the utils code when needed. bool identity; Delegate del; if (!Conversions.Instance.TryGetStandardConversion(typeSrc.ItemType, itemType, out del, out identity)) { return(false); } ColumnType typeDst = itemType; if (typeSrc.IsVector) { typeDst = new VectorType(itemType, typeSrc.AsVector); } // An output column is transposable iff the input column was transposable. VectorType slotType = null; if (info.SlotTypeSrc != null) { slotType = new VectorType(itemType, info.SlotTypeSrc); } ex = new ColInfoEx(kind, range != null, typeDst, slotType); return(true); }