Esempio n. 1
0
        ///////////////////////////////////////////////////////////////////////

        //
        // HACK: This is a horrible hack to workaround the issue with not being
        //       able to use plugin enumerated types from the "primary"
        //       application domain when the plugin has been loaded in isolated
        //       mode.
        //
        public static ReturnCode FixupOptions(
            IPluginData pluginData,
            OptionDictionary options,
            bool strict,
            ref Result error
            )
        {
            if (pluginData == null)
            {
                if (strict)
                {
                    error = "invalid plugin data";
                    return(ReturnCode.Error);
                }

                return(ReturnCode.Ok);
            }

            if (options == null)
            {
                if (strict)
                {
                    error = "invalid options";
                    return(ReturnCode.Error);
                }

                return(ReturnCode.Ok);
            }

            if (!IsIsolated(pluginData))
            {
                return(ReturnCode.Ok);
            }

            Assembly assembly = pluginData.Assembly;

            foreach (KeyValuePair <string, IOption> pair in options)
            {
                IOption option = pair.Value;

                if (option == null)
                {
                    continue;
                }

                //
                // HACK: Skip options that do not have enumerated types.
                //       For now, these are the only options we really have to
                //       worry about because they are the only ones that can
                //       directly refer to user-defined types [of any kind].
                //
                if (!option.HasFlags(OptionFlags.MustBeEnum, true))
                {
                    continue;
                }

                //
                // NOTE: Grab the enumerated (?) type and figure out if it
                //       came from the plugin assembly.  If not, ignore it and
                //       continue.
                //
                Type type = option.Type;

                if ((type == null) || !type.IsEnum ||
                    !Object.ReferenceEquals(type.Assembly, assembly))
                {
                    continue;
                }

                //
                // NOTE: Get the current value of the option.
                //
                object   oldValue = option.InnerValue;
                TypeCode typeCode = TypeCode.Empty;

                //
                // NOTE: Attempt to get the new value for the integral type for
                //       the enumeration value of this option, if any.  We must
                //       do this even if the original value is null because we
                //       must have the type code to properly reset the option
                //       flags.
                //
                object newValue = EnumOps.ConvertToTypeCodeValue(
                    type, (oldValue != null) ? oldValue : 0, ref typeCode,
                    ref error);

                if (newValue == null)
                {
                    return(ReturnCode.Error);
                }

                //
                // NOTE: Get the option flags required for the integral type.
                //
                OptionFlags flags = GetEnumOptionFlags(typeCode, strict);

                if (flags == OptionFlags.None)
                {
                    error = String.Format(
                        "unsupported type code for enumerated type \"{0}\"",
                        type);

                    return(ReturnCode.Error);
                }

                //
                // NOTE: Special handling for "flags" enumerations here.
                //
                if (EnumOps.IsFlagsEnum(type))
                {
                    //
                    // HACK: Substitute our placeholder flags enumerated type.
                    //       It does not know about the textual values provided
                    //       by the actual enumerated type; however, at least
                    //       they can use the custom flags enumeration handling
                    //       (i.e. the "+" and "-" operators, etc).
                    //
                    option.Type = typeof(StubFlagsEnum);
                }
                else
                {
                    //
                    // NOTE: Remove the MustBeEnum flag for this option and add
                    //       the flag(s) needed for its integral type.
                    //
                    option.Flags &= ~OptionFlags.MustBeEnum;
                    option.Flags |= flags;

                    //
                    // NOTE: Clear the type for the option.  The type property
                    //       is only meaningful for enumeration-based options
                    //       and we are converting this option to use some kind
                    //       of integral type.
                    //
                    option.Type = null;
                }

                //
                // NOTE: If necessary, set the new [default] value for this
                //       option to the one we converted to an integral type
                //       value above.  If the old (original) value was null, we
                //       just discard the new value which will be zero anyhow.
                //
                option.Value = (oldValue != null) ? new Variant(newValue) : null;
            }

            return(ReturnCode.Ok);
        }