GenerateProtocolMagicMethods(IntPtr protocolPtr, Type protocol, string[] fields)
        {
            if (protocolPtr == IntPtr.Zero)
            {
                return;
            }

            foreach (string field in fields)
            {
                if (CPyMarshal.ReadPtrField(protocolPtr, protocol, field) != IntPtr.Zero)
                {
                    string name;
                    string template;
                    Type   dgtType;
                    bool   needGetSwappedInfo;
                    MagicMethods.GetInfo(field, out name, out template, out dgtType, out needGetSwappedInfo);
                    this.methodTable[this.tablePrefix + name] = CPyMarshal.ReadFunctionPtrField(protocolPtr, protocol, field, dgtType);
                    this.code.Append(String.Format(template, name, "", this.tablePrefix));

                    if (needGetSwappedInfo)
                    {
                        MagicMethods.GetSwappedInfo(field, out name, out template, out dgtType);
                        this.methodTable[this.tablePrefix + name] = CPyMarshal.ReadFunctionPtrField(protocolPtr, protocol, field, dgtType);;
                        this.code.Append(String.Format(template, name, "", this.tablePrefix));
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Gets magic method if declared.
        /// </summary>
        public RoutineInfo this[MagicMethods magic]
        {
            get
            {
                Debug.Assert(magic != MagicMethods.undefined);

                PhpMethodInfo m;
                return((_magicMethods != null && _magicMethods.TryGetValue(magic, out m)) ? m : null);
            }
        }
Exemple #3
0
        protected TypeNode(TypeNode parent, Type parentType, MemberInfo memberInfo, Type subType = null)
            : this(parent)
        {
            if (memberInfo == null)
            {
                Type = subType;
                return;
            }

            MemberInfo = memberInfo;

            Name = memberInfo.Name;

            var propertyInfo = memberInfo as PropertyInfo;
            var fieldInfo    = memberInfo as FieldInfo;

            if (propertyInfo != null)
            {
                Type = subType ?? propertyInfo.PropertyType;

                var indexParameters = propertyInfo.GetIndexParameters();

                // ignore custom indexers
                if (indexParameters.Length == 0)
                {
                    ValueGetter = MagicMethods.MagicFunc(parentType, propertyInfo.GetGetMethod());

                    var setMethod = propertyInfo.GetSetMethod();

                    if (setMethod != null)
                    {
                        ValueSetter = MagicMethods.MagicAction(parentType, setMethod);
                    }
                }
            }
            else if (fieldInfo != null)
            {
                Type = subType ?? fieldInfo.FieldType;

                ValueGetter = fieldInfo.GetValue;
                ValueSetter = fieldInfo.SetValue;
            }
            else
            {
                throw new NotSupportedException($"{memberInfo.GetType().Name} not supported");
            }

            NullableUnderlyingType = Nullable.GetUnderlyingType(Type);

            var attributes = memberInfo.GetCustomAttributes(true).ToList();

            IsIgnored = attributes.OfType <IgnoreAttribute>().Any();

            /* Don't go any further if we're ignoring this. */
            if (IsIgnored)
            {
                return;
            }

            var fieldOrderAttribute = attributes.OfType <FieldOrderAttribute>().SingleOrDefault();
            if (fieldOrderAttribute != null)
            {
                Order = fieldOrderAttribute.Order;
            }

            var serializeAsAttribute = attributes.OfType <SerializeAsAttribute>().SingleOrDefault();
            if (serializeAsAttribute != null)
            {
                _serializedType = serializeAsAttribute.SerializedType;

#pragma warning disable 618
                if (_serializedType == SerializedType.NullTerminatedString)
                {
                    _serializedType = SerializedType.TerminatedString;
                }
#pragma warning restore 618

                if (_serializedType.Value == SerializedType.TerminatedString)
                {
                    AreStringsTerminated = true;
                    StringTerminator     = serializeAsAttribute.StringTerminator;
                }
            }

            IsNullable = NullableUnderlyingType != null;
            if (!IsNullable)
            {
                var serializedType = GetSerializedType();
                IsNullable = serializedType == SerializedType.Default ||
                             serializedType == SerializedType.ByteArray ||
                             serializedType == SerializedType.TerminatedString ||
                             serializedType == SerializedType.SizedString;
            }

            // setup bindings
            FieldLengthBindings     = GetBindings <FieldLengthAttribute>(attributes);
            FieldCountBindings      = GetBindings <FieldCountAttribute>(attributes);
            FieldOffsetBindings     = GetBindings <FieldOffsetAttribute>(attributes);
            FieldScaleBindings      = GetBindings <FieldScaleAttribute>(attributes);
            FieldEndiannessBindings = GetBindings <FieldEndiannessAttribute>(attributes);
            FieldEncodingBindings   = GetBindings <FieldEncodingAttribute>(attributes);

            var fieldAlignmentAttributes = attributes.OfType <FieldAlignmentAttribute>()
                                           .ToLookup(attribute => attribute.Mode);
            var leftAlignmentAttributes =
                fieldAlignmentAttributes[FieldAlignmentMode.LeftAndRight].Concat(
                    fieldAlignmentAttributes[FieldAlignmentMode.LeftOnly]);

            var rightAlignmentAttributes =
                fieldAlignmentAttributes[FieldAlignmentMode.LeftAndRight].Concat(
                    fieldAlignmentAttributes[FieldAlignmentMode.RightOnly]);

            LeftFieldAlignmentBindings =
                GetBindings <FieldAlignmentAttribute>(leftAlignmentAttributes.Cast <object>().ToArray());
            RightFieldAlignmentBindings =
                GetBindings <FieldAlignmentAttribute>(rightAlignmentAttributes.Cast <object>().ToArray());

            var fieldValueAttributes = attributes.OfType <FieldValueAttributeBase>().ToArray();
            FieldValueAttributes = new ReadOnlyCollection <FieldValueAttributeBase>(fieldValueAttributes);

            if (FieldValueAttributes.Count > 0)
            {
                FieldValueBindings = GetBindings <FieldValueAttributeBase>(attributes);
            }

            var serializeWhenAttributes = attributes.OfType <SerializeWhenAttribute>().ToArray();
            SerializeWhenAttributes = new ReadOnlyCollection <SerializeWhenAttribute>(serializeWhenAttributes);

            if (SerializeWhenAttributes.Count > 0)
            {
                SerializeWhenBindings = new ReadOnlyCollection <ConditionalBinding>(
                    serializeWhenAttributes.Select(
                        attribute => new ConditionalBinding(attribute, GetBindingLevel(attribute.Binding))).ToList());
            }

            var serializeWhenNotAttributes = attributes.OfType <SerializeWhenNotAttribute>().ToArray();
            SerializeWhenNotAttributes = new ReadOnlyCollection <SerializeWhenNotAttribute>(serializeWhenNotAttributes);

            if (SerializeWhenNotAttributes.Count > 0)
            {
                SerializeWhenNotBindings = new ReadOnlyCollection <ConditionalBinding>(
                    serializeWhenNotAttributes.Select(
                        attribute => new ConditionalBinding(attribute, GetBindingLevel(attribute.Binding))).ToList());
            }

            // don't inherit subtypes if this is itself a subtype
            if (subType == null)
            {
                var subtypeAttributes = attributes.OfType <SubtypeAttribute>().Cast <SubtypeBaseAttribute>().ToArray();

                SubtypeAttributes = new ReadOnlyCollection <SubtypeBaseAttribute>(subtypeAttributes);
                SubtypeBindings   = GetBindings(subtypeAttributes, Type);

                SubtypeDefaultAttribute = attributes.OfType <SubtypeDefaultAttribute>().SingleOrDefault();

                if (SubtypeDefaultAttribute != null)
                {
                    if (!Type.IsAssignableFrom(SubtypeDefaultAttribute.Subtype))
                    {
                        throw new InvalidOperationException(
                                  $"{SubtypeDefaultAttribute.Subtype} is not a subtype of {Type}");
                    }
                }

                var subtypeFactoryAttribute = attributes.OfType <SubtypeFactoryAttribute>().SingleOrDefault();
                if (subtypeFactoryAttribute != null)
                {
                    SubtypeFactoryBinding = GetBinding(subtypeFactoryAttribute);
                    SubtypeFactory        =
                        (ISubtypeFactory)subtypeFactoryAttribute.FactoryType.GetConstructor(new Type[0]).Invoke(null);
                }
            }

            var itemSubtypeAttributes = attributes.OfType <ItemSubtypeAttribute>().Cast <SubtypeBaseAttribute>()
                                        .ToArray();
            ItemSubtypeAttributes = new ReadOnlyCollection <SubtypeBaseAttribute>(itemSubtypeAttributes);

            if (itemSubtypeAttributes.Length > 0)
            {
                Type itemBaseType;

                if (Type.IsArray)
                {
                    itemBaseType = Type.GetElementType();
                }
                else if (typeof(IList).IsAssignableFrom(Type))
                {
                    var genericArguments = Type.GetGenericArguments();
                    if (genericArguments.Length > 1)
                    {
                        throw new InvalidOperationException("Multiple generic arguments not supported.");
                    }

                    itemBaseType = genericArguments[0];
                }
                else
                {
                    throw new InvalidOperationException("ItemSubtype can only be used with collections.");
                }

                ItemSubtypeBindings = GetBindings(itemSubtypeAttributes, itemBaseType);
            }

            var itemSubtypeFactoryAttribute = attributes.OfType <ItemSubtypeFactoryAttribute>().SingleOrDefault();
            if (itemSubtypeFactoryAttribute != null)
            {
                ItemSubtypeFactoryBinding = GetBinding(itemSubtypeFactoryAttribute);
                ItemSubtypeFactory        =
                    (ISubtypeFactory)itemSubtypeFactoryAttribute.FactoryType.GetConstructor(new Type[0]).Invoke(null);
            }

            ItemSubtypeDefaultAttribute = attributes.OfType <ItemSubtypeDefaultAttribute>().SingleOrDefault();

            SerializeUntilAttribute = attributes.OfType <SerializeUntilAttribute>().SingleOrDefault();
            if (SerializeUntilAttribute != null)
            {
                SerializeUntilBinding = GetBinding(SerializeUntilAttribute);
            }

            ItemLengthBindings = GetBindings <ItemLengthAttribute>(attributes);

            ItemSerializeUntilAttribute = attributes.OfType <ItemSerializeUntilAttribute>().SingleOrDefault();

            if (ItemSerializeUntilAttribute != null)
            {
                ItemSerializeUntilBinding = GetBinding(ItemSerializeUntilAttribute);
            }
        }
Exemple #4
0
        /// <summary>
        /// Gets magic method if declared.
        /// </summary>
        public RoutineInfo this[MagicMethods magic]
        {
            get
            {
                Debug.Assert(magic != MagicMethods.undefined);

                PhpMethodInfo m;
                return (_magicMethods != null && _magicMethods.TryGetValue(magic, out m)) ? m : null;
            }
        }