/////////////////////////////////////////////////////////////////////// #region Callback Methods private ReturnCode InterruptCallback( Interpreter interpreter, /* NOTE: Parent interpreter. */ InterruptType interruptType, IClientData clientData, ref Result error ) /* throw */ { // // NOTE: If the are no callback arguments configured, just skip it // and return success. // StringList arguments = CallbackArguments; if (arguments == null) /* NOTE: Disabled? */ { return(ReturnCode.Ok); } Interpreter debugInterpreter = this.interpreter; if (debugInterpreter == null) { error = "debugger interpreter not available"; return(ReturnCode.Error); } // // NOTE: *WARNING* This is a cross-interpreter call, do NOT dispose // the parent interpreter because we do not own it. This is // guaranteed by using the NoDispose object flag (indirectly) // here. // ICallback callback = CommandCallback.Create( MarshalFlags.Default, CallbackFlags.Default, ObjectFlags.Callback, ByRefArgumentFlags.None, debugInterpreter, clientData, null, new StringList( arguments), ref error); if (callback == null) { return(ReturnCode.Error); } try { callback.FireEventHandler(this, RuntimeOps.GetInterruptEventArgs(interpreter, interruptType, clientData) as EventArgs); return(ReturnCode.Ok); } catch (Exception e) { error = e; } return(ReturnCode.Error); }
public override ReturnCode Execute( Interpreter interpreter, IClientData clientData, ArgumentList arguments, ref Result result ) { ReturnCode code; if (interpreter != null) { if (arguments != null) { if (arguments.Count >= 2) { string subCommand = arguments[1]; bool tried = false; code = ScriptOps.TryExecuteSubCommandFromEnsemble( interpreter, this, clientData, arguments, true, false, ref subCommand, ref tried, ref result); if ((code == ReturnCode.Ok) && !tried) { // // NOTE: Programmatically interact with the debugger (breakpoint, watch, // eval, etc). // switch (subCommand) { case "clear": { if (arguments.Count == 2) { code = interpreter.ClearCallbackQueue(ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { result = "wrong # args: should be \"callback clear\""; code = ReturnCode.Error; } break; } case "count": { if (arguments.Count == 2) { int count = 0; code = interpreter.CountCallbacks(ref count, ref result); if (code == ReturnCode.Ok) { result = count; } } else { result = "wrong # args: should be \"callback count\""; code = ReturnCode.Error; } break; } case "dequeue": { if (arguments.Count >= 2) { OptionDictionary options = ObjectOps.GetDequeueOptions(); int argumentIndex = Index.Invalid; if (arguments.Count > 2) { code = interpreter.GetOptions(options, arguments, 0, 2, Index.Invalid, true, ref argumentIndex, ref result); } else { code = ReturnCode.Ok; } if (code == ReturnCode.Ok) { if (argumentIndex == Index.Invalid) { Type returnType; ObjectFlags objectFlags; string objectName; string interpName; bool create; bool dispose; bool alias; bool aliasRaw; bool aliasAll; bool aliasReference; bool toString; ObjectOps.ProcessFixupReturnValueOptions( options, null, out returnType, out objectFlags, out objectName, out interpName, out create, out dispose, out alias, out aliasRaw, out aliasAll, out aliasReference, out toString); // // NOTE: Which Tcl interpreter do we want a command alias created // in, if any? // ICallback callback = null; code = interpreter.DequeueCallback(ref callback, ref result); if (code == ReturnCode.Ok) { ObjectOptionType objectOptionType = ObjectOptionType.Dequeue | ObjectOps.GetOptionType(aliasRaw, aliasAll); code = MarshalOps.FixupReturnValue( interpreter, interpreter.Binder, interpreter.CultureInfo, returnType, objectFlags, ObjectOps.GetInvokeOptions( objectOptionType), objectOptionType, objectName, interpName, callback, create, dispose, alias, aliasReference, toString, ref result); } } else { result = "wrong # args: should be \"callback dequeue ?options?\""; code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"callback dequeue ?options?\""; code = ReturnCode.Error; } break; } case "enqueue": { if (arguments.Count >= 3) { ICallback callback = CommandCallback.Create( MarshalFlags.Default, CallbackFlags.Default, ObjectFlags.Callback, ByRefArgumentFlags.None, interpreter, clientData, null, new StringList( arguments, 2), ref result); if (callback != null) { code = interpreter.EnqueueCallback(callback, ref result); if (code == ReturnCode.Ok) { result = String.Empty; } } else { code = ReturnCode.Error; } } else { result = "wrong # args: should be \"callback enqueue name ?arg ...?\""; code = ReturnCode.Error; } break; } case "execute": { if (arguments.Count == 2) { code = interpreter.ExecuteCallbackQueue(ref result); } else { result = "wrong # args: should be \"callback execute\""; code = ReturnCode.Error; } break; } case "list": { if ((arguments.Count == 2) || (arguments.Count == 3)) { string pattern = null; if (arguments.Count == 3) { pattern = arguments[2]; } StringList list = null; code = interpreter.ListCallbacks( pattern, false, ref list, ref result); if (code == ReturnCode.Ok) { result = list; } } else { result = "wrong # args: should be \"callback list ?pattern?\""; code = ReturnCode.Error; } break; } default: { result = ScriptOps.BadSubCommand( interpreter, null, null, subCommand, this, null, null); code = ReturnCode.Error; break; } } } } else { result = "wrong # args: should be \"callback option ?arg ...?\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
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) { OptionDictionary options = new OptionDictionary( new IOption[] { new Option(null, OptionFlags.None, 1, Index.Invalid, "-ascii", null), new Option(null, OptionFlags.None, 1, Index.Invalid, "-dictionary", null), new Option(null, OptionFlags.None, 1, Index.Invalid, "-integer", null), new Option(null, OptionFlags.None, 1, Index.Invalid, "-random", null), new Option(null, OptionFlags.None, 1, Index.Invalid, "-real", null), new Option(null, OptionFlags.None, 2, Index.Invalid, "-increasing", null), new Option(null, OptionFlags.None, 2, Index.Invalid, "-decreasing", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-nocase", null), new Option(null, OptionFlags.None, Index.Invalid, Index.Invalid, "-unique", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-command", null), new Option(null, OptionFlags.MustHaveValue, Index.Invalid, Index.Invalid, "-index", null) // NOTE: Of sub-lists, not list. }); int argumentIndex = Index.Invalid; code = interpreter.GetOptions(options, arguments, 0, 1, Index.Invalid, false, ref argumentIndex, ref result); if (code == ReturnCode.Ok) { if ((argumentIndex != Index.Invalid) && ((argumentIndex + 1) == arguments.Count)) { StringList list = null; // // WARNING: Cannot cache list representation here, the list // is modified below. // code = Parser.SplitList( interpreter, arguments[argumentIndex], 0, Length.Invalid, false, ref list, ref result); if (code == ReturnCode.Ok) { Variant value = null; string indexText = null; if (options.IsPresent("-index", ref value)) { indexText = value.ToString(); } bool ascending = true; // FIXME: PRI 5: Default handling. if (options.IsPresent("-decreasing")) { ascending = false; } else if (options.IsPresent("-increasing")) { ascending = true; } bool noCase = false; if (options.IsPresent("-nocase")) { noCase = true; } bool unique = false; if (options.IsPresent("-unique")) { unique = true; } IntDictionary duplicates = null; IComparer <string> comparer = null; if (options.IsPresent("-command", ref value)) { StringList callbackArguments = null; if (value.IsList()) { callbackArguments = (StringList)value.Value; } else { string temporary = value.ToString(); code = Parser.SplitList( interpreter, temporary, 0, Length.Invalid, true, ref callbackArguments); } if (code == ReturnCode.Ok) { ICallback callback = CommandCallback.Create( MarshalFlags.Default, CallbackFlags.Default, ObjectFlags.Callback, ByRefArgumentFlags.None, interpreter, _Public.ClientData.Empty, null, callbackArguments, ref result); if (callback != null) { comparer = new _Comparers.StringCommandComparer( interpreter, callback, ascending, indexText, false, unique, interpreter.CultureInfo, ref duplicates); } else { code = ReturnCode.Error; } } } else if (options.IsPresent("-dictionary")) { comparer = new _Comparers.StringDictionaryComparer( interpreter, ascending, indexText, false, unique, interpreter.CultureInfo, ref duplicates); } else if (options.IsPresent("-integer")) { comparer = new _Comparers.StringIntegerComparer( interpreter, ascending, indexText, false, unique, interpreter.CultureInfo, ref duplicates); } else if (options.IsPresent("-random")) { comparer = new _Comparers.StringRandomComparer( interpreter, ascending, indexText, false, unique, interpreter.CultureInfo, interpreter.RandomNumberGenerator, ref duplicates); } else if (options.IsPresent("-real")) { comparer = new _Comparers.StringRealComparer( interpreter, ascending, indexText, false, unique, interpreter.CultureInfo, ref duplicates); } else if (options.IsPresent("-ascii") || true) // FIXME: PRI 5: Default handling. { comparer = new _Comparers.StringAsciiComparer( interpreter, ascending, indexText, false, noCase, unique, interpreter.CultureInfo, ref duplicates); } if (code == ReturnCode.Ok) { try { lock (interpreter.SyncRoot) /* TRANSACTIONAL */ { if (comparer != null) { list.Sort(comparer); } else { // // FIXME: This will never be hit because we always default // to using the StringAsciiComparer (above). // list.Sort(); // use .NET Framework defaults } } // // NOTE: If we are in unique mode, remove any duplicates from // the final resulting list now. // if (unique) { StringList uniqueList = new StringList(); // // NOTE: Process each element in the list to see if it has // been counted as a duplicate value by the comparer. // // If the value has not been added to the final resulting // list yet, add it now and mark the value so that it will // never be added again (i.e. we only want the first value // from every group of duplicates and we want all the other // values as well). // // HACK: In the worst possible case, this loop can have a runtime // of O(N^2), including called functions, primarily due to // the inability of .NET to provide proper context to // IComparer callbacks. This code could be avoided entirely // if there was an interface for sorting comparison callbacks // that provided the indexes of the elements being compared // in addition to their values. // foreach (string element in list) /* O(N) */ { // // NOTE: Has this value been marked as having been previously // added to the final resulting list? // int count = ListOps.GetDuplicateCount(comparer, duplicates, element); if (count != Count.Invalid) { // // NOTE: Add this element into the final resulting list. // Either it has no duplicates or we have not yet // added it to the final resulting list. // uniqueList.Add(element); // // NOTE: If this value had any duplicates, mark the value // as having been added to the final resulting list. // if (!ListOps.SetDuplicateCount(comparer, duplicates, element, Count.Invalid)) { result = String.Format( "failed to update duplicate count for element \"{0}\"", element); code = ReturnCode.Error; break; } } } // // NOTE: The list of unique elements is now the result. // if (code == ReturnCode.Ok) { list = uniqueList; } } if (code == ReturnCode.Ok) { result = list; } } catch (Exception e) { Engine.SetExceptionErrorCode(interpreter, e); if (e.InnerException != null) { result = e.InnerException.Message; } else if (e is ScriptException) { result = e.Message; } else { result = e; } code = ReturnCode.Error; } } } } else { if ((argumentIndex != Index.Invalid) && Option.LooksLikeOption(arguments[argumentIndex])) { result = OptionDictionary.BadOption(options, arguments[argumentIndex]); } else { result = "wrong # args: should be \"lsort ?options? list\""; } code = ReturnCode.Error; } } } else { result = "wrong # args: should be \"lsort ?options? list\""; code = ReturnCode.Error; } } else { result = "invalid argument list"; code = ReturnCode.Error; } } else { result = "invalid interpreter"; code = ReturnCode.Error; } return(code); }
/////////////////////////////////////////////////////////////////////// public static ReturnCode UploadDataAsync( Interpreter interpreter, IClientData clientData, StringList arguments, CallbackFlags callbackFlags, Uri uri, string method, byte[] rawData, ref Result error ) { TraceOps.DebugTrace(String.Format( "UploadDataAsync: interpreter = {0}, clientData = {1}, " + "arguments = {2}, callbackFlags = {3}, uri = {4}, " + "method = {5}, rawData = {6}", FormatOps.InterpreterNoThrow(interpreter), FormatOps.WrapOrNull(clientData), FormatOps.WrapOrNull(true, true, arguments), FormatOps.WrapOrNull(callbackFlags), FormatOps.WrapOrNull(uri), FormatOps.WrapOrNull(method), FormatOps.WrapOrNull(rawData)), typeof(WebOps).Name, TracePriority.NetworkDebug); ReturnCode code = ReturnCode.Ok; WebClient webClient = null; try { ICallback callback = CommandCallback.Create( MarshalFlags.Default, callbackFlags, ObjectFlags.Callback, ByRefArgumentFlags.None, interpreter, null, null, arguments, ref error); if (callback != null) { try { Result localError = null; webClient = CreateClient( interpreter, "UploadDataAsync", clientData, ref localError); if (webClient != null) { callback.ClientData = new ClientData( new AnyTriplet <WebClient, Uri, IAnyPair <string, byte[]> >( webClient, uri, new AnyPair <string, byte[]>(method, rawData))); webClient.UploadDataCompleted += new UploadDataCompletedEventHandler( UploadDataAsyncCompleted); /* NO RESULT */ webClient.UploadDataAsync( uri, method, rawData, callback); } else if (localError != null) { error = localError; code = ReturnCode.Error; } else { error = "could not create web client"; code = ReturnCode.Error; } } catch (Exception e) { error = e; code = ReturnCode.Error; } } else { code = ReturnCode.Error; } } finally { if ((code != ReturnCode.Ok) && (webClient != null)) { ReturnCode disposeCode; Result disposeError = null; disposeCode = ObjectOps.TryDispose( webClient, ref disposeError); if (disposeCode != ReturnCode.Ok) { DebugOps.Complain( interpreter, disposeCode, disposeError); } } } return(code); }