示例#1
0
文件: Open.cs 项目: jdruin/F5Eagle
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string fileName = arguments[1];

                        if (interpreter.HasChannels(ref result))
                        {
                            MapOpenAccess access      = MapOpenAccess.Default;
                            int           permissions = 0; // NOTE: This is ONLY parsed, NOT used for opening the file.
                            string        type        = null;

                            if (arguments.Count >= 3)
                            {
                                Result enumString = arguments[2];

                                if (!String.IsNullOrEmpty(enumString))
                                {
                                    //
                                    // HACK: Translate illegal mode char "+" to what our Enum uses.
                                    //       This strategy will backfire later if we ever decide to
                                    //       allow parsing of the access mode as "flags" (via GetOptions).
                                    //
                                    enumString = enumString.Replace(Characters.PlusSign.ToString(), "Plus");
                                }

                                code = StringOps.StringToEnumList(interpreter, enumString, ref enumString);

                                if (code == ReturnCode.Ok)
                                {
                                    object enumValue = EnumOps.TryParseEnum(
                                        typeof(MapOpenAccess), enumString,
                                        true, true);

                                    if (enumValue is MapOpenAccess)
                                    {
                                        access = (MapOpenAccess)enumValue;
                                    }
                                    else
                                    {
                                        enumString = ScriptOps.BadValue(
                                            "invalid", "access mode", arguments[2],
                                            Enum.GetNames(typeof(MapOpenAccess)), null, null);

                                        code = ReturnCode.Error;
                                    }
                                }

                                if (code != ReturnCode.Ok)
                                {
                                    //
                                    // NOTE: Transfer local result from above and add to the error info.
                                    //
                                    result = enumString;

                                    Engine.AddErrorInformation(interpreter, result,
                                                               String.Format("{0}    while processing open access modes \"{1}\"",
                                                                             Environment.NewLine, FormatOps.Ellipsis(arguments[2])));
                                }
                            }

                            if ((code == ReturnCode.Ok) && (arguments.Count >= 4))
                            {
                                code = Value.GetInteger2(
                                    (IGetValue)arguments[3], ValueFlags.AnyInteger,
                                    interpreter.CultureInfo, ref permissions, ref result);
                            }

                            if (code == ReturnCode.Ok)
                            {
                                if (arguments.Count >= 5)
                                {
                                    type = arguments[4];
                                }

                                OptionDictionary options = new OptionDictionary(
                                    new IOption[] {
#if CONSOLE
                                    new Option(null, OptionFlags.None, 1, Index.Invalid, "-stdin", null),
                                    new Option(null, OptionFlags.None, 1, Index.Invalid, "-stdout", null),
                                    new Option(null, OptionFlags.None, 1, Index.Invalid, "-stderr", null),
#else
                                    new Option(null, OptionFlags.Unsupported, 1, Index.Invalid, "-stdin", null),
                                    new Option(null, OptionFlags.Unsupported, 1, Index.Invalid, "-stdout", null),
                                    new Option(null, OptionFlags.Unsupported, 1, Index.Invalid, "-stderr", null),
#endif
                                    new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-channelid", null),
                                    new Option(null, OptionFlags.MustHaveIntegerValue, Index.Invalid, Index.Invalid, "-buffersize", null),
                                    new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-autoflush", null),
                                    new Option(typeof(HostStreamFlags), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-streamflags",
                                               new Variant(HostStreamFlags.Default)),
                                    new Option(typeof(FileOptions), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-options",
                                               new Variant(FileOptions.None)),
                                    new Option(typeof(FileShare), OptionFlags.MustHaveEnumValue, Index.Invalid, Index.Invalid, "-share",
                                               new Variant(FileShare.Read))
                                });

                                int argumentIndex = Index.Invalid;

                                if (arguments.Count > 5)
                                {
                                    code = interpreter.GetOptions(options, arguments, 0, 5, Index.Invalid, true, ref argumentIndex, ref result);
                                }
                                else
                                {
                                    code = ReturnCode.Ok;
                                }

                                if (code == ReturnCode.Ok)
                                {
                                    if (argumentIndex == Index.Invalid)
                                    {
                                        Variant value     = null;
                                        string  channelId = null;

                                        if (options.IsPresent("-channelid", ref value))
                                        {
                                            channelId = value.ToString();
                                        }

                                        if ((channelId == null) ||
                                            (interpreter.DoesChannelExist(channelId) != ReturnCode.Ok))
                                        {
#if CONSOLE
                                            if (options.IsPresent("-stdin"))
                                            {
                                                //
                                                // NOTE: Enforce the proper access for the standard input
                                                //       channel.
                                                //
                                                if (access == MapOpenAccess.RdOnly)
                                                {
                                                    try
                                                    {
                                                        IStreamHost streamHost = interpreter.Host;

                                                        //
                                                        // NOTE: *WARNING* This option causes the "fileName",
                                                        //       "access", "permissions", and "type" arguments
                                                        //       to be ignored.
                                                        //
                                                        lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                                        {
                                                            if (streamHost.In == null)
                                                            {
                                                                int?bufferSize = null;

                                                                if (options.IsPresent("-buffersize", ref value))
                                                                {
                                                                    bufferSize = (int)value.Value;
                                                                }

                                                                streamHost.In = (bufferSize != null) ?
                                                                                Console.OpenStandardInput((int)bufferSize) :
                                                                                Console.OpenStandardInput();
                                                            }
                                                        }

                                                        code = interpreter.ModifyStandardChannels(
                                                            streamHost, channelId, ChannelType.Input |
                                                            ChannelType.ErrorOnExist, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            result = (channelId != null) ? channelId : StandardChannel.Input;
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "illegal access mode \"{0}\", standard input " +
                                                        "can only be opened using access mode \"{1}\"",
                                                        access, MapOpenAccess.RdOnly);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else if (options.IsPresent("-stdout"))
                                            {
                                                //
                                                // NOTE: Enforce the proper access for the standard output
                                                //       channel.
                                                //
                                                if (access == MapOpenAccess.WrOnly)
                                                {
                                                    try
                                                    {
                                                        IStreamHost streamHost = interpreter.Host;

                                                        //
                                                        // NOTE: *WARNING* This option causes the "fileName",
                                                        //       "access", "permissions", and "type" arguments
                                                        //       to be ignored.
                                                        //
                                                        lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                                        {
                                                            if (streamHost.Out == null)
                                                            {
                                                                int?bufferSize = null;

                                                                if (options.IsPresent("-buffersize", ref value))
                                                                {
                                                                    bufferSize = (int)value.Value;
                                                                }

                                                                streamHost.Out = (bufferSize != null) ?
                                                                                 Console.OpenStandardOutput((int)bufferSize) :
                                                                                 Console.OpenStandardOutput();
                                                            }
                                                        }

                                                        code = interpreter.ModifyStandardChannels(
                                                            streamHost, channelId, ChannelType.Output |
                                                            ChannelType.ErrorOnExist, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            result = (channelId != null) ? channelId : StandardChannel.Output;
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "illegal access mode \"{0}\", standard output " +
                                                        "can only be opened using access mode \"{1}\"",
                                                        access, MapOpenAccess.WrOnly);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else if (options.IsPresent("-stderr"))
                                            {
                                                //
                                                // NOTE: Enforce the proper access for the standard error
                                                //       channel.
                                                //
                                                if (access == MapOpenAccess.WrOnly)
                                                {
                                                    try
                                                    {
                                                        IStreamHost streamHost = interpreter.Host;

                                                        //
                                                        // NOTE: *WARNING* This option causes the "fileName",
                                                        //       "access", "permissions", and "type" arguments
                                                        //       to be ignored.
                                                        //
                                                        lock (interpreter.SyncRoot) /* TRANSACTIONAL */
                                                        {
                                                            if (streamHost.Error == null)
                                                            {
                                                                int?bufferSize = null;

                                                                if (options.IsPresent("-buffersize", ref value))
                                                                {
                                                                    bufferSize = (int)value.Value;
                                                                }

                                                                streamHost.Error = (bufferSize != null) ?
                                                                                   Console.OpenStandardError((int)bufferSize) :
                                                                                   Console.OpenStandardError();
                                                            }
                                                        }

                                                        code = interpreter.ModifyStandardChannels(
                                                            streamHost, channelId, ChannelType.Error |
                                                            ChannelType.ErrorOnExist, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            result = (channelId != null) ? channelId : StandardChannel.Error;
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                }
                                                else
                                                {
                                                    result = String.Format(
                                                        "illegal access mode \"{0}\", standard error " +
                                                        "can only be opened using access mode \"{1}\"",
                                                        access, MapOpenAccess.WrOnly);

                                                    code = ReturnCode.Error;
                                                }
                                            }
                                            else
#endif
                                            {
                                                Stream stream    = null;
                                                bool   autoFlush = false;

                                                switch (type)
                                                {
                                                case null:                      /* FALL-THROUGH */
                                                case /* String.Empty */ "":     /* FALL-THROUGH */
                                                case "file":
                                                {
                                                    try
                                                    {
                                                        HostStreamFlags hostStreamFlags = HostStreamFlags.OpenCommand;
                                                        FileAccess      fileAccess      = FileOps.FileAccessFromAccess(access);
                                                        FileMode        fileMode        = FileOps.FileModeFromAccess(access);
                                                        FileShare       fileShare       = FileShare.Read;

                                                        if (options.IsPresent("-streamflags", ref value))
                                                        {
                                                            hostStreamFlags = (HostStreamFlags)value.Value;
                                                        }

                                                        if (options.IsPresent("-share", ref value))
                                                        {
                                                            fileShare = (FileShare)value.Value;
                                                        }

                                                        int bufferSize = Channel.DefaultBufferSize;

                                                        if (options.IsPresent("-buffersize", ref value))
                                                        {
                                                            bufferSize = (int)value.Value;
                                                        }

                                                        FileOptions fileOptions = FileOptions.None;

                                                        if (options.IsPresent("-options", ref value))
                                                        {
                                                            fileOptions = (FileOptions)value.Value;
                                                        }

                                                        if (options.IsPresent("-autoflush"))
                                                        {
                                                            autoFlush = true;
                                                        }

                                                        bool seekToEof = false;

                                                        //
                                                        // HACK: Check for special case where they want to Append
                                                        //       and Read/ReadWrite.
                                                        //
                                                        if (((fileAccess == FileAccess.Read) ||
                                                             (fileAccess == FileAccess.ReadWrite)) &&
                                                            (FlagOps.HasFlags(access, MapOpenAccess.SeekToEof, true) ||
                                                             FlagOps.HasFlags(access, MapOpenAccess.Append, true)))
                                                        {
                                                            seekToEof = true;
                                                        }

                                                        code = interpreter.GetStream(
                                                            fileName, fileMode, fileAccess, fileShare, bufferSize,
                                                            fileOptions, Channel.StrictGetStream, ref hostStreamFlags,
                                                            ref stream, ref result);

                                                        if (code == ReturnCode.Ok)
                                                        {
                                                            if ((stream != null) && seekToEof)
                                                            {
                                                                stream.Seek(0, SeekOrigin.End);
                                                            }
                                                        }
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        Engine.SetExceptionErrorCode(interpreter, e);

                                                        result = e;
                                                        code   = ReturnCode.Error;
                                                    }
                                                    break;
                                                }

                                                default:
                                                {
                                                    result = String.Format(
                                                        "unsupported channel type \"{0}\"",
                                                        type);

                                                    code = ReturnCode.Error;
                                                    break;
                                                }
                                                }

                                                //
                                                // NOTE: Did we manage to open the file successfully?
                                                //
                                                if (code == ReturnCode.Ok)
                                                {
                                                    StreamFlags flags = StreamFlags.PreventClose;

                                                    if (channelId == null)
                                                    {
                                                        channelId = FormatOps.Id("file", null, interpreter.NextId());
                                                    }

                                                    code = interpreter.AddFileOrSocketChannel(
                                                        channelId, stream, options, flags,
                                                        FlagOps.HasFlags(access, MapOpenAccess.Append, true),
                                                        autoFlush, null, ref result);

                                                    if (code == ReturnCode.Ok)
                                                    {
                                                        result = channelId;
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "can't add \"{0}\": channel already exists",
                                                channelId);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                    else
                                    {
                                        result = "wrong # args: should be \"open fileName ?access? ?permissions? ?type? ?options?\"";
                                        code   = ReturnCode.Error;
                                    }
                                }
                            }
                        }
                        else
                        {
                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"open fileName ?access? ?permissions? ?type? ?options?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#2
0
文件: Exit.cs 项目: jdruin/F5Eagle
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 1)
                    {
                        OptionDictionary options = new OptionDictionary(
                            new IOption[] {
                            new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-force", null),
                            new Option(null, OptionFlags.Unsafe, Index.Invalid, Index.Invalid, "-fail", null),
                            new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-message", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-current", null),
                            new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, Option.EndOfOptions, null)
                        });

                        int argumentIndex = Index.Invalid;

                        if (arguments.Count > 1)
                        {
                            code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result);
                        }
                        else
                        {
                            code = ReturnCode.Ok;
                        }

                        if (code == ReturnCode.Ok)
                        {
                            if ((argumentIndex == Index.Invalid) ||
                                ((argumentIndex + 1) == arguments.Count))
                            {
                                bool force = false;

                                if (options.IsPresent("-force"))
                                {
                                    force = true;
                                }

                                bool fail = false;

                                if (options.IsPresent("-fail"))
                                {
                                    fail = true;
                                }

                                Variant value   = null;
                                string  message = null;

                                if (options.IsPresent("-message", ref value))
                                {
                                    message = value.ToString();
                                }

                                //
                                // NOTE: The default exit code is "success" (i.e. zero).
                                //
                                ExitCode exitCode = ResultOps.SuccessExitCode();

                                if (options.IsPresent("-current"))
                                {
                                    exitCode = interpreter.ExitCode;
                                }

                                //
                                // NOTE: Was an exit code specified in the command?
                                //
                                if (argumentIndex != Index.Invalid)
                                {
                                    object enumValue = EnumOps.TryParseEnum(
                                        typeof(ExitCode), arguments[argumentIndex],
                                        true, true, ref result);

                                    if (enumValue is ExitCode)
                                    {
                                        exitCode = (ExitCode)enumValue;
                                    }
                                    else
                                    {
                                        result = ScriptOps.BadValue(
                                            null, "exit code", arguments[argumentIndex],
                                            Enum.GetNames(typeof(ExitCode)), null, ", or an integer");

                                        code = ReturnCode.Error;
                                    }
                                }

                                //
                                // NOTE: Make sure we succeeded at coverting the exit code to an integer.
                                //
                                if (code == ReturnCode.Ok)
                                {
                                    //
                                    // NOTE: Make sure the interpreter host, if any, agrees to exit (i.e. it may deny the
                                    //       request if the application is doing something that should not be interrupted).
                                    //
                                    code = interpreter.CanExit(exitCode, force, fail, message, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        //
                                        // NOTE: Exit the application (either by marking the current interpreter as "exited"
                                        //       or physically exiting the containing process).
                                        //
                                        TraceOps.DebugTrace(String.Format(
                                                                "Execute: {0}, interpreter = {1}, message = {2}",
                                                                force && fail ?
                                                                "forcibly failing" : force ? "forcibly exiting" : "exiting",
                                                                FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(message)),
                                                            typeof(Exit).Name, TracePriority.Command);

                                        if (force)
                                        {
#if !MONO
                                            if (fail && !CommonOps.Runtime.IsMono())
                                            {
                                                try
                                                {
                                                    //
                                                    // NOTE: Using this method to exit a script is NOT recommended unless
                                                    //       you are trying to prevent damaging another part of the system.
                                                    //
                                                    // MONO: This method is not supported by the Mono runtime.
                                                    //
                                                    Environment.FailFast(message);

                                                    /* NOT REACHED */
                                                    result = "failed to exit process";
                                                    code   = ReturnCode.Error;
                                                }
                                                catch (Exception e)
                                                {
                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }
                                            }
                                            else
#endif
                                            {
                                                //
                                                // BUGFIX: Try to dispose our containing interpreter now.  We must do
                                                //         this to prevent it from being disposed on a random GC thread.
                                                //
                                                try
                                                {
                                                    interpreter.Dispose();
                                                    interpreter = null;
                                                }
                                                catch (Exception e)
                                                {
                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }

                                                //
                                                // NOTE: If we could not dispose the interpreter properly, complain;
                                                //       however, keep exiting anyway.
                                                //
                                                if (code != ReturnCode.Ok)
                                                {
                                                    DebugOps.Complain(interpreter, code, result);
                                                }

                                                try
                                                {
                                                    //
                                                    // NOTE: Using this method to exit a script is NOT recommended unless
                                                    //       you are running a standalone script in the Eagle Shell (i.e.
                                                    //       you are not hosted within another application).
                                                    //
                                                    Environment.Exit((int)exitCode);

                                                    /* NOT REACHED */
                                                    result = "failed to exit process";
                                                    code   = ReturnCode.Error;
                                                }
                                                catch (Exception e)
                                                {
                                                    result = e;
                                                    code   = ReturnCode.Error;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            interpreter.ExitCode = exitCode;
                                            interpreter.Exit     = true;

                                            result = String.Empty;
                                            code   = ReturnCode.Ok;
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if ((argumentIndex != Index.Invalid) &&
                                    Option.LooksLikeOption(arguments[argumentIndex]))
                                {
                                    result = OptionDictionary.BadOption(options, arguments[argumentIndex]);
                                }
                                else
                                {
                                    result = "wrong # args: should be \"exit ?options? ?returnCode?\"";
                                }

                                code = ReturnCode.Error;
                            }
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"exit ?options? ?returnCode?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#3
0
        ///////////////////////////////////////////////////////////////////////////////////////////////

        #region IExecuteArgument Members
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Argument value,
            ref Result error
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count == (this.Arguments + 1))
                    {
                        Variant variant1 = null;

                        code = Value.GetVariant(interpreter,
                                                (IGetValue)arguments[1], ValueFlags.AnyVariant,
                                                interpreter.CultureInfo, ref variant1, ref error);

                        int intValue = 0;

                        if (code == ReturnCode.Ok)
                        {
                            code = Value.GetInteger2(
                                (IGetValue)arguments[2], ValueFlags.AnyInteger,
                                interpreter.CultureInfo, ref intValue, ref error);
                        }

                        MidpointRounding rounding = MidpointRounding.ToEven; // TODO: Good default?

                        if (code == ReturnCode.Ok)
                        {
                            object enumValue = EnumOps.TryParseEnum(
                                typeof(MidpointRounding), arguments[3], true,
                                true, ref error);

                            if (enumValue is MidpointRounding)
                            {
                                rounding = (MidpointRounding)enumValue;
                            }
                            else
                            {
                                code = ReturnCode.Error;
                            }
                        }

                        if (code == ReturnCode.Ok)
                        {
                            try
                            {
                                if (variant1.IsDouble())
                                {
                                    //
                                    // NOTE: No FixPrecision, Already rounding.
                                    //
                                    value = Math.Round((double)variant1.Value, intValue, rounding);
                                }
                                else if (variant1.IsDecimal())
                                {
                                    //
                                    // NOTE: No FixPrecision, Already rounding.
                                    //
                                    value = Math.Round((decimal)variant1.Value, intValue, rounding);
                                }
                                else if (variant1.IsWideInteger())
                                {
                                    value = ((long)variant1.Value);
                                }
                                else if (variant1.IsInteger())
                                {
                                    value = ((int)variant1.Value);
                                }
                                else if (variant1.IsBoolean())
                                {
                                    value = ((bool)variant1.Value);
                                }
                                else
                                {
                                    error = String.Format(
                                        "unsupported variant type for function \"{0}\"",
                                        base.Name);

                                    code = ReturnCode.Error;
                                }
                            }
                            catch (Exception e)
                            {
                                Engine.SetExceptionErrorCode(interpreter, e);

                                error = String.Format(
                                    "caught math exception: {0}",
                                    e);

                                code = ReturnCode.Error;
                            }
                        }
                    }
                    else
                    {
                        if (arguments.Count > (this.Arguments + 1))
                        {
                            error = String.Format(
                                "too many arguments for math function \"{0}\"",
                                base.Name);
                        }
                        else
                        {
                            error = String.Format(
                                "too few arguments for math function \"{0}\"",
                                base.Name);
                        }

                        code = ReturnCode.Error;
                    }
                }
                else
                {
                    error = "invalid argument list";
                    code  = ReturnCode.Error;
                }
            }
            else
            {
                error = "invalid interpreter";
                code  = ReturnCode.Error;
            }

            return(code);
        }
示例#4
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if ((arguments.Count == 3) || (arguments.Count == 4))
                    {
                        string  channelId = arguments[1];
                        Channel channel   = interpreter.GetChannel(channelId, ref result);

                        if (channel != null)
                        {
                            long offset = 0;

                            code = Value.GetWideInteger2(
                                (IGetValue)arguments[2], ValueFlags.AnyWideInteger,
                                interpreter.CultureInfo, ref offset, ref result);

                            if (code == ReturnCode.Ok)
                            {
                                SeekOrigin origin = SeekOrigin.Begin;

                                if (arguments.Count >= 4)
                                {
                                    object enumValue = EnumOps.TryParseEnum(
                                        typeof(MapSeekOrigin), arguments[3],
                                        true, true);

                                    if (enumValue is MapSeekOrigin)
                                    {
                                        origin = (SeekOrigin)enumValue;
                                    }
                                    else
                                    {
                                        result = String.Format(
                                            "bad origin \"{0}\": must be start, current, or end",
                                            arguments[3]);

                                        code = ReturnCode.Error;
                                    }
                                }

                                if (code == ReturnCode.Ok)
                                {
                                    try
                                    {
                                        if (channel.CanSeek)
                                        {
                                            channel.Seek(offset, origin);
                                            result = String.Empty;
                                        }
                                        else
                                        {
                                            result = String.Format(
                                                "error during seek on \"{0}\": invalid argument",
                                                channelId);

                                            code = ReturnCode.Error;
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        Engine.SetExceptionErrorCode(interpreter, e);

                                        result = e;
                                        code   = ReturnCode.Error;
                                    }
                                }
                            }
                        }
                        else
                        {
                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"seek channelId offset ?origin?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }
示例#5
0
        ///////////////////////////////////////////////////////////////////////

#if XML
        private static ReturnCode FromDocument(
            XmlDocument document,
            InterpreterSettings interpreterSettings,
            ref Result error
            )
        {
            if (document == null)
            {
                error = "invalid xml document";
                return(ReturnCode.Error);
            }

            if (interpreterSettings == null)
            {
                error = "invalid interpreter settings";
                return(ReturnCode.Error);
            }

            XmlElement documentElement = document.DocumentElement;

            if (documentElement == null)
            {
                error = "invalid xml document element";
                return(ReturnCode.Error);
            }

            XmlNode node;

            node = documentElement.SelectSingleNode("Args");

            if ((node != null) && !String.IsNullOrEmpty(node.InnerText))
            {
                StringList list = null;

                if (Parser.SplitList(
                        null, node.InnerText, 0, Length.Invalid, false,
                        ref list, ref error) == ReturnCode.Ok)
                {
                    interpreterSettings.Args = list;
                }
                else
                {
                    return(ReturnCode.Error);
                }
            }

            node = documentElement.SelectSingleNode("CreateFlags");

            if ((node != null) && !String.IsNullOrEmpty(node.InnerText))
            {
                object enumValue = EnumOps.TryParseEnum(
                    typeof(CreateFlags), node.InnerText,
                    true, true, ref error);

                if (enumValue is CreateFlags)
                {
                    interpreterSettings.CreateFlags = (CreateFlags)enumValue;
                }
                else
                {
                    return(ReturnCode.Error);
                }
            }

            node = documentElement.SelectSingleNode("InitializeFlags");

            if ((node != null) && !String.IsNullOrEmpty(node.InnerText))
            {
                object enumValue = EnumOps.TryParseEnum(
                    typeof(InitializeFlags), node.InnerText,
                    true, true, ref error);

                if (enumValue is InitializeFlags)
                {
                    interpreterSettings.InitializeFlags = (InitializeFlags)enumValue;
                }
                else
                {
                    return(ReturnCode.Error);
                }
            }

            node = documentElement.SelectSingleNode("ScriptFlags");

            if ((node != null) && !String.IsNullOrEmpty(node.InnerText))
            {
                object enumValue = EnumOps.TryParseEnum(
                    typeof(ScriptFlags), node.InnerText,
                    true, true, ref error);

                if (enumValue is ScriptFlags)
                {
                    interpreterSettings.ScriptFlags = (ScriptFlags)enumValue;
                }
                else
                {
                    return(ReturnCode.Error);
                }
            }

            node = documentElement.SelectSingleNode("InterpreterFlags");

            if ((node != null) && !String.IsNullOrEmpty(node.InnerText))
            {
                object enumValue = EnumOps.TryParseEnum(
                    typeof(InterpreterFlags), node.InnerText,
                    true, true, ref error);

                if (enumValue is InterpreterFlags)
                {
                    interpreterSettings.InterpreterFlags = (InterpreterFlags)enumValue;
                }
                else
                {
                    return(ReturnCode.Error);
                }
            }

            node = documentElement.SelectSingleNode("AutoPathList");

            if ((node != null) && !String.IsNullOrEmpty(node.InnerText))
            {
                StringList list = null;

                if (Parser.SplitList(
                        null, node.InnerText, 0, Length.Invalid, false,
                        ref list, ref error) == ReturnCode.Ok)
                {
                    interpreterSettings.AutoPathList = list;
                }
                else
                {
                    return(ReturnCode.Error);
                }
            }

            return(ReturnCode.Ok);
        }
示例#6
0
        public override ReturnCode Execute(
            Interpreter interpreter,
            IClientData clientData,
            ArgumentList arguments,
            ref Result result
            )
        {
            ReturnCode code = ReturnCode.Ok;

            if (interpreter != null)
            {
                if (arguments != null)
                {
                    if (arguments.Count >= 2)
                    {
                        string  channelId = arguments[1];
                        Channel channel   = interpreter.GetChannel(channelId, ref result);

                        if (channel != null)
                        {
                            try
                            {
                                if (arguments.Count >= 4)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                        new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-blocking", null),
                                        new Option(null, OptionFlags.MustHaveEncodingValue, Index.Invalid, Index.Invalid, "-encoding", null),
                                        new Option(null, OptionFlags.MustHaveListValue, Index.Invalid, Index.Invalid, "-translation", null)
                                    });

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if (argumentIndex == Index.Invalid)
                                        {
                                            Variant value        = null;
                                            bool?   blockingMode = null;

                                            if (options.IsPresent("-blocking"))
                                            {
                                                blockingMode = (bool)value.Value;
                                            }

                                            Encoding encoding = null;

                                            if (options.IsPresent("-encoding", ref value))
                                            {
                                                encoding = (Encoding)value.Value;
                                            }

                                            StringList translationNames = null;

                                            if (options.IsPresent("-translation", ref value))
                                            {
                                                translationNames = (StringList)value.Value;
                                            }

                                            StreamTranslationList translation = null;

                                            if (translationNames != null)
                                            {
                                                if ((translationNames.Count == 1) || (translationNames.Count == 2))
                                                {
                                                    translation = new StreamTranslationList();

                                                    foreach (string translationName in translationNames)
                                                    {
                                                        object enumValue = EnumOps.TryParseEnum(
                                                            typeof(StreamTranslation), translationName,
                                                            true, true);

                                                        if (enumValue is StreamTranslation)
                                                        {
                                                            translation.Add((StreamTranslation)enumValue);
                                                        }
                                                        else
                                                        {
                                                            result = ScriptOps.BadValue(
                                                                null, "value for -translation", translationName,
                                                                Enum.GetNames(typeof(StreamTranslation)),
                                                                null, null);

                                                            code = ReturnCode.Error;
                                                            break;
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    result = "bad value for -translation: must be a one or two element list";
                                                    code   = ReturnCode.Error;
                                                }
                                            }

                                            if (code == ReturnCode.Ok)
                                            {
                                                if (blockingMode != null)
                                                {
                                                    channel.SetBlockingMode((bool)blockingMode);
                                                }

                                                if (encoding != null)
                                                {
                                                    channel.SetEncoding(encoding);
                                                }

                                                if (translation != null)
                                                {
                                                    channel.SetTranslation(translation);
                                                }

                                                result = String.Empty;
                                            }
                                        }
                                        else
                                        {
                                            result = "wrong # args: should be \"fconfigure channelId ?optionName? ?value?\"";
                                            code   = ReturnCode.Error;
                                        }
                                    }
                                }
                                else if (arguments.Count == 3)
                                {
                                    OptionDictionary options = new OptionDictionary(
                                        new IOption[] {
                                        new Option(null, OptionFlags.MustHaveBooleanValue, Index.Invalid, Index.Invalid, "-blocking", null),
                                        new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-encoding", null),
                                        new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-translation", null)
                                    });

                                    int argumentIndex = Index.Invalid;

                                    code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result);

                                    if (code == ReturnCode.Ok)
                                    {
                                        if (argumentIndex == Index.Invalid)
                                        {
                                            StringList list = new StringList();

                                            if (options.IsPresent("-blocking"))
                                            {
                                                list.Add(channel.GetBlockingMode().ToString());
                                            }

                                            if (options.IsPresent("-encoding"))
                                            {
                                                list.Add(channel.GetEncoding().WebName);
                                            }

                                            if (options.IsPresent("-translation"))
                                            {
                                                list.Add(channel.GetTranslation().ToString());
                                            }

                                            if (list.Count > 1)
                                            {
                                                result = list;
                                            }
                                            else if (list.Count == 1)
                                            {
                                                result = list[0];
                                            }
                                            else
                                            {
                                                result = String.Empty;
                                            }
                                        }
                                        else
                                        {
                                            result = "wrong # args: should be \"fconfigure channelId ?optionName? ?value?\"";
                                            code   = ReturnCode.Error;
                                        }
                                    }
                                }
                                else
                                {
                                    Encoding encoding = channel.GetEncoding();
                                    StreamTranslationList translation = channel.GetTranslation();

                                    result = StringList.MakeList(
                                        "-blocking", channel.GetBlockingMode(),
                                        "-encoding", (encoding != null) ?
                                        encoding.WebName : StringOps.NullEncodingName,
                                        "-translation", translation);
                                }
                            }
                            catch (Exception e)
                            {
                                Engine.SetExceptionErrorCode(interpreter, e);

                                result = e;
                                code   = ReturnCode.Error;
                            }
                        }
                        else
                        {
                            code = ReturnCode.Error;
                        }
                    }
                    else
                    {
                        result = "wrong # args: should be \"fconfigure channelId ?optionName? ?value?\"";
                        code   = ReturnCode.Error;
                    }
                }
                else
                {
                    result = "invalid argument list";
                    code   = ReturnCode.Error;
                }
            }
            else
            {
                result = "invalid interpreter";
                code   = ReturnCode.Error;
            }

            return(code);
        }