Exemple #1
0
        private void AddItem(MemberInfo m, CommonOptions options, bool must, bool all)
        {
            var ia = new ItemAttrs(m, Options, all ? AllOptionality : YuzuItemOptionality.None);

            if (ia.Count == 0)
            {
                if (must)
                {
                    throw Error("Item {0} must be serialized", m.Name);
                }
                return;
            }
            if (ia.Count != 1)
            {
                throw Error("More than one of optional, required and member attributes for field '{0}'", m.Name);
            }
            var attrs         = Options.GetItem(m);
            var serializeCond = attrs.Attr(Options.SerializeConditionAttribute);
            var item          = new Item {
                Alias         = Options.GetAlias(ia.Any()) ?? m.Name,
                IsOptional    = ia.Required == null,
                IsCompact     = attrs.HasAttr(Options.CompactAttribute),
                IsCopyable    = attrs.HasAttr(Options.CopyableAttribute),
                IsMember      = ia.Member != null,
                SerializeCond = serializeCond != null?
                                Options.GetSerializeCondition(serializeCond, Type) : null,
                                    SerializeIfMethod = serializeCond != null?
                                                        Options.GetSerializeMethod(serializeCond, Type) : null,
                                                            DefaultValue = serializeCond != null?
                                                                           Options.GetDefault(serializeCond) : YuzuNoDefault.NoDefault,
                                                                               Name = m.Name,
            };

            if (!item.IsOptional)
            {
                RequiredCount += 1;
            }
            var merge = attrs.HasAttr(Options.MergeAttribute);

            switch (m.MemberType)
            {
            case MemberTypes.Field:
                var f = m as FieldInfo;
                if (!f.IsPublic)
                {
                    throw Error("Non-public item '{0}'", f.Name);
                }
                item.Type     = f.FieldType;
                item.GetValue = f.GetValue;
                if (!merge)
                {
                    item.SetValue = f.SetValue;
                }
                item.FieldInfo = f;
                break;

            case MemberTypes.Property:
                var p      = m as PropertyInfo;
                var getter = p.GetGetMethod();
                if (getter == null)
                {
                    throw Error("No getter for item '{0}'", p.Name);
                }
                item.Type = p.PropertyType;
                var setter = p.GetSetMethod();
#if iOS // Apple forbids code generation.
                item.GetValue = obj => p.GetValue(obj, Utils.ZeroObjects);
                if (!merge && setter != null)
                {
                    item.SetValue = (obj, value) => p.SetValue(obj, value, Utils.ZeroObjects);
                }
#else
                if (Utils.IsStruct(Type))
                {
                    item.GetValue = obj => p.GetValue(obj, Utils.ZeroObjects);
                    if (!merge && setter != null)
                    {
                        item.SetValue = (obj, value) => p.SetValue(obj, value, Utils.ZeroObjects);
                    }
                }
                else
                {
                    item.GetValue = BuildGetter(getter);
                    if (!merge && setter != null)
                    {
                        item.SetValue = BuildSetter(setter);
                    }
                }
#endif
                item.PropInfo = p;
                break;

            default:
                throw Error("Member type {0} not supported", m.MemberType);
            }
            if (item.SetValue == null)
            {
                if (!item.Type.IsClass && !item.Type.IsInterface || item.Type == typeof(object))
                {
                    throw Error("Unable to either set or merge item {0}", item.Name);
                }
            }
            var over = Options.GetOverride(item.Type);
            if (over.HasAttr(Options.CompactAttribute))
            {
                item.IsCompact = true;
            }
            if (!over.HasAttr(Options.CopyableAttribute))
            {
                CheckCopyable(item.Type, options);
            }

            if (ia.Member != null && item.SerializeCond == null && !Type.IsAbstract && !Type.IsInterface)
            {
                item.SerializeCond = GetSerializeIf(item, options);
            }
            Items.Add(item);
        }
Exemple #2
0
        private void AddItem(MemberInfo m, bool must, bool all)
        {
            var ia = new ItemAttrs(m, Options, all ? AllOptionality : YuzuItemOptionality.None);

            if (ia.Count == 0)
            {
                if (must)
                {
                    throw Error("Item {0} must be serialized", m.Name);
                }
                return;
            }
            if (ia.Count != 1)
            {
                throw Error("More than one of optional, required and member attributes for field '{0}'", m.Name);
            }
            var serializeIf = m.GetCustomAttribute_Compat(Options.SerializeIfAttribute, true);
            var item        = new Item {
                Alias                             = Options.GetAlias(ia.Any()) ?? m.Name,
                IsOptional                        = ia.Required == null,
                IsCompact                         = m.IsDefined(Options.CompactAttribute, false),
                SerializeIf                       = serializeIf != null?Options.GetSerializeCondition(serializeIf) : null,
                                             Name = m.Name,
            };
            var merge = m.IsDefined(Options.MergeAttribute, false);

            switch (m.MemberType)
            {
            case MemberTypes.Field:
                var f = m as FieldInfo;
                if (!f.IsPublic)
                {
                    throw Error("Non-public item '{0}'", f.Name);
                }
                item.Type     = f.FieldType;
                item.GetValue = f.GetValue;
                if (!merge)
                {
                    item.SetValue = f.SetValue;
                }
                item.FieldInfo = f;
                break;

            case MemberTypes.Property:
                var p      = m as PropertyInfo;
                var getter = p.GetGetMethod();
                if (getter == null)
                {
                    throw Error("No getter for item '{0}'", p.Name);
                }
                item.Type = p.PropertyType;
                var setter = p.GetSetMethod();
#if iOS // Apple forbids code generation.
                item.GetValue = obj => p.GetValue(obj, Utils.ZeroObjects);
                if (!merge && setter != null)
                {
                    item.SetValue = (obj, value) => p.SetValue(obj, value, Utils.ZeroObjects);
                }
#else
                if (Utils.IsStruct(Type))
                {
                    item.GetValue = obj => p.GetValue(obj, Utils.ZeroObjects);
                    if (!merge && setter != null)
                    {
                        item.SetValue = (obj, value) => p.SetValue(obj, value, Utils.ZeroObjects);
                    }
                }
                else
                {
                    item.GetValue = BuildGetter(getter);
                    if (!merge && setter != null)
                    {
                        item.SetValue = BuildSetter(setter);
                    }
                }
#endif
                item.PropInfo = p;
                break;

            default:
                throw Error("Member type {0} not supported", m.MemberType);
            }
            if (item.SetValue == null)
            {
                if (!item.Type.IsClass && !item.Type.IsInterface || item.Type == typeof(object))
                {
                    throw Error("Unable to either set or merge item {0}", item.Name);
                }
            }
            if (item.Type.IsDefined(Options.CompactAttribute, false))
            {
                item.IsCompact = true;
            }
            if (ia.Member != null && item.SerializeIf == null && !Type.IsAbstract && !Type.IsInterface)
            {
                if (Default == null)
                {
                    Default = Activator.CreateInstance(Type);
                }
                var d     = item.GetValue(Default);
                var icoll = Utils.GetICollection(item.Type);
                if (d != null && icoll != null)
                {
                    var mi = Utils.GetPrivateGeneric(
                        GetType(), nameof(IsNonEmptyCollection), icoll.GetGenericArguments()[0]);
                    item.SerializeIf =
                        (Func <object, object, bool>)
                        Delegate.CreateDelegate(typeof(Func <object, object, bool>), this, mi);
                }
                else
                {
                    item.SerializeIf = (object obj, object value) => !Object.Equals(item.GetValue(obj), d);
                }
            }
            Items.Add(item);
        }