示例#1
0
        /// <summary>
        /// Write a collection of rows of TRow to the given path asynchronously.
        ///
        /// The file be created if it does not existing, overwritten if it does, and the encoding used will be utf-8.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        ///
        /// A CancellationToken may also be provided, CancellationToken.None will be used otherwise.
        /// </summary>
        public static ValueTask WriteToFileAsync <TRow>(
            IAsyncEnumerable <TRow> rows,
            string path,
            [NullableExposed("options will default to Options.Default")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null,
            CancellationToken cancellationToken = default
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));
            Utils.CheckArgumentNull(path, nameof(path));

            return(WriteToFileImplAsync(rows, path, options, context, cancellationToken));
        /// <summary>
        /// Creates a SurrogateTypeDescriberBuilder with the given fallback behavior, type describer, and fallback type describer.
        ///
        /// Uses the given ITypeDescriber to describes surrogates,
        ///   and falls back to provided fallback if no surrogate is registered and the provided SurrogateTypeDescriberFallbackBehavior
        ///   allows it.
        /// </summary>
        public static SurrogateTypeDescriberBuilder CreateBuilder(SurrogateTypeDescriberFallbackBehavior fallbackBehavior, ITypeDescriber typeDescriber, ITypeDescriber fallbackTypeDescriber)
        {
            if (!Enum.IsDefined(Types.SurrogateTypeDescriberFallbackBehavior, fallbackBehavior))
            {
                Throw.ArgumentException($"Unexpected {nameof(SurrogateTypeDescriberFallbackBehavior)}: {fallbackBehavior}", nameof(fallbackBehavior));
            }

            Utils.CheckArgumentNull(typeDescriber, nameof(typeDescriber));
            Utils.CheckArgumentNull(fallbackTypeDescriber, nameof(fallbackTypeDescriber));

            var inner = ImmutableDictionary.CreateBuilder <TypeInfo, TypeInfo>();

            return(new SurrogateTypeDescriberBuilder(typeDescriber, fallbackTypeDescriber, fallbackBehavior, inner));
        }
示例#3
0
        /// <summary>
        /// Lazily enumerate dynamic rows from the given TextReader.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on ReadContext.
        /// </summary>
        public static IEnumerable <dynamic> EnumerateDynamic(
            TextReader reader,
            [NullableExposed("options will default to Options.Default")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null
            )
        {
            Utils.CheckArgumentNull(reader, nameof(reader));

            var c = Configuration.ForDynamic(options ?? Options.DynamicDefault);

            return(EnumerateFromStreamImpl(c, reader, context));
        }
示例#4
0
        /// <summary>
        /// Write a collection of dynamic rows to the given path asynchronously.
        ///
        /// The file be created if it does not existing, overwritten if it does, and the encoding used will be utf-8.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        ///
        /// A CancellationToken may also be provided, CancellationToken.None will be used otherwise.
        /// </summary>
        public static ValueTask WriteDynamicToFileAsync(
            IEnumerable <dynamic> rows,
            string path,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null,
            CancellationToken cancellationToken = default
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));
            Utils.CheckArgumentNull(path, nameof(path));

            return(WriteDynamicToFileAsync(new AsyncEnumerableAdapter <dynamic>(rows), path, options, context, cancellationToken));
        }
示例#5
0
        // async write methods

        /// <summary>
        /// Write a collection of rows of TRow to the given TextWriter asynchronously.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        ///
        /// A CancellationToken may also be provided, CancellationToken.None will be used otherwise.
        /// </summary>
        public static ValueTask WriteAsync <TRow>(
            IEnumerable <TRow> rows,
            TextWriter writer,
            [NullableExposed("options will default to Options.Default")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null,
            CancellationToken cancellationToken = default
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));
            Utils.CheckArgumentNull(writer, nameof(writer));

            return(WriteAsync(new AsyncEnumerableAdapter <TRow>(rows), writer, options, context, cancellationToken));
        }
示例#6
0
        // async read methods

        /// <summary>
        /// Lazily and asynchronously enumerate rows of type TRow from the given TextReader.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on ReadContext.
        ///
        /// A CancellationToken may also be provided, CancellationToken.None will be used otherwise.
        /// </summary>
        public static IAsyncEnumerable <TRow> EnumerateAsync <TRow>(
            TextReader reader,
            [NullableExposed("options will default to Options.Default")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null,
            CancellationToken cancellationToken = default
            )
        {
            Utils.CheckArgumentNull(reader, nameof(reader));

            var c = Configuration.For <TRow>(options ?? Options.Default);

            return(EnumerateFromStreamImplAsync(c, reader, context, cancellationToken));
        }
示例#7
0
        /// <summary>
        /// Lazily enumerate dynamic rows from the given string.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on ReadContext.
        /// </summary>
        public static IEnumerable <dynamic> EnumerateDynamicFromString(
            string data,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null
            )
        {
            Utils.CheckArgumentNull(data, nameof(data));

            var reader = new StringReader(data);

            // reader will be disposed in the Enumerate call
            return(EnumerateDynamic(reader, options, context));
        }
        /// <summary>
        /// Creates a SurrogateTypeDescriberBuilder which copies it's fallback behavior, type describer, fallback type describer, and
        ///   surrogate types from the given SurrogateTypeDescriber.
        /// </summary>
        public static SurrogateTypeDescriberBuilder CreateBuilder(SurrogateTypeDescriber typeDescriber)
        {
            Utils.CheckArgumentNull(typeDescriber, nameof(typeDescriber));

            var inner = ImmutableDictionary.CreateBuilder <TypeInfo, TypeInfo>();

            foreach (var kv in typeDescriber.SurrogateTypes)
            {
                inner[kv.Key] = kv.Value;
            }

            var behavior = typeDescriber.ThrowOnNoRegisteredSurrogate ? SurrogateTypeDescriberFallbackBehavior.Throw : SurrogateTypeDescriberFallbackBehavior.UseFallback;

            return(new SurrogateTypeDescriberBuilder(typeDescriber.TypeDescriber, typeDescriber.FallbackDescriber, behavior, inner));
        }
示例#9
0
        /// <summary>
        /// Lazily enumerate rows of type TRow from the given file.  If the file as a byte-order-marker (BOM) the indicated encoding will be used,
        ///   otherwise utf-8 will be assumed.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on ReadContext.
        /// </summary>
        public static IEnumerable <TRow> EnumerateFromFile <TRow>(
            string path,
            [NullableExposed("options will default to Options.Default")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null
            )
        {
            Utils.CheckArgumentNull(path, nameof(path));

            // reader will be disposed in the Enumerate call
            var reader = new StreamReader(path, true);

            return(Enumerate <TRow>(reader, options, context));
        }
示例#10
0
        /// <summary>
        /// Write a collection of dynamic rows to the given TextWriter.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        /// </summary>
        public static void WriteDynamic(
            IEnumerable <dynamic> rows,
            TextWriter writer,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));
            Utils.CheckArgumentNull(writer, nameof(writer));

            var c = Configuration.ForDynamic(options ?? Options.DynamicDefault);

            WriteImpl(c, rows, writer, context);
        }
示例#11
0
        /// <summary>
        /// Lazily and asynchronously enumerate dynamic rows from the given string.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on ReadContext.
        ///
        /// A CancellationToken may also be provided, CancellationToken.None will be used otherwise.
        /// </summary>
        public static IAsyncEnumerable <dynamic> EnumerateDynamicFromStringAsync(
            string data,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null,
            CancellationToken cancellationToken = default
            )
        {
            Utils.CheckArgumentNull(data, nameof(data));

            // reader will be disposed in the EnumerateDynamicAsync call
            var reader = new StringReader(data);

            return(EnumerateDynamicAsync(reader, options, context, cancellationToken));
        }
示例#12
0
        /// <summary>
        /// Write a collection of dynamics rows to the given TextWriter asynchronously.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        ///
        /// A CancellationToken may also be provided, CancellationToken.None will be used otherwise.
        /// </summary>
        public static ValueTask WriteDynamicAsync(
            IAsyncEnumerable <dynamic> rows,
            TextWriter writer,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null,
            CancellationToken cancellationToken = default
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));
            Utils.CheckArgumentNull(writer, nameof(writer));

            var c = Configuration.ForDynamic(options ?? Options.DynamicDefault);

            return(WriteImplAsync(c, rows, writer, context, cancellationToken));
        }
示例#13
0
        /// <summary>
        /// Write a collection of dynamic rows to a string.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        /// </summary>
        public static string WriteDynamicToString(
            IEnumerable <dynamic> rows,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));

            using (var writer = new StringWriter())
            {
                WriteDynamic(rows, writer, options, context);

                return(writer.ToString());
            }
        }
示例#14
0
        public TCollection ReadAll <TCollection>(TCollection into)
            where TCollection : class, ICollection <T>
        {
            AssertNotDisposed(this);
            AssertNotPoisoned(Configuration);

            Utils.CheckArgumentNull(into, nameof(into));
            Utils.CheckImmutableReadInto <TCollection, T>(into, nameof(into));

            try
            {
                HandleRowEndingsAndHeaders();

                while (true)
                {
#pragma warning disable CES0005 // T is generic, and null is legal, but since T isn't known to be a class we have to forgive null here
                    T _ = default !;
示例#15
0
        /// <summary>
        /// Write a collection of dynamic rows to the given path.
        ///
        /// The file be created if it does not existing, overwritten if it does, and the encoding used will be utf-8.
        ///
        /// An optional Options object may be used, if not provided Options.Default
        ///   will be used.
        ///
        /// Takes an optional context object which is made available
        ///   during certain operations as a member on WriteContext.
        /// </summary>
        public static void WriteDynamicToFile(
            IEnumerable <dynamic> rows,
            string path,
            [NullableExposed("options will default to Options.DynamicDefault")]
            Options?options = null,
            [NullableExposed("context is truly optional")]
            object?context = null
            )
        {
            Utils.CheckArgumentNull(rows, nameof(rows));
            Utils.CheckArgumentNull(path, nameof(path));

            using (var stream = File.Create(path))
                using (var writer = new StreamWriter(stream, Encoding.UTF8))
                {
                    WriteDynamic(rows, writer, options, context);
                }
        }
示例#16
0
        public int WriteAll(IEnumerable <T> rows)
        {
            AssertNotDisposed(this);
            AssertNotPoisoned(Configuration);

            var oldRowNumber = RowNumber;

            Utils.CheckArgumentNull(rows, nameof(rows));

            foreach (var row in rows)
            {
                WriteInner(row);
            }

            var ret = RowNumber - oldRowNumber;

            return(ret);
        }
        /// <summary>
        /// Registered a surrogate type for forType.
        ///
        /// Whenever forType is passed to one of the EnumerateXXX methods, surrogateType
        ///   will be used to discover members instead.  The discovered members will then
        ///   be mapped to forType, and returned.
        /// </summary>
        public SurrogateTypeDescriberBuilder WithSurrogateType(TypeInfo forType, TypeInfo surrogateType)
        {
            Utils.CheckArgumentNull(forType, nameof(forType));
            Utils.CheckArgumentNull(surrogateType, nameof(surrogateType));

            if (forType == surrogateType)
            {
                Throw.InvalidOperationException($"Type {forType} cannot be a surrogate for itself");
            }

            if (SurrogateTypes.ContainsKey(forType))
            {
                Throw.InvalidOperationException($"Surrogate already registered for {forType}");
            }

            SurrogateTypes[forType] = surrogateType;

            return(this);
        }
示例#18
0
        private ValueTask <TCollection> ReadAllIntoCollectionAsync <TCollection>(TCollection into, CancellationToken cancellationToken)
            where TCollection : class, ICollection <T>
        {
            AssertNotDisposed(this);
            AssertNotPoisoned(Configuration);

            Utils.CheckArgumentNull(into, nameof(into));
            Utils.CheckImmutableReadInto <TCollection, T>(into, nameof(into));

            try
            {
                var headersAndRowEndingsTask = HandleRowEndingsAndHeadersAsync(cancellationToken);
                if (!headersAndRowEndingsTask.IsCompletedSuccessfully(this))
                {
                    return(ReadAllAsync_ContinueAfterHandleRowEndingsAndHeadersAsync(this, headersAndRowEndingsTask, into, cancellationToken));
                }

                while (true)
                {
#pragma warning disable CES0005 // T is generic, and null is legal, but since T isn't known to be a class we have to forgive null here
                    T _ = default !;
示例#19
0
        /// <summary>
        /// Set the delegate to use when constructing new instances of
        ///   the given type.
        /// </summary>
        public ManualTypeDescriberBuilder WithInstanceProvider(TypeInfo forType, InstanceProvider instanceProvider)
        {
            Utils.CheckArgumentNull(forType, nameof(forType));
            Utils.CheckArgumentNull(instanceProvider, nameof(instanceProvider));

            var createdType = instanceProvider.ConstructsType;

            if (!forType.IsAssignableFrom(createdType))
            {
                Throw.InvalidOperationException($"{forType} cannot be assigned from {createdType}, constructed by {instanceProvider}");
            }

            if (Builders.ContainsKey(forType))
            {
                Throw.InvalidOperationException($"Instance provider already registered for {forType}");
            }

            Builders[forType] = instanceProvider;

            return(this);
        }
        void ICollection <T> .CopyTo(T[] array, int arrayIndex)
        {
            Utils.CheckArgumentNull(array, nameof(array));

            if (arrayIndex < 0)
            {
                Throw.ArgumentOutOfRangeException(nameof(arrayIndex), arrayIndex, 0, array.Length);
            }

            if (arrayIndex + Data.Count > array.Length)
            {
                Throw.ArgumentException(nameof(arrayIndex), $"Collection contains {Data.Count} elements, which will not fit in array of Length {array.Length} starting at index {arrayIndex}");
            }

            // not looking to optimize this, because we don't really care about
            //     this interface... but need it for LINQ to play ball
            for (var i = 0; i < Data.Count; i++)
            {
                array[i + arrayIndex] = GetAt(i);
            }
        }
示例#21
0
        /// <summary>
        /// Create a new OptionsBuilder, copying defaults
        /// from the given Options.
        /// </summary>
        public static OptionsBuilder CreateBuilder(Options options)
        {
            Utils.CheckArgumentNull(options, nameof(options));

            return(new OptionsBuilder(options));
        }
示例#22
0
        /// <summary>
        /// Add a property to deserialize with the given name, parser, whether the column is required, and a reset method - for the type which declares the property.
        /// </summary>
        public ManualTypeDescriberBuilder WithDeserializableProperty(PropertyInfo property, string name, Parser parser, MemberRequired required, Reset reset)
        {
            Utils.CheckArgumentNull(reset, nameof(reset));

            return(WithDeserializeMember(property?.DeclaringType?.GetTypeInfo(), (Setter?)property?.SetMethod, name, parser, required, reset));
        }
示例#23
0
        /// <summary>
        /// Add a field to deserialize with the given name, parser, whether the column is required, and a reset method - for the type which declares the field.
        /// </summary>
        public ManualTypeDescriberBuilder WithDeserializableField(FieldInfo field, string name, Parser parser, MemberRequired required, Reset reset)
        {
            Utils.CheckArgumentNull(reset, nameof(reset));

            return(WithDeserializeMember(field?.DeclaringType?.GetTypeInfo(), (Setter?)field, name, parser, required, reset));
        }
示例#24
0
        /// <summary>
        /// Add a setter for the given type, with the given name, using the given setter, parser, whether the column is required, and a reset method.
        /// </summary>
        public ManualTypeDescriberBuilder WithExplicitSetter(TypeInfo forType, string name, Setter setter, Parser parser, MemberRequired required, Reset reset)
        {
            Utils.CheckArgumentNull(reset, nameof(reset));

            return(WithDeserializeMember(forType, setter, name, parser, required, reset));
        }
示例#25
0
        /// <summary>
        /// Add a property to serialize with the given name, formatter, ShouldSerialize method, and whether to emit a default value - for the type which declares the property.
        /// </summary>
        public ManualTypeDescriberBuilder WithSerializableProperty(PropertyInfo property, string name, Formatter formatter, ShouldSerialize shouldSerialize, EmitDefaultValue emitDefault)
        {
            Utils.CheckArgumentNull(shouldSerialize, nameof(shouldSerialize));

            return(WithSerializableMember(property?.DeclaringType?.GetTypeInfo(), (Getter?)property?.GetMethod, name, formatter, shouldSerialize, emitDefault));
        }
示例#26
0
        /// <summary>
        /// Add a field to serialize with the given name, formatter, ShouldSerialize method, and whether to emit a default value - for the type which declares the field.
        /// </summary>
        public ManualTypeDescriberBuilder WithSerializableField(FieldInfo field, string name, Formatter formatter, ShouldSerialize shouldSerialize, EmitDefaultValue emitDefault)
        {
            Utils.CheckArgumentNull(shouldSerialize, nameof(shouldSerialize));

            return(WithSerializableMember(field?.DeclaringType?.GetTypeInfo(), (Getter?)field, name, formatter, shouldSerialize, emitDefault));
        }
示例#27
0
        /// <summary>
        /// Add a field to serialize for the given type, using the given name, formatter, and ShouldSerialize method.
        /// </summary>
        public ManualTypeDescriberBuilder WithSerializableField(TypeInfo forType, FieldInfo field, string name, Formatter formatter, ShouldSerialize shouldSerialize)
        {
            Utils.CheckArgumentNull(shouldSerialize, nameof(shouldSerialize));

            return(WithSerializableMember(forType, (Getter?)field, name, formatter, shouldSerialize, EmitDefaultValue.Yes));
        }
示例#28
0
        /// <summary>
        /// Add a getter for the given type, with the given name, using the given getter, formatter, ShouldSerialize method, and whether to emit a default value.
        /// </summary>
        public ManualTypeDescriberBuilder WithExplicitGetter(TypeInfo forType, string name, Getter getter, Formatter formatter, ShouldSerialize shouldSerialize, EmitDefaultValue emitDefault)
        {
            Utils.CheckArgumentNull(shouldSerialize, nameof(shouldSerialize));

            return(WithSerializableMember(forType, getter, name, formatter, shouldSerialize, emitDefault));
        }
示例#29
0
        /// <summary>
        /// Create a new ManualTypeDescriberBuilder that copies it's
        ///   initial values from the given ManualTypeDescriber.
        /// </summary>
        public static ManualTypeDescriberBuilder CreateBuilder(ManualTypeDescriber typeDescriber)
        {
            Utils.CheckArgumentNull(typeDescriber, nameof(typeDescriber));

            return(new ManualTypeDescriberBuilder(typeDescriber));
        }
示例#30
0
        public void WriteComment(string comment)
        {
            Utils.CheckArgumentNull(comment, nameof(comment));

            WriteComment(comment.AsSpan());
        }