public static Hashtable MapFilter( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.select(condition)"), condition); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); object value = Eval(entry.Value, runtime); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value)); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if (!test.IsNilFalseZero) { result.Add(entry.Key, value); } } return(result); }
public static DekiScriptMap ValidateToMap(DekiScriptParameter[] parameters, DekiScriptList args) { DekiScriptMap result = new DekiScriptMap(); // check passed in arguments int i = 0; var count = Math.Min(args.Value.Count, parameters.Length); for(; i < count; ++i) { var value = args[i]; if(value.IsNil) { if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } // set default value for this parameter result.Add(parameters[i].Name, parameters[i].Default); } else { result.Add(parameters[i].Name, parameters[i].Convert(value)); } } // check that missing arguments are optional for(; i < parameters.Length; ++i) { if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } result.Add(parameters[i].Name, parameters[i].Default); } return result; }
public static DekiScriptMap ValidateToMap(DekiScriptParameter[] parameters, DekiScriptMap args) { DekiScriptMap result = new DekiScriptMap(); // check passed in arguments for (int i = 0; i < parameters.Length; ++i) { var value = args[parameters[i].Name]; if (value.IsNil) { if ((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } // set default value for this parameter result.Add(parameters[i].Name, parameters[i].Default); } else { result.Add(parameters[i].Name, parameters[i].Convert(value)); } } return(result); }
//--- Class Methods --- public static DekiScriptMap MakeErrorObject(Exception e, DekiScriptEnv env) { DekiScriptMap exception = new DekiScriptMap(); // add call stack if one is available DekiScriptList callstack = null; if(env != null) { DekiScriptLiteral callstackVar; if(env.Vars.TryGetValue(DekiScriptEnv.CALLSTACK, out callstackVar)) { callstack = callstackVar as DekiScriptList; } } while(e is DekiScriptInvokeException) { var ex = (DekiScriptInvokeException)e; if(callstack == null) { callstack = new DekiScriptList(); } callstack.AddNativeValue(ex.FunctionName); e = ex.InnerException; } if(callstack != null) { exception.Add("callstack", callstack); } // add exception text exception.Add("message", DekiScriptExpression.Constant(e.Message)); exception.Add("stacktrace", DekiScriptExpression.Constant(e.GetCoroutineStackTrace())); if(e.InnerException != null) { exception.Add("inner", MakeErrorObject(e.InnerException, null)); } if(e is DekiScriptException) { exception.Add("source", DekiScriptExpression.Constant(((DekiScriptException)e).Location.Origin)); } return exception; }
//--- Methods --- public int Compare(object left, object right) { _values.Add("left", DekiScriptLiteral.FromNativeValue(left)); _values.Add("right", DekiScriptLiteral.FromNativeValue(right)); _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values); DekiScriptLiteral test = _runtime.Evaluate(_compare, DekiScriptEvalMode.EvaluateSafeMode, _env); return((int)(test.AsNumber() ?? 0.0)); }
public static Hashtable MapApply( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach(DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime))); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env)); } return result; }
public static ArrayList ListIntersect( [DekiScriptParam("first list")] ArrayList first, [DekiScriptParam("second list")] ArrayList second, [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); if (condition != null) { // loop over both lists and keep items from the first list based on the outcome of the condition DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition); foreach (object left in first) { foreach (object right in second) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left)); keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if (!test.IsNilFalseZero) { result.Add(left); break; } } } } else { // using simple containment check to keep items foreach (object item in first) { if (second.Contains(item)) { result.Add(item); } } } return(result); }
//--- Class Methods --- public static DekiScriptMap MakeErrorObject(Exception e, DekiScriptEnv env) { DekiScriptMap exception = new DekiScriptMap(); // add call stack if one is available DekiScriptList callstack = null; if (env != null) { DekiScriptLiteral callstackVar; if (env.Vars.TryGetValue(DekiScriptEnv.CALLSTACK, out callstackVar)) { callstack = callstackVar as DekiScriptList; } } while (e is DekiScriptInvokeException) { var ex = (DekiScriptInvokeException)e; if (callstack == null) { callstack = new DekiScriptList(); } callstack.AddNativeValue(ex.FunctionName); e = ex.InnerException; } if (callstack != null) { exception.Add("callstack", callstack); } // add exception text exception.Add("message", DekiScriptExpression.Constant(e.Message)); exception.Add("stacktrace", DekiScriptExpression.Constant(e.GetCoroutineStackTrace())); if (e.InnerException != null) { exception.Add("inner", MakeErrorObject(e.InnerException, null)); } if (e is DekiScriptException) { exception.Add("source", DekiScriptExpression.Constant(((DekiScriptException)e).Location.Origin)); } return(exception); }
public static object ListReduce( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression, [DekiScriptParam("starting value (default: nil)", true)] object value, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression); foreach (object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap values = new DekiScriptMap(); values.Add("value", DekiScriptLiteral.FromNativeValue(value)); values.Add("item", DekiScriptLiteral.FromNativeValue(entry)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values); value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue; } return(value); }
public static Hashtable MapApply( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime))); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env)); } return(result); }
public static Hashtable MapFilter( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.select(condition)"), condition); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach(DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); object value = Eval(entry.Value, runtime); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value)); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { result.Add(entry.Key, value); } } return result; }
public DekiScriptOutputBuffer.Range Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state) { DekiScriptMap result = new DekiScriptMap(); if (expr.Generator == null) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state)); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state)); result.Add(text, value); } } } else { DekiScriptGeneratorEvaluation.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state.With(subEnv))); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state.With(subEnv))); result.Add(text, value); } } }, state); } return(state.Push(result)); }
public DekiScriptLiteral Visit(DekiScriptMapConstructor expr, DekiScriptEnv env) { DekiScriptMap result = new DekiScriptMap(); if (expr.Generator == null) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = field.Key.VisitWith(this, env); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = field.Value.VisitWith(this, env); result.Add(text, value); } } } else { DekiScriptGeneratorEvaluation.Instance.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = field.Key.VisitWith(this, subEnv); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = field.Value.VisitWith(this, subEnv); result.Add(text, value); } } }, env.NewLocalScope()); } return(result); }
private static DekiScriptLiteral ToDekiScriptRecurse(XDoc doc) { XDoc xdoc = doc.Elements; switch (xdoc.Name) { case "nil": return(DekiScriptNil.Value); case "boolean": if (xdoc.Contents.GetType().Equals(typeof(String))) { return(DekiScriptExpression.Constant((xdoc.Contents.Contains("1") || xdoc.Contents.Contains("true")) ? true : false)); } return(DekiScriptExpression.Constant(xdoc.AsBool ?? false)); case "double": return(DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0)); case "int": case "i4": return(DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0)); case "string": return(DekiScriptExpression.Constant(xdoc.AsText ?? string.Empty)); case "struct": { DekiScriptMap result = new DekiScriptMap(); foreach (XDoc value in xdoc["member"]) { result.Add(value["name"].Contents, ToDekiScriptRecurse(value["value"])); } return(result); } case "array": { DekiScriptList result = new DekiScriptList(); foreach (XDoc value in xdoc["data/value"]) { result.Add(ToDekiScriptRecurse(value)); } return(result); } default: throw new ArgumentException("this type does not exist in the XML-RPC standard"); } }
public DekiScriptExpression Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state) { // TODO (steveb): need to figure out how to optimize maps with generators if (expr.Generator != null) { return(expr); } // optimize each item in the map var fields = new DekiScriptMapConstructor.FieldConstructor[expr.Fields.Length]; bool isLiteral = true; for (int i = 0; i < expr.Fields.Length; i++) { var current = expr.Fields[i]; DekiScriptExpression key = current.Key.VisitWith(this, state); DekiScriptExpression value = current.Value.VisitWith(this, state); fields[i] = new DekiScriptMapConstructor.FieldConstructor(current.Location, key, value); isLiteral = isLiteral && (key is DekiScriptLiteral) && (value is DekiScriptLiteral); } if (!isLiteral) { return(DekiScriptExpression.Map(expr.Location, fields)); } // convert expression to a map DekiScriptMap result = new DekiScriptMap(); foreach (var field in fields) { DekiScriptLiteral key = (DekiScriptLiteral)field.Key; // check that key is a simple type string text = key.AsString(); if (text != null) { result.Add(text, (DekiScriptLiteral)field.Value); } } return(result); }
public DekiScriptLiteral GetMagicId(string id) { DekiScriptLiteral result = DekiScriptNil.Value; // check if magic IDs map already exists; if not, create one if (_magicIds == null) { _magicIds = new DekiScriptMap(); } else { result = _magicIds[id]; } // check if a magic ID was found; if not, create one if (result.IsNil) { result = DekiScriptExpression.Constant(id + "_" + StringUtil.CreateAlphaNumericKey(8)); _magicIds.Add(id, result); } return(result); }
public static void InitializeCustomDekiScriptHeaders(PageBE page) { var current = DreamContext.Current; DekiScriptMap env = current.GetState<DekiScriptMap>("pageimplicitenv-" + page.ID); // check if we already have an initialized environment if(env == null) { DekiContext deki = DekiContext.Current; DekiInstance instance = deki.Instance; env = new DekiScriptMap(); // add site fields DekiScriptMap siteFields = new DekiScriptMap(); siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName)); siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host)); siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage)); siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString())); siteFields.Add("id", DekiScriptExpression.Constant(instance.Id)); env.Add("site", siteFields); // add page fields DekiScriptMap pageFields = new DekiScriptMap(); pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName())); pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath())); pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace))); pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString())); pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title))); pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R"))); pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language)); env.Add("page", pageFields); // add user fields DekiScriptMap userFields = new DekiScriptMap(); if(deki.User != null) { UserBE user = deki.User; userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString())); userFields.Add("name", DekiScriptExpression.Constant(user.Name)); userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null)))); userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8))); userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant())); userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language)); } else { userFields.Add("id", DekiScriptExpression.Constant("0")); userFields.Add("name", DekiScriptExpression.Constant(string.Empty)); userFields.Add("uri", DekiScriptExpression.Constant(string.Empty)); userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty)); userFields.Add("anonymous", DekiScriptExpression.Constant("true")); userFields.Add("language", DekiScriptNil.Value); } env.Add("user", userFields); // store env for later current.SetState("pageimplicitenv-" + page.ID, env); } // set implicit environment DreamContext.Current.SetState(env); }
public static void InitializeCustomDekiScriptHeaders(PageBE page) { var current = DreamContext.Current; DekiScriptMap env = current.GetState <DekiScriptMap>("pageimplicitenv-" + page.ID); // check if we already have an initialized environment if (env == null) { DekiContext deki = DekiContext.Current; DekiInstance instance = deki.Instance; env = new DekiScriptMap(); // add site fields DekiScriptMap siteFields = new DekiScriptMap(); siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName)); siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host)); siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage)); siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString())); siteFields.Add("id", DekiScriptExpression.Constant(instance.Id)); env.Add("site", siteFields); // add page fields DekiScriptMap pageFields = new DekiScriptMap(); pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName())); pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath())); pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace))); pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString())); pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title))); pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R"))); pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language)); env.Add("page", pageFields); // add user fields DekiScriptMap userFields = new DekiScriptMap(); if (deki.User != null) { UserBE user = deki.User; userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString())); userFields.Add("name", DekiScriptExpression.Constant(user.Name)); userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null)))); userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8))); userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant())); userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language)); } else { userFields.Add("id", DekiScriptExpression.Constant("0")); userFields.Add("name", DekiScriptExpression.Constant(string.Empty)); userFields.Add("uri", DekiScriptExpression.Constant(string.Empty)); userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty)); userFields.Add("anonymous", DekiScriptExpression.Constant("true")); userFields.Add("language", DekiScriptNil.Value); } env.Add("user", userFields); // store env for later current.SetState("pageimplicitenv-" + page.ID, env); } // set implicit environment DreamContext.Current.SetState(env); }
public static ArrayList ListIntersect( [DekiScriptParam("first list")] ArrayList first, [DekiScriptParam("second list")] ArrayList second, [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); if(condition != null) { // loop over both lists and keep items from the first list based on the outcome of the condition DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition); foreach(object left in first) { foreach(object right in second) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left)); keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { result.Add(left); break; } } } } else { // using simple containment check to keep items foreach(object item in first) { if(second.Contains(item)) { result.Add(item); } } } return result; }
public static object ListReduce( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression, [DekiScriptParam("starting value (default: nil)", true)] object value, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression); foreach(object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap values = new DekiScriptMap(); values.Add("value", DekiScriptLiteral.FromNativeValue(value)); values.Add("item", DekiScriptLiteral.FromNativeValue(entry)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values); value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue; } return value; }
public static DekiScriptLiteral FromXml(XDoc doc) { // check if response is an HTML document if(doc.HasName("html")) { // TODO (steveb): this handling seems to be to specific to belong here. return new DekiScriptList().Add(new DekiScriptXml(doc)); } // check if response is a DekiScript XML document if(!doc.HasName("value") || (doc["@type"].AsText == null)) { throw new ArgumentException("doc"); } switch(doc["@type"].AsText) { case "nil": return DekiScriptNil.Value; case "bool": return Constant(doc.AsBool ?? false); case "num": return Constant(doc.AsDouble ?? 0.0); case "str": return Constant(doc.AsText ?? string.Empty); case "uri": { return Constant(doc.AsUri); } case "map": { DekiScriptMap result = new DekiScriptMap(); foreach(XDoc value in doc["value"]) { result.Add(value["@key"].AsText, FromXml(value)); } return result; } case "list": { DekiScriptList result = new DekiScriptList(); foreach(XDoc value in doc["value"]) { result.Add(FromXml(value)); } return result; } case "xml": if((doc.AsXmlNode.ChildNodes.Count == 1) && (doc.AsXmlNode.ChildNodes[0].NodeType == XmlNodeType.Element)) { return new DekiScriptXml(doc[doc.AsXmlNode.ChildNodes[0]]); } return DekiScriptNil.Value; default: throw new ArgumentException("doc"); } }
private static DekiScriptLiteral ToDekiScriptRecurse(XDoc doc) { XDoc xdoc = doc.Elements; switch(xdoc.Name) { case "nil": return DekiScriptNil.Value; case "boolean": if(xdoc.Contents.GetType().Equals(typeof(String))) { return DekiScriptExpression.Constant((xdoc.Contents.Contains("1") || xdoc.Contents.Contains("true")) ? true : false); } return DekiScriptExpression.Constant(xdoc.AsBool ?? false); case "double": return DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0); case "int": case "i4": return DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0); case "string": return DekiScriptExpression.Constant(xdoc.AsText ?? string.Empty); case "struct": { DekiScriptMap result = new DekiScriptMap(); foreach(XDoc value in xdoc["member"]) { result.Add(value["name"].Contents, ToDekiScriptRecurse(value["value"])); } return result; } case "array": { DekiScriptList result = new DekiScriptList(); foreach(XDoc value in xdoc["data/value"]) { result.Add(ToDekiScriptRecurse(value)); } return result; } default: throw new ArgumentException("this type does not exist in the XML-RPC standard"); } }
//--- Methods --- private DekiScriptEnv ProcessEnvironment() { var current = DreamContext.Current; DekiScriptEnv env = current.GetState<DekiScriptEnv>("pageenv-" + _basePage.ID); // check if we already have an initialized environment if(env == null) { // create environment env = ExtensionBL.CreateEnvironment(_basePage); // add request arguments DekiScriptMap request = new DekiScriptMap(); DekiScriptMap queryArgs = new DekiScriptMap(); DreamContext context = DreamContext.CurrentOrNull; if(context != null) { if(context.Uri.Params != null) { foreach(KeyValuePair<string, string> query in context.Uri.Params) { // check that query parameter doesn't have 'dream.' prefix if(!query.Key.StartsWithInvariantIgnoreCase("dream.")) { DekiScriptLiteral value; // check if a query parameter with the same name was alreayd found if(queryArgs.TryGetValue(query.Key, out value)) { DekiScriptList list = value as DekiScriptList; // check if the current value is already a list if(list == null) { list = new DekiScriptList(); list.Add(value); // replace current value queryArgs.Add(query.Key, list); } // append new value to list list.Add(DekiScriptExpression.Constant(query.Value)); } else { // add query parameter queryArgs.Add(query.Key, DekiScriptExpression.Constant(query.Value)); } } } } // show User-Agent, Referer and Host information in __request request.Add("referer", DekiScriptExpression.Constant(context.Request.Headers.Referer)); request.Add("useragent", DekiScriptExpression.Constant(context.Request.Headers.UserAgent)); request.Add("host", DekiScriptExpression.Constant(context.Request.Headers.Host)); // determine the client IP address var clientIPs = current.Request.Headers.DreamClientIP; if(clientIPs.Length > 0) { request.Add("client", DekiScriptExpression.Constant(clientIPs[clientIPs.Length - 1])); } else { request.Add("client", DekiScriptNil.Value); } // parse form fields from a request for requests with a mimetype of application/x-www-form-urlencoded DekiScriptMap postParams; if(context.Request.ContentType.Match(MimeType.FORM_URLENCODED)) { KeyValuePair<string, string>[] formFields = XUri.ParseParamsAsPairs(context.Request.ToText()); if(!ArrayUtil.IsNullOrEmpty(formFields)) { postParams = new DekiScriptMap(); foreach(KeyValuePair<string, string> kvp in formFields) { postParams.Add(kvp.Key, DekiScriptExpression.Constant(kvp.Value)); } request.Add("fields", postParams); } } } request.Add("args", queryArgs); env.Vars.Add("__request", request); // store computed environment for subsequent calls current.SetState("pageenv-" + _basePage.ID, env); } env = env.NewScope(); // global processing variables env.Vars.Add("__include", DekiScriptExpression.Constant(_isInclude)); env.Vars.Add("__mode", DekiScriptExpression.Constant(_mode.ToString().ToLowerInvariant())); env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(ExtensionRuntime.IsSafeMode(_page))); env.Vars.Add("__page", DekiContext.Current.Deki.PropertyAt("$page", _page.ID, true)); // set processing settings DekiScriptMap settings = new DekiScriptMap(); settings.Add("nofollow", DekiScriptExpression.Constant(DekiContext.Current.Instance.WebLinkNoFollow)); env.Vars.Add(DekiScriptEnv.SETTINGS, settings); // add callstack (specific for each page invocation) DekiScriptList callstack = new DekiScriptList(); ParserState parseState = GetParseState(); if(parseState != null) { foreach(PageBE includingPage in parseState.ProcessingStack) { callstack.Add(DekiScriptExpression.Constant(includingPage.Title.AsPrefixedDbPath())); } env.Vars.Add(DekiScriptEnv.CALLSTACK, callstack); } // add arguments environment vars env.Vars.Add("args", _args ?? DekiScriptNil.Value); env.Vars.Add("$", _args ?? DekiScriptNil.Value); return env.NewScope(); }