示例#1
0
        private static ImmutableArray <(string Name, TypeInfo Type)> GetRequiredColumns()
        {
            var recordType = typeof(TRecord).GetTypeInfo();

            var(cons, _, _) = recordType.ReadRecordType();

            return(ImmutableArray.CreateRange(cons.GetParameters().Select(p => (Utils.NonNull(p.Name), p.ParameterType.GetTypeInfo()))));
        }
示例#2
0
        /// <summary>
        /// Enumerate members which will be serialized for the given type.
        ///
        /// Note that these members are generated ahead of time with a source gneerator,
        ///   and cannot be changed at runtime.
        /// </summary>
        public IEnumerable <SerializableMember> EnumerateMembersToSerialize(TypeInfo forType)
        {
            var paired = GetPairedType(forType, SERIALIZER_KIND);

            if (paired == null)
            {
                return(Enumerable.Empty <SerializableMember>());
            }

            var colNamesField = paired.GetFieldNonNull("ColumnNames", PublicStatic);
            var colNames      = (ImmutableArray <string>)colNamesField.GetValueNonNull(null);

            var ret = ImmutableArray.CreateBuilder <SerializableMember>(colNames.Length);

            for (var i = 0; i < colNames.Length; i++)
            {
                var name = colNames[i];

                var colWriterName = $"__Column_{i}";
                var colWriterMtd  = paired.GetMethodNonNull(colWriterName, PublicStatic);

#pragma warning disable CS0618 // This is obsolete to prevent clients from using them, but they are fine for us.
                var emitsDefaultValue = colWriterMtd.GetCustomAttribute <DoesNotEmitDefaultValueAttribute>() == null;
#pragma warning restore CS0618

                var shouldSerializeName = $"__Column_{i}_ShouldSerialize";
                var shouldSerializeMtd  = paired.GetMethod(shouldSerializeName, PublicStatic);
                var shouldSerialize     = (ShouldSerialize?)shouldSerializeMtd;

                var getterName = $"__Column_{i}_Getter";
                var getterMtd  = paired.GetMethodNonNull(getterName, PublicStatic);
                var getter     = Getter.ForMethod(getterMtd);

                var       formatterName = $"__Column_{i}_Formatter";
                var       formatterMtd  = paired.GetMethod(formatterName, PublicStatic);
                Formatter formatter;
                if (formatterMtd == null)
                {
                    // if a method isn't provided, it must be using the default
                    formatter = Utils.NonNull(Formatter.GetDefault(getter.Returns));
                }
                else
                {
                    formatter = Formatter.ForMethod(formatterMtd);
                }


                ret.Add(SerializableMember.ForGeneratedMethod(name, colWriterMtd, getter, formatter, shouldSerialize, emitsDefaultValue));
            }

            return(ret.ToImmutable());
        }
        internal DynamicRowEnumerableNonGeneric(object row)
        {
            if (row is DynamicRow dynRow)
            {
                Row       = dynRow;
                DependsOn = dynRow;
                Offset    = Length = null;
            }
            else
            {
                var dynRowRange = Utils.NonNull(row as DynamicRowRange);

                Row       = dynRowRange.Parent;
                DependsOn = dynRowRange;
                Offset    = dynRowRange.Offset;
                Length    = dynRowRange.Length;
            }
        }
示例#4
0
 internal Options(OptionsBuilder copy)
 {
     ValueSeparator              = copy.ValueSeparator;
     EscapedValueStartAndEnd     = copy.EscapedValueStartAndEnd;
     EscapedValueEscapeCharacter = copy.EscapedValueEscapeCharacter;
     ReadRowEnding          = copy.ReadRowEnding;
     WriteRowEnding         = copy.WriteRowEnding;
     ReadHeader             = copy.ReadHeader;
     WriteHeader            = copy.WriteHeader;
     TypeDescriber          = Utils.NonNull(copy.TypeDescriber);
     WriteTrailingRowEnding = copy.WriteTrailingRowEnding;
     MemoryPoolProvider     = Utils.NonNull(copy.MemoryPoolProvider);
     CommentCharacter       = copy.CommentCharacter;
     WriteBufferSizeHint    = copy.WriteBufferSizeHint;
     ReadBufferSizeHint     = copy.ReadBufferSizeHint;
     DynamicRowDisposal     = copy.DynamicRowDisposal;
     WhitespaceTreatment    = copy.WhitespaceTreatment;
     ExtraColumnTreatment   = copy.ExtraColumnTreatment;
 }
示例#5
0
        internal PassthroughRowEnumerable(object row)
        {
            if (row is DynamicRow dynRow)
            {
                Row       = dynRow;
                DependsOn = dynRow;
                Offset    = Length = null;
            }
            else
            {
                var dynRowRange = Utils.NonNull(row as DynamicRowRange);

                Row       = dynRowRange.Parent;
                DependsOn = dynRowRange;
                Offset    = dynRowRange.Offset;
                Length    = dynRowRange.Length;
            }

            Generation = Row.Generation;
        }
示例#6
0
            private static ulong[] CreateValues()
            {
                var enumType = typeof(T).GetTypeInfo();

                if (enumType.IsFlagsEnum())
                {
                    // only need the actual values if we're in Flags mode
                    var values = Enum.GetValues(enumType);
                    var ret    = new ulong[values.Length];
                    for (var i = 0; i < values.Length; i++)
                    {
                        var obj = values.GetValue(i);
                        var asT = (T)Utils.NonNull(obj);
                        ret[i] = Utils.EnumToULong(asT);
                    }

                    return(ret);
                }

                return(Array.Empty <ulong>());
            }
示例#7
0
            private static ulong[] CreateULongValues()
            {
                var enumType = typeof(T).GetTypeInfo();

                // note that this is different from CreateValues()
                //   which means these don't match like they do in formatting
                if (!enumType.IsFlagsEnum())
                {
                    // only need ULongValues for [Flags] enums
                    return(Array.Empty <ulong>());
                }

                var values = Enum.GetValues(enumType);
                var ret    = new ulong[values.Length];

                for (var i = 0; i < values.Length; i++)
                {
                    var obj = values.GetValue(i);
                    obj    = Utils.NonNull(obj);
                    ret[i] = Utils.EnumToULong((T)obj);
                }

                return(ret);
            }
示例#8
0
        private static ImmutableArray <(string Name, TypeInfo Type, Delegate Setter)> GetOptionalColumns()
        {
            var recordType = typeof(TRecord).GetTypeInfo();

            var(_, propsSetByCons, _) = recordType.ReadRecordType();

            var propsWithSetters = recordType.GetProperties().Where(p => p.SetMethod != null).Except(propsSetByCons);

            var ret = ImmutableArray.CreateBuilder <(string Name, TypeInfo Type, Delegate Setter)>();

            foreach (var prop in propsWithSetters)
            {
                var name   = prop.Name;
                var type   = prop.PropertyType.GetTypeInfo();
                var setMtd = Utils.NonNull(prop.SetMethod);

                var delType = Types.Action2.MakeGenericType(typeof(TRecord), type);
                var del     = Delegate.CreateDelegate(delType, setMtd);

                ret.Add((name, type, del));
            }

            return(ret.ToImmutable());
        }
示例#9
0
        /// <summary>
        /// Enumerate members which will be deserialized for the given type.
        ///
        /// Note that these members are generated ahead of time with a source gneerator,
        ///   and cannot be changed at runtime.
        /// </summary>
        public IEnumerable <DeserializableMember> EnumerateMembersToDeserialize(TypeInfo forType)
        {
            var paired = GetPairedType(forType, DESERIALIZER_KIND);

            if (paired == null)
            {
                return(Enumerable.Empty <DeserializableMember>());
            }

            var colNamesProp = paired.GetPropertyNonNull("__ColumnNames", PublicStatic);
            var colNames     = (ImmutableArray <string>)colNamesProp.GetValueNonNull(null);

            var ret = ImmutableArray.CreateBuilder <DeserializableMember>(colNames.Length);

            ParameterInfo[]? consPs = null;

            for (var i = 0; i < colNames.Length; i++)
            {
                var name = colNames[i];

                var colReaderName = $"__Column_{i}";
                var colReaderMtd  = paired.GetMethodNonNull(colReaderName, PublicInstance);

#pragma warning disable CS0618 // These are obsolete to prevent clients from using them, but they are fine for us.
                var isRequired = colReaderMtd.GetCustomAttribute <IsRequiredAttribute>() != null;
                var setterBackedByParameter = colReaderMtd.GetCustomAttribute <SetterBackedByConstructorParameterAttribute>();
                var setterIsInitOnly        = colReaderMtd.GetCustomAttribute <SetterBackedByInitOnlyPropertyAttribute>();
#pragma warning restore CS0618

                Setter setter;
                if (setterBackedByParameter == null && setterIsInitOnly == null)
                {
                    // directly a method
                    var setterName = $"__Column_{i}_Setter";
                    var setterMtd  = paired.GetMethodNonNull(setterName, PublicStatic);
                    setter = Setter.ForMethod(setterMtd);
                }
                else if (setterBackedByParameter != null)
                {
                    // parameter to constructor
                    if (consPs == null)
                    {
                        var ip = GetInstanceProvider(forType);
                        ip = Utils.NonNull(ip);

                        var cons = ip.Constructor.Value;
                        consPs = cons.GetParameters();
                    }

                    var consParameterIndex = setterBackedByParameter.Index;
                    if (consParameterIndex < 0 || consParameterIndex >= consPs.Length)
                    {
                        Throw.ImpossibleException($"Setter for column {i} claims to be backed by constructor parameter, but its position is out of bounds (index={consParameterIndex})");
                    }

                    var p = consPs[setterBackedByParameter.Index];
                    setter = Setter.ForConstructorParameter(p);
                }
                else
                {
                    // init only property
                    var initOnly = Utils.NonNull(setterIsInitOnly);

                    var prop = forType.GetProperty(initOnly.PropertyName, initOnly.BindingFlags);
                    if (prop == null)
                    {
                        Throw.ImpossibleException($"Setter for column {i} claims to be backed by init-only property {initOnly.PropertyName} with bindings ({initOnly.BindingFlags}), but it could not be found");
                    }

                    setter = Setter.ForProperty(prop);
                }

                var resetMethodName = $"__Column_{i}_Reset";
                var resetMtd        = paired.GetMethod(resetMethodName, PublicStatic);
                var reset           = (Reset?)resetMtd;

                var    parserMethodName = $"__Column_{i}_Parser";
                var    parserMtd        = paired.GetMethod(parserMethodName, PublicStatic);
                Parser?parser;
                if (parserMtd != null)
                {
                    parser = Parser.ForMethod(parserMtd);
                }
                else
                {
                    parser = Utils.NonNull(Parser.GetDefault(setter.Takes));
                }

                ret.Add(DeserializableMember.CreateInner(forType, name, setter, parser, isRequired ? MemberRequired.Yes : MemberRequired.No, reset, paired));
            }

            return(ret.ToImmutable());
        }