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)); } } } }
/// <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); } }
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); } }
/// <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; } }