public static IColumnWriter TryGetColumnWriter(IStreamProvider streamProvider, Type columnType, string columnPath) { IColumnWriter writer = null; // Build a direct writer for the column type, if available ITypeProvider columnTypeProvider = TryGet(columnType); if (columnTypeProvider != null) { writer = columnTypeProvider.BinaryWriter(streamProvider, columnPath); } // If the column type doesn't have a provider or writer, convert to String8 and write that if (writer == null) { Func <XArray, XArray> converter = TypeConverterFactory.GetConverter(columnType, typeof(String8)); if (converter == null) { return(null); } writer = TypeProviderFactory.TryGet(typeof(String8)).BinaryWriter(streamProvider, columnPath); writer = new ConvertingWriter(writer, converter); } // Wrap with a NullableWriter to handle null persistence writer = new NullableWriter(streamProvider, columnPath, writer); // Wrap with an EnumWriter to write as an EnumColumn while possible. // Try for *all types* [even bool, byte, ushort] because Enum columns can roll nulls into the column itself and accelerate groupBy writer = new EnumWriter(streamProvider, columnPath, columnType, writer); return(writer); }
public static Func <XArray, XArray> TryGetConverter(Type sourceType, Type targetType, ValueKinds errorOn = ValueKindsDefaults.ErrorOn, object defaultValue = null, ValueKinds changeToDefault = ValueKindsDefaults.ChangeToDefault) { // Error if there's a default but nothing will be changed to it if (defaultValue != null && changeToDefault == ValueKinds.None) { throw new ArgumentException("Cast with a default value must have [ChangeToDefaultOn] not 'None'."); } // Convert the defaultValue to the right type defaultValue = ConvertSingle(defaultValue, targetType); Func <XArray, XArray> converter = null; // See if the target type provides conversion ITypeProvider targetTypeProvider = TypeProviderFactory.TryGet(targetType); if (targetTypeProvider != null) { converter = NegatedTryConvertToConverter(targetTypeProvider.TryGetNegatedTryConvert(sourceType, targetType, defaultValue), "", errorOn, changeToDefault); if (converter != null) { return(converter); } } // See if the source type provides conversion ITypeProvider sourceTypeProvider = TypeProviderFactory.TryGet(sourceType); if (sourceTypeProvider != null) { converter = NegatedTryConvertToConverter(sourceTypeProvider.TryGetNegatedTryConvert(sourceType, targetType, defaultValue), "", errorOn, changeToDefault); if (converter != null) { return(converter); } } // Try again with implicit string to String8 conversion if (sourceType == typeof(string)) { converter = TryGetConverter(typeof(String8), targetType, errorOn, defaultValue, changeToDefault); // If found, encode the string to String8 conversion and then the String8 to target conversion if (converter != null) { Func <XArray, XArray> innerConverter = GetConverter(typeof(string), typeof(String8), errorOn, defaultValue, changeToDefault); return((xarray) => converter(innerConverter(xarray))); } } return(null); }