From 2a1cd4fda8a4a8e649910d16b4dfa1ce7ae63543 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Fri, 12 May 2023 09:24:40 +0800 Subject: *misc --- .../CsvHelper/Expressions/ObjectRecordWriter.cs | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/ObjectRecordWriter.cs (limited to 'ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/ObjectRecordWriter.cs') diff --git a/ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/ObjectRecordWriter.cs b/ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/ObjectRecordWriter.cs new file mode 100644 index 0000000..08fc79b --- /dev/null +++ b/ThirdParty/CsvHelper-master/src/CsvHelper/Expressions/ObjectRecordWriter.cs @@ -0,0 +1,124 @@ +// Copyright 2009-2022 Josh Close +// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0. +// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0. +// https://github.com/JoshClose/CsvHelper +using CsvHelper.Configuration; +using CsvHelper.TypeConversion; +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; + +namespace CsvHelper.Expressions +{ + /// + /// Writes objects. + /// + public class ObjectRecordWriter : RecordWriter + { + /// + /// Initializes a new instance using the given writer. + /// + /// The writer. + public ObjectRecordWriter(CsvWriter writer) : base(writer) { } + + /// + /// Creates a of type + /// that will write the given record using the current writer row. + /// + /// The record type. + /// The record. + protected override Action CreateWriteDelegate(T record) + { + var type = Writer.GetTypeForRecord(record); + + if (Writer.Context.Maps[type] == null) + { + Writer.Context.Maps.Add(Writer.Context.AutoMap(type)); + } + + var recordParameter = Expression.Parameter(typeof(T), "record"); + var recordParameterConverted = Expression.Convert(recordParameter, type); + + // Get a list of all the members so they will + // be sorted properly. + var members = new MemberMapCollection(); + members.AddMembers(Writer.Context.Maps[type]); + + if (members.Count == 0) + { + throw new WriterException(Writer.Context, $"No properties are mapped for type '{type.FullName}'."); + } + + var delegates = new List>(); + + foreach (var memberMap in members) + { + if (memberMap.Data.WritingConvertExpression != null) + { + // The user is providing the expression to do the conversion. + var constructor = typeof(ConvertToStringArgs).GetConstructor(new Type[] { typeof(T) }); + var args = Expression.New(constructor, recordParameterConverted); + Expression exp = Expression.Invoke(memberMap.Data.WritingConvertExpression, args); + exp = Expression.Call(Expression.Constant(Writer), nameof(Writer.WriteField), null, exp); + delegates.Add(Expression.Lambda>(exp, recordParameter).Compile()); + continue; + } + + if (!Writer.CanWrite(memberMap)) + { + continue; + } + + Expression fieldExpression; + + if (memberMap.Data.IsConstantSet) + { + if (memberMap.Data.Constant == null) + { + fieldExpression = Expression.Constant(string.Empty); + } + else + { + fieldExpression = Expression.Constant(memberMap.Data.Constant); + var typeConverterExpression = Expression.Constant(Writer.Context.TypeConverterCache.GetConverter(memberMap.Data.Constant.GetType())); + var method = typeof(ITypeConverter).GetMethod(nameof(ITypeConverter.ConvertToString)); + fieldExpression = Expression.Convert(fieldExpression, typeof(object)); + fieldExpression = Expression.Call(typeConverterExpression, method, fieldExpression, Expression.Constant(Writer), Expression.Constant(memberMap.Data)); + } + } + else + { + if (memberMap.Data.TypeConverter == null) + { + // Skip if the type isn't convertible. + continue; + } + + fieldExpression = ExpressionManager.CreateGetMemberExpression(recordParameterConverted, Writer.Context.Maps[type], memberMap); + + var typeConverterExpression = Expression.Constant(memberMap.Data.TypeConverter); + memberMap.Data.TypeConverterOptions = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = Writer.Configuration.CultureInfo }, Writer.Context.TypeConverterOptionsCache.GetOptions(memberMap.Data.Member.MemberType()), memberMap.Data.TypeConverterOptions); + + var method = typeof(ITypeConverter).GetMethod(nameof(ITypeConverter.ConvertToString)); + fieldExpression = Expression.Convert(fieldExpression, typeof(object)); + fieldExpression = Expression.Call(typeConverterExpression, method, fieldExpression, Expression.Constant(Writer), Expression.Constant(memberMap.Data)); + + if (type.GetTypeInfo().IsClass) + { + var areEqualExpression = Expression.Equal(recordParameterConverted, Expression.Constant(null)); + fieldExpression = Expression.Condition(areEqualExpression, Expression.Constant(string.Empty), fieldExpression); + } + } + + var writeFieldMethodCall = Expression.Call(Expression.Constant(Writer), nameof(Writer.WriteConvertedField), null, fieldExpression, Expression.Constant(memberMap.Data.Type)); + + delegates.Add(Expression.Lambda>(writeFieldMethodCall, recordParameter).Compile()); + } + + var action = CombineDelegates(delegates) ?? new Action((T parameter) => { }); + + return action; + } + } +} -- cgit v1.1-26-g67d0