private PhpCallback/*!*/ GetOrCreateFilterCallback(ScriptContext/*!*/ context) { if (filterCallback == null) filterCallback = new PhpCallback(new RoutineDelegate(Filter), context); return filterCallback; }
/// <summary> /// Invoke the specified method and args. /// </summary> /// <param name="method">Method.</param> /// <param name="args">Arguments.</param> /// <param name="func">Func.</param> public override object Invoke(string func, params object[] args) { try { if (State == PluginState.Loaded && Globals.Contains(func)) { object result = (object)null; using (new Stopper(Name, func)) { var caller = new PhpCallback(Class, func); result = caller.Invoke(args); } return result; } else { Logger.LogWarning("[Plugin] Function: " + func + " not found in plugin: " + Name + ", or plugin is not loaded."); return null; } } catch (Exception ex) { string fileinfo = (String.Format("{0}<{1}>.{2}()", Name, Type, func) + Environment.NewLine); Logger.LogError(fileinfo + FormatException(ex)); return null; } }
static void Main(string[] args) { ScriptContext context = ScriptContext.InitApplication(ApplicationContext.Default, null, null, null); var sb = new StringBuilder(); using (TextWriter tw = new StringWriter(sb)) { context.Output = tw; context.OutputStream = Console.OpenStandardOutput(); //TODO: Should also redirect binary output. context.Include("main.php", true); var klass = (PhpObject)context.NewObject("Klass", new object[] { "yipppy" }); var foo = new PhpCallback(klass, "foo"); foo.Invoke(null, new object[] { "param" }); tw.Close(); } string output = sb.ToString(); const string EXPECTED = "yipppyparam"; if (output != EXPECTED) { Console.WriteLine("FAIL"); Console.Write("Expected: " + EXPECTED); Console.Write("Got: "); Console.WriteLine(output); } else { Console.WriteLine("PASS"); } }
public static object CallUserFunction(DTypeDesc caller, PhpCallback function, params object[] args) { if (function == null) { PhpException.ArgumentNull("function"); return null; } if (function.IsInvalid) return null; // invoke the callback: return PhpVariable.Dereference(function.Invoke(caller, args)); }
internal static void InvokeHeaderFunction(this HttpWebResponse response, PhpCurlResource curlResource, PhpCallback headerFunction) { StringBuilder builder = new StringBuilder(HTTP_HEADER_ROW_LENGTH); int startIndex = 0; IterateHtppHeaders(response, ref builder, delegate(ref StringBuilder sb) { headerFunction.Invoke(curlResource, sb.ToString(startIndex, sb.Length - startIndex)); startIndex = sb.Length; } ); }
public static bool CreateClrThread(ScriptContext/*!*/context, PhpCallback/*!*/ callback, params object[] args) { if (callback == null) PhpException.ArgumentNull("callback"); if (!callback.Bind()) return false; object[] copies = (args != null) ? new object[args.Length] : ArrayUtils.EmptyObjects; for (int i = 0; i < copies.Length; i++) copies[i] = PhpVariable.DeepCopy(args[i]); return ThreadPool.QueueUserWorkItem(new Worker(context, copies).Run, callback); }
public static object CallUserFunctionArray(DTypeDesc caller, PhpCallback function, PhpArray args) { object[] args_array; if (args != null) { args_array = new object[args.Count]; args.CopyValuesTo(args_array, 0); } else { args_array = ArrayUtils.EmptyObjects; } return CallUserFunction(caller, function, args_array); }
public void BindOrBiteMyLegsOff(DTypeDesc caller, NamingContext namingContext) { if (Callback != null) { if (Callback.TargetInstance == null && Parser._handlerObject != null) _currentCallback = new PhpCallback(Parser._handlerObject, Callback.RoutineName); else _currentCallback = Callback; Bound = _currentCallback.Bind(true, caller, namingContext); } else { Bound = false; } }
public string Highlight(string code, string language) { ScriptContext context = ScriptContext.CurrentContext; // redirect PHP output to the console: context.Output = Console.Out; // Unicode text output context.OutputStream = Console.OpenStandardOutput(); // byte stream output context.Include("geshi.php", true); var geshi = (PhpObject)context.NewObject("GeSHi", code, language); var result = new PhpCallback(geshi, "parse_code").Invoke(); var error = new PhpCallback(geshi, "error").Invoke(); new PhpCallback(geshi, "enable_keyword_links").Invoke(false); return result.ToString(); }
public static int Apply(ScriptContext/*!*/context, PHP.Core.Reflection.DTypeDesc caller, Iterator/*!*/iterator, PhpCallback function, PhpArray args) { // check parameters: Debug.Assert(context != null); Debug.Assert(iterator != null, "Phalanger should not pass a null here."); if (function == null) { PhpException.ArgumentNull("function"); return -1; } // copy args into object array: object[] args_array; if (args != null) { args_array = new object[args.Count]; args.Values.CopyTo(args_array, 0); } else { args_array = ArrayUtils.EmptyObjects; } // iterate through the iterator: int n = 0; iterator.rewind(context); while (PHP.Core.Convert.ObjectToBoolean(iterator.valid(context))) { if (!PHP.Core.Convert.ObjectToBoolean(function.Invoke(caller, args_array))) break; n++; iterator.next(context); } // return amount of iterated elements: return n; }
public static void LoadFile(string path, PhpCallback function) { string file = string.Empty; if (function == null) { PhpException.ArgumentNull("function"); return; } if (function.IsInvalid) return; WebClient webclient = new WebClient(); webclient.DownloadStringCompleted += new DownloadStringCompletedEventHandler( delegate(object sender, DownloadStringCompletedEventArgs downEventArgs) { var canvas = ((ClrObject)ScriptContext.CurrentContext.AutoGlobals.Canvas.Value).RealObject as System.Windows.Controls.Canvas; canvas.Dispatcher.BeginInvoke(() => { function.Invoke(downEventArgs.Result); }); } ); var source_root = ((ClrObject)ScriptContext.CurrentContext.AutoGlobals.Addr.Value).RealObject as string; Uri baseUri = new Uri(source_root + "/", UriKind.Absolute); Uri uriFile = new Uri(path, UriKind.RelativeOrAbsolute); Uri uri = new Uri(baseUri, uriFile); webclient.DownloadStringAsync(uri); //downloadFinished.WaitOne(); //return XamlReader.Load(file); }
/// <summary> /// Visits an entyr of array which <see cref="Walk"/> or <see cref="WalkRecursive"/> is walking through. /// </summary> private static void VisitEntryOnWalk(PHP.Core.Reflection.DTypeDesc caller, KeyValuePair<IntStringKey, object> entry, IDictionary<IntStringKey, object> array, PhpCallback callback, object[] args) { PhpReference ref_item = entry.Value as PhpReference; // fills arguments for the callback: ((PhpReference)args[0]).Value = (ref_item != null) ? ref_item.Value : entry.Value; args[1] = entry.Key.Object; // invoke callback: Core.Convert.ObjectToBoolean(callback.Invoke(caller, args)); // loads a new value from a reference: if (ref_item != null) { ref_item.Value = ((PhpReference)args[0]).Value; } else { array[entry.Key] = ((PhpReference)args[0]).Value; } }
public static PhpArray Filter(PHP.Core.Reflection.DTypeDesc caller, PhpArray array, PhpCallback callback) { if (callback == null) { PhpException.ArgumentNull("callback"); return null; } if (array == null) { PhpException.ArgumentNull("array"); return null; } PhpArray result = new PhpArray(); object[] args = new object[1]; foreach (KeyValuePair<IntStringKey, object> entry in array) { // no deep copying needed because it is done so in callback: args[0] = entry.Value; // adds entry to the resulting array if callback returns true: if (Core.Convert.ObjectToBoolean(callback.Invoke(caller, args))) { result.Add(entry.Key, entry.Value); } } // values should be inplace deeply copied: result.InplaceCopyOnReturn = true; return result; }
public static bool WalkRecursive(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpHashtable array, PhpCallback callback, object data) { object[] args = PrepareWalk(array, callback, data); if (args == null) return false; using (PhpHashtable.RecursiveEnumerator iterator = array.GetRecursiveEnumerator(true,false)) { while (iterator.MoveNext()) { // visits the item unless it is an array or a reference to an array: PhpReference ref_value = iterator.Current.Value as PhpReference; if (!(iterator.Current.Value is PhpHashtable || (ref_value != null && ref_value.Value is PhpHashtable))) VisitEntryOnWalk(caller, iterator.Current, iterator.CurrentTable, callback, args); } } return true; }
/// <summary> /// Prepares a walk for <see cref="Walk"/> and <see cref="WalkRecursive"/> methods. /// </summary> /// <exception cref="PhpException"><paramref name="callback"/> or <paramref name="array"/> are <B>null</B> references.</exception> private static object[] PrepareWalk(IDictionary array, PhpCallback callback, object data) { if (callback == null) { PhpException.ArgumentNull("callback"); return null; } if (array == null) { PhpException.ArgumentNull("array"); return null; } // prepares an array of callback's arguments (no deep copying needed because it is done so in callback): if (data != null) return new object[3] { new PhpReference(), null, data }; else return new object[2] { new PhpReference(), null }; }
public static object Replace(ScriptContext/*!*/context, object pattern, PhpCallback callback, object data, int limit, out int count) { count = 0; return Replace(context, null, null, pattern, null, callback, data, limit, ref count); }
public static bool WalkRecursive(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpHashtable array, PhpCallback callback) { return WalkRecursive(caller, array, callback, null); }
public static void RegisterTickFunction(PhpCallback function, object arg) { PhpException.FunctionNotSupported(); }
/// <summary> /// Private mehtod implementing all replace methods. Just one of <paramref name="replacement"/> or <paramref name="callback" /> should be used. /// </summary> /// <param name="context">Current <see cref="ScriptContext"/>. Must not be null.</param> /// <param name="self">Instance of object that called the replace method (replace pattern may contain $this)</param> /// <param name="definedVariables"></param> /// <param name="pattern"></param> /// <param name="replacement"></param> /// <param name="callback"></param> /// <param name="data"></param> /// <param name="limit"></param> /// <param name="count"></param> /// <returns>String or an array.</returns> private static object Replace(ScriptContext/*!*/context, DObject self, Dictionary<string, object> definedVariables, object pattern, object replacement, PhpCallback callback, object data, int limit, ref int count) { // if we have no replacement and no callback, matches are deleted (replaced by an empty string) if (replacement == null && callback == null) replacement = String.Empty; // exactly one of replacement or callback is valid now Debug.Assert(replacement != null ^ callback != null); // get eval info if it has been captured - is needed even if we do not need them later SourceCodeDescriptor descriptor = context.GetCapturedSourceCodeDescriptor(); // PHP's behaviour for undocumented limit range if (limit < -1) limit = 0; PhpArray replacement_array = replacement as PhpArray; string replacement_string = null; if (replacement_array == null && replacement != null) replacement_string = Core.Convert.ObjectToString(replacement); // we should return new array, if there is an array passed as subject, it should remain unchanged: object data_copy = PhpVariable.DeepCopy(data); PhpArray pattern_array = pattern as PhpArray; if (pattern_array == null) { // string pattern // string replacement if (replacement_array != null) { // string pattern and array replacement not allowed: PhpException.InvalidArgument("replacement", LibResources.GetString("replacement_array_pattern_not")); return null; } // pattern should be treated as string and therefore replacement too: return SimpleReplace(self, definedVariables, pattern, replacement_string, callback, data_copy, limit, descriptor, ref count); } else if (replacement_array == null) { // array pattern // string replacement using (var pattern_enumerator = pattern_array.GetFastEnumerator()) while (pattern_enumerator.MoveNext()) { data_copy = SimpleReplace(self, definedVariables, pattern_enumerator.CurrentValue, replacement_string, callback, data_copy, limit, descriptor, ref count); } } else //if (replacement_array != null) { // array pattern // array replacement var replacement_enumerator = replacement_array.GetFastEnumerator(); bool replacement_valid = true; using (var pattern_enumerator = pattern_array.GetFastEnumerator()) while (pattern_enumerator.MoveNext()) { // replacements are in array, move to next item and take it if possible, in other case take empty string: if (replacement_valid && replacement_enumerator.MoveNext()) { replacement_string = Core.Convert.ObjectToString(replacement_enumerator.CurrentValue); } else { replacement_string = string.Empty; replacement_valid = false; // end of replacement_enumerator, do not call MoveNext again! } data_copy = SimpleReplace(self, definedVariables, pattern_enumerator.CurrentValue, replacement_string, callback, data_copy, limit, descriptor, ref count); } } // return resulting array or string assigned to data return data_copy; }
public static PhpArray Map(PHP.Core.Reflection.DTypeDesc caller, PhpCallback map, [PhpRw] params PhpArray[] arrays) { if (!PhpArgument.CheckCallback(map, caller, "map", 0, true)) return null; if (arrays == null || arrays.Length == 0) { PhpException.InvalidArgument("arrays", LibResources.GetString("arg:null_or_emtpy")); return null; } // if callback has not been specified uses the default one: if (map == null) map = new PhpCallback(new RoutineDelegate(MapIdentity), ScriptContext.CurrentContext); int count = arrays.Length; bool preserve_keys = count == 1; PhpReference[] args = new PhpReference[count]; IEnumerator<KeyValuePair<IntStringKey, object>>[] iterators = new IEnumerator<KeyValuePair<IntStringKey, object>>[count]; PhpArray result; // initializes iterators and args array, computes length of the longest array: int max_count = 0; for (int i = 0; i < arrays.Length; i++) { var array = arrays[i]; if (array == null) { PhpException.Throw(PhpError.Warning, LibResources.GetString("argument_not_array", i + 2));// +2 (first arg is callback) return null; } args[i] = new PhpReference(); iterators[i] = array.GetEnumerator(); if (array.Count > max_count) max_count = array.Count; } // keys are preserved in a case of a single array and re-indexed otherwise: if (preserve_keys) result = new PhpArray(arrays[0].IntegerCount, arrays[0].StringCount); else result = new PhpArray(max_count, 0); for (; ; ) { // fills args[] with items from arrays: for (int i = 0; i < arrays.Length; i++) { if (iterators[i] != null) { // an element is available: if (iterators[i].MoveNext()) { // note: deep copy is not necessary since a function copies its arguments if needed: object value = iterators[i].Current.Value; PhpReference valueref = (value != null) ? value as PhpReference : null; args[i].Value = (valueref != null) ? valueref.value : value; //args[i].Value = iterators[i].Current.Value; // TODO: throws if the current Value is PhpReference } else { // the i-th iterator has stopped: count--; iterators[i] = null; args[i].Value = null; } } } if (count == 0) break; // invokes callback: object return_value = map.Invoke(args); // return value is not deeply copied: if (preserve_keys) result.Add(iterators[0].Current.Key, return_value); else result.Add(return_value); // loads new values (callback may modify some by ref arguments): for (int i = 0; i < arrays.Length; i++) { if (iterators[i] != null) { object item = iterators[i].Current.Value; PhpReference ref_item = item as PhpReference; if (ref_item != null) { ref_item.Value = args[i].Value; } else { arrays[i][iterators[i].Current.Key] = args[i].Value; } } } } return result; }
/// <summary> /// There have to be at least 1 value in <paramref name="vars"/>. /// The last is converted to callback, the rest to arrays. /// </summary> private static bool SplitArraysAndComparers(int comparerCount, PhpArray array, object[] vars, out PhpArray[] arrays, out PhpCallback cmp1, out PhpCallback cmp2) { arrays = null; cmp1 = cmp2 = null; if (vars == null || vars.Length == 0) { PhpException.InvalidArgumentCount(null, null); return false; } // the first callback: cmp1 = Core.Convert.ObjectToCallback(vars[vars.Length - comparerCount]); if (!PhpArgument.CheckCallback(cmp1, PHP.Core.Reflection.UnknownTypeDesc.Singleton/*(J): TBD pass caller from library func when this will be performance issue*/, null, vars.Length - comparerCount + 3, false)) return false; // the second callback: if (comparerCount > 1) { cmp2 = Core.Convert.ObjectToCallback(vars[vars.Length - 1]); if (!PhpArgument.CheckCallback(cmp2, PHP.Core.Reflection.UnknownTypeDesc.Singleton/*(J): TBD pass caller from library func when this will be performance issue*/, null, vars.Length - comparerCount + 3, false)) return false; } // remaining arguments should be arrays: arrays = new PhpArray[vars.Length - comparerCount + 1]; arrays[0] = array; for (int i = 0; i < vars.Length - comparerCount; i++) { arrays[i + 1] = vars[i] as PhpArray; if (arrays[i + 1] == null) { PhpException.Throw(PhpError.Warning, LibResources.GetString("argument_not_array", i + 3)); return false; } } return true; }
public static bool UserKeySort(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpArray array, PhpCallback compare) { if (array == null) { PhpException.ReferenceNull("array"); return false; } if (!PhpArgument.CheckCallback(compare, caller, "compare", 0, false)) return false; array.Sort(new KeyComparer(new PhpUserComparer(compare), false)); return true; }
public static bool UserAssocSort(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpArray array, PhpCallback compare) { if (array == null) { PhpException.ReferenceNull("array"); return false; } if (!PhpArgument.CheckCallback(compare, caller, "compare", 0, false)) return false; // sorts array using callback for comparisons: array.Sort(new ValueComparer(new PhpUserComparer(compare), false)); return true; }
/// <summary> /// Takes a regular expression <paramref name="pattern"/> and one of <paramref name="replacement"/> or /// <paramref name="callback"/>. Performs replacing on <paramref name="data"/>, which can be /// <see cref="PhpArray"/>, in other cases it is converted to string. /// If <paramref name="data"/> is <see cref="PhpArray"/>, every value is converted to string and /// replacement is performed in place in this array. /// Either <paramref name="replacement"/> or <paramref name="callback"/> should be null. /// </summary> /// <param name="self">Instance of object that called the replace method (replace pattern may contain $this)</param> /// <param name="definedVariables">Array with local variables - can be used by replace pattern</param> /// <param name="pattern">Regular expression to search.</param> /// <param name="replacement">Regular replacement expression. Should be null if callback is specified.</param> /// <param name="callback">Callback function that should be called to make replacements. Should be null /// if replacement is specified.</param> /// <param name="data">Array or string where pattern is searched.</param> /// <param name="limit">Max count of replacements for each item in subject.</param> /// <param name="descriptor"><see cref="SourceCodeDescriptor"/> for possible lambda function creation.</param> /// <param name="count">Cumulated number of replacements.</param> /// <returns></returns> private static object SimpleReplace(DObject self, Dictionary<string, object> definedVariables, object pattern, string replacement, PhpCallback callback, object data, int limit, SourceCodeDescriptor descriptor, ref int count) { Debug.Assert(limit >= -1); // exactly one of replacement or callback is valid: Debug.Assert(replacement != null ^ callback != null); PerlRegExpConverter converter = ConvertPattern(pattern, replacement); if (converter == null) return null; // get types of data we need: PhpArray data_array = data as PhpArray; string data_string = (data_array == null) ? ConvertData(data, converter) : null; // data comprising of a single string: if (data_array == null) { return ReplaceInternal(self, definedVariables, converter, callback, data_string, limit, descriptor, ref count); } else { // data is array, process each item: var enumerator = data_array.GetFastEnumerator(); while (enumerator.MoveNext()) { enumerator.CurrentValue = ReplaceInternal(self, definedVariables, converter, callback, ConvertData(enumerator.CurrentValue, converter), limit, descriptor, ref count); } enumerator.Dispose(); // return array with items replaced: return data; } }
public static void RegisterShutdownFunction(PhpCallback/*!*/ function, params object[] parameters) { if (function == null) { PhpException.ArgumentNull("function"); return; } ScriptContext.CurrentContext.RegisterShutdownCallback(function, parameters); }
public static object Reduce(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpArray array, PhpCallback function, [PhpDeepCopy] object initialValue) { if (array == null) { PhpException.ReferenceNull("array"); return null; } if (!PhpArgument.CheckCallback(function, caller, "function", 0, false)) return null; if (array.Count == 0) return initialValue; object[] args = new object[] { initialValue, null }; PhpReference holder = new PhpReference(); foreach (KeyValuePair<IntStringKey, object> entry in array) { object item = entry.Value; PhpReference ref_item = item as PhpReference; // array item is a reference: if (ref_item != null) { args[1] = item; args[0] = function.Invoke(args); } else { // array item is not a reference: holder.Value = item; args[1] = holder; args[0] = function.Invoke(args); // updates an item if it has been changed: if (item != holder.Value) array[entry.Key] = holder.Value; } } // dereferences the last returned value: return PhpVariable.Dereference(args[0]); }
public static void UnregisterTickFunction(PhpCallback function) { PhpException.FunctionNotSupported(); }
public static bool Walk(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpHashtable array, PhpCallback function) { return Walk(caller, array, function, null); }
public static object Reduce(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpArray array, PhpCallback function) { return Reduce(caller, array, function, null); }
public static bool Walk(PHP.Core.Reflection.DTypeDesc caller, [PhpRw] PhpHashtable array, PhpCallback callback, object data) { object[] args = PrepareWalk(array, callback, data); if (args == null) return false; foreach (KeyValuePair<IntStringKey, object> entry in array) { VisitEntryOnWalk(caller, entry, array, callback, args); } return true; }