public static void p5_string_index_of(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Figuring out source value for [index-of], and returning early if there is no source. string source = XUtil.Single <string> (context, e.Args); if (source == null) { return; } // Retrieving what to look for, and returning early if we have no source. var src = XUtil.Source(context, e.Args); if (src == null) { return; } // Checking what type of value we're looking for, and acting accordingly. if (src is Regex) { // Regex type of find. e.Args.AddRange(IndexOfRegex(source, src as Regex).Select(ix => new Node("", ix))); } else { // Simple string type of find. e.Args.AddRange(IndexOfString(source, Utilities.Convert <string> (context, src)).Select(ix => new Node("", ix))); } } }
public void p5_web_return_response_object(ApplicationContext context, ActiveEventArgs e) { var key = XUtil.Single <string> (context, e.Args); var source = XUtil.Source(context, e.Args); AjaxPage.SendObject(key, Utilities.Convert <string> (context, source)); }
public static void p5_string_trim(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args)) { // Getting trim characters, defaulting to whitespace characters. var characters = e.Args.GetExChildValue("chars", context, " \r\n\t"); // Returning length of constant or expression, converted to string if necessary. var source = XUtil.Single <string> (context, e.Args); switch (e.Name) { case "trim": case "p5.string.trim": e.Args.Value = source.Trim(characters.ToArray()); break; case "trim-left": case "p5.string.trim-left": e.Args.Value = source.TrimStart(characters.ToArray()); break; case "trim-right": case "p5.string.trim-right": e.Args.Value = source.TrimEnd(characters.ToArray()); break; } } }
public static void p5_web_echo(ApplicationContext context, ActiveEventArgs e) { // Discarding current response, and removing session cookie, unless caller explicitly said he wanted to keep it HttpContext.Current.Response.Filter = null; HttpContext.Current.Response.ClearContent(); // Rendering content back on wire var val = e.Args.Value as byte []; if (val != null) { // Content is binary type of content HttpContext.Current.Response.BinaryWrite(val); } else { // Content is string, integer, etc type of content HttpContext.Current.Response.Write(XUtil.Single <string> (context, e.Args)); } // Flushing response, and making sure default content is never rendered HttpContext.Current.Response.OutputStream.Flush(); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.SuppressContent = true; }
public static void p5_web_echo_file(ApplicationContext context, ActiveEventArgs e) { // Discarding current response, and removing session cookie, unless caller explicitly said he wanted to keep it HttpContext.Current.Response.Filter = null; HttpContext.Current.Response.ClearContent(); // Retrieving root node of web application var rootFolder = context.RaiseEvent(".p5.core.application-folder").Get <string> (context); // Finding filename var fileName = context.RaiseEvent(".p5.io.unroll-path", new Node("", XUtil.Single <string> (context, e.Args))).Get <string> (context); // Verifying user is authorized to reading from currently iterated file context.RaiseEvent(".p5.io.authorize.read-file", new Node("", fileName).Add("args", e.Args)); // Rendering file back to client using (Stream fileStream = File.OpenRead(rootFolder + fileName)) { fileStream.CopyTo(HttpContext.Current.Response.OutputStream); } // Flushing response, and making sure default content is never rendered HttpContext.Current.Response.OutputStream.Flush(); HttpContext.Current.Response.Flush(); HttpContext.Current.Response.SuppressContent = true; }
/* * Will evaluate the given condition to true, if it is anything but a false boolean, null, * or an expression returning anything but null or false */ void TryEvaluateSimpleExist() { // If value is not boolean type, we evaluate value, and set its value to true, if evaluation did not result in "null" or "false". if (_args.Value == null) { // Null evaluates to false. _args.Value = false; } else { // Checking if value already is boolean, at which case we don't evaluate any further, since it is already evaluated. if (!(_args.Value is bool)) { var obj = XUtil.Single <object> (_context, _args); if (obj == null) { // Result of evaluated expression yields null, hence evaluation result is false. _args.Value = false; } else if (obj is bool) { // Result of evaluated expression yields boolean, using this boolean as result. _args.Value = obj; } else { // Anything but null and boolean, existence is true, hence evaluation becomes true _args.Value = true; } } } }
/* * Saves response into filename given */ static void RenderFileResponse( ApplicationContext context, HttpWebRequest request, Node args) { // Getting filename user wants to save response as var filename = context.RaiseEvent(".p5.io.unroll-path", new Node("", XUtil.Single <string> (context, args ["filename"]))).Get <string>(context); // Making sure user is authorized to write/overwrite the file response should be saved to context.RaiseEvent(".p5.io.authorize.modify-file", new Node("", filename).Add("args", args)); // Retrieving HTTP response var response = request.GetResponseNoException(); Node result = args.Add("result").LastChild; // Getting HTTP response headers GetResponseHeaders(context, response, result, request); // Retrieving response content stream, and parsing as expected by caller using (Stream stream = response.GetResponseStream()) { // Retrieving root folder of web application var rootFolder = context.RaiseEvent(".p5.core.application-folder").Get <string> (context); // Copying response content stream to file stream encapsualting file caller requested to save content to using (Stream fileStream = File.Create(rootFolder + filename)) { // Copy response stream to file stream stream.CopyTo(fileStream); } } }
public static void p5_crypto_hash_create_sha1(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args)) { // Retrieving value to hash as a single string. var whatToHash = XUtil.Single <byte []> (context, e.Args); // Creating Sha256 hash, and returning as value of args. using (var sha1 = SHA1.Create()) { // Checking if caller wants "raw bytes". if (e.Args.GetExChildValue("raw", context, false)) { // Returning Sha256 hash as raw bytes. e.Args.Value = sha1.ComputeHash(whatToHash); } else if (e.Args.GetExChildValue("hex", context, false)) { // Returning value as hexadecimal string. e.Args.Value = BitConverter.ToString(sha1.ComputeHash(whatToHash)).Replace("-", string.Empty); } else { // Returning Sha256 hash as base64 encoded string. e.Args.Value = Convert.ToBase64String(sha1.ComputeHash(whatToHash)); } } } }
/* * Processing a single data item, which might be a single data value, constant, null, or a sub-template. */ static IEnumerable <Node> ProcessDataItem(ApplicationContext context, Node template, Node source) { // Retrieving node's name var name = template.Name.Substring(1, template.Name.Length - 2); // Checking type of template. if (template.Value is Expression) { // Expression type, checking if this is a single value template definition, or a sub-template definition. var match = template.Get <Expression> (context).Evaluate(context, source, template); if (match.TypeOfMatch == Match.MatchType.node) { // Sanity check, before applying sub-template, ignoring children, since they're arguments to sub-template, and not current template. if (name != "template") { throw new LambdaException("A node expression can only be supplied to a sub [{template}] definition", template, context); } // Processing sub-template, returning one node for each item braided with source. foreach (var idxResult in ProcessSubTemplate(context, template, source)) { yield return(idxResult); } // Preventing execution of default logic below. yield break; } // Notice the fallthrough to final yield return in method, instead of else logic. } // Databound simple value, making sure we process children. yield return(new Node(name, XUtil.Single <object> (context, template, source), ProcessItemChildren(context, template, source))); }
public static void p5_string_match(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Figuring out source value for [match], and returning early if there is no source. string source = XUtil.Single <string> (context, e.Args); if (source == null) { return; } // Retrieving what source to look for, and returning early if there is none. var src = XUtil.Source(context, e.Args); if (src == null) { return; } var srcRegex = Utilities.Convert <Regex> (context, src); // Evaluating regular expression, and returning results. foreach (System.Text.RegularExpressions.Match idxMatch in srcRegex.Matches(source)) { // Returning all groups matches. foreach (Group idxGroup in idxMatch.Groups) { e.Args.Add(idxGroup.Value); } } } }
/* * Decorating all HTTP headers for request. */ static void SetRequestHeaders(ApplicationContext context, HttpWebRequest request, Node args) { /* * Redmond/MSFT, this is ridiculous! Why can't we set headers in a uniform way ...? */ foreach (var idxHeader in args.Children.Where( idxArg => idxArg.Name != "" && idxArg.Name != ".onrequest" && idxArg.Name != ".onresponse" && idxArg.Name != "result" && idxArg.Name != "content")) { switch (idxHeader.Name) { case "Accept": request.Accept = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "Connection": request.Connection = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "Content-Length": request.ContentLength = XUtil.Single <long> (context, idxHeader, idxHeader); break; case "Content-Type": request.ContentType = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "Date": request.Date = XUtil.Single <DateTime> (context, idxHeader, idxHeader); break; case "Expect": request.Expect = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "Host": request.Host = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "If-Modified-Since": request.IfModifiedSince = XUtil.Single <DateTime> (context, idxHeader, idxHeader); break; case "Referer": request.Referer = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "Transfer-Encoding": request.TransferEncoding = XUtil.Single <string> (context, idxHeader, idxHeader); break; case "User-Agent": request.UserAgent = XUtil.Single <string> (context, idxHeader, idxHeader); break; default: request.Headers.Add(idxHeader.Name, XUtil.Single <string> (context, idxHeader, idxHeader)); break; } } }
public static void p5_string_to_lower(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new Utilities.ArgsRemover(e.Args)) { // Returning to lowers of expression or constant. e.Args.Value = XUtil.Single <string> (context, e.Args).ToLowerInvariant(); } }
static void p5_string_decode_base64(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up after ourselves. using (new ArgsRemover(e.Args)) { // Decoding given value from base64 and returning to caller. e.Args.Value = Convert.FromBase64String(XUtil.Single <string> (context, e.Args)); } }
public static void p5_string_length(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new Utilities.ArgsRemover(e.Args)) { // Returning length of constant or expression, converted to string if necessary. e.Args.Value = (XUtil.Single <string> (context, e.Args) ?? "").Length; } }
public static void lambda_fetch(ApplicationContext context, ActiveEventArgs e) { // Evaluating [fetch] lambda block. context.RaiseEvent("eval-mutable", e.Args); // Now we can fetch expression value, and clear body, making sure we remove formatting parameters first. e.Args.Value = XUtil.Single <object> (context, e.Args); e.Args.Clear(); }
static void p5_string_encode_base64(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up after ourselves. using (new ArgsRemover(e.Args)) { // Encoding given value to base64 and returning results to caller. var bytes = XUtil.Single <byte []> (context, e.Args); e.Args.Value = bytes == null ? null : Convert.ToBase64String(bytes); } }
/* * Will evaluate the given condition to true, if it is anything but a false boolean, null, * or an expression returning anything but null or false */ static Node EnsureParentFindPreviousCondition(ApplicationContext context, Node args) { // Sanity check. if (args.Parent == null || args.Parent.Name == "") { throw new LambdaException( string.Format("[{0}] cannot be raised as a root node, only as a child of a conditional Active Event", args.Name), args, context); } // If value is not boolean type, we evaluate value, and set its value to true, if evaluation did not result in "null" or "false". if (args.Parent.Value == null) { // Null evaluates to false. args.Parent.Value = false; } else { // Checking if value already is boolean, at which case we don't continue, since it is already evaluated. if (!(args.Parent.Value is bool)) { var obj = XUtil.Single <object> (context, args.Parent); if (obj == null) { // Result of evaluated expression yields null, hence evaluation result is false. args.Parent.Value = false; } else if (obj is bool) { // Result of evaluated expression yields boolean, using this boolean as result. args.Parent.Value = obj; } else { // Anything but null and boolean, existence is true, hence evaluation becomes true. args.Parent.Value = true; } } } // Making sure we return previous conditional node. var retVal = args.PreviousSibling ?? args.Parent; while (retVal != null && retVal.Name == "") { retVal = retVal.PreviousSibling ?? retVal.Parent; } // Sanity check. if (retVal == null) { throw new LambdaException(string.Format("No previous condition found for [{0}]", args.Name), args, context); } return(retVal); }
/* * Helper method for above. */ static void CreateHash(ApplicationContext context, HashAlgorithm hasher, Node args) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(args)) { // Retrieving value to hash as a blob. var whatToHash = XUtil.Single <byte []> (context, args); // Returning value to caller. ReturnHash(context, args, hasher.ComputeHash(whatToHash)); } }
/* * Returns content back to caller. */ static object GetRequestContent(ApplicationContext context, Node content) { // Checking for Hyperlambda. if (content.Value == null && content.Count > 0) { // Hyperlambda content. return(context.RaiseEvent("lambda2hyper", content.Clone()).Value); } // Some sort of "value" content, either text content, or binary blob (byte[]). return(XUtil.Single <object> (context, content)); }
public void p5_web_set_location(ApplicationContext context, ActiveEventArgs e) { // Checking if this is ajax callback, which means we'll have to redirect using JavaScript if (AjaxPage.IsAjaxRequest) { // Redirecting using JavaScript AjaxPage.SendJavaScript(string.Format("window.location='{0}';", XUtil.Single <string> (context, e.Args).Replace("'", "\\'"))); } else { // Redirecting using Response object AjaxPage.Response.Redirect(XUtil.Single <string> (context, e.Args)); } }
/* * Returns content back to caller */ private static object GetRequestContent( ApplicationContext context, Node content) { if (content.Value == null && content.Children.Count > 0) { // Hyperlambda content return(context.Raise("lambda2hyper", content.UnTie()).Value); } else { // Some sort of "value" content, either text or binary (byte[]) return(XUtil.Single <object> (context, content)); } }
public static void p5_string_ends_with(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args)) { // Retrieving what to look for, and returning early if we have no source. var src = XUtil.Source(context, e.Args); if (src == null) { return; } // Returning to lowers of expression or constant. e.Args.Value = XUtil.Single <string> (context, e.Args)?.EndsWithEx(Utilities.Convert <string> (context, src)) ?? false; } }
public void p5_web_set_location(ApplicationContext context, ActiveEventArgs e) { // Checking if this is ajax callback, which means we'll have to redirect using JavaScript if (AjaxPage.IsAjaxRequest) { // Redirecting using JavaScript. AjaxPage.SendJavaScript(string.Format("window.location='{0}';", XUtil.Single <string> (context, e.Args).Replace("'", "\\'"))); } else { // Redirecting using Response object. try { AjaxPage.Response.Redirect(XUtil.Single <string> (context, e.Args)); } catch (System.Threading.ThreadAbortException) { ; // Silently catching, no reasons to allow it to penetrate ... } } }
/* * Renders HTTP post/put file request */ static void RenderFileRequest( ApplicationContext context, HttpWebRequest request, Node args, string method) { // Verifying caller supplied [file] node if (args["filename"] == null) { throw new LambdaException( "No [filename] node given", args, context); } // Getting file to post or put, verifying expression does not lead into oblivion var filename = context.RaiseEvent(".p5.io.unroll-path", new Node("", XUtil.Single <string> (context, args["filename"]))).Get <string> (context); // Making sure user is authorized to read the file request should send context.RaiseEvent(".p5.io.authorize.read-file", new Node("", filename).Add("args", args)); // Opening request stream, and render file as content of request using (Stream stream = request.GetRequestStream()) { // Setting Content-Type to "application/octet-stream", unless file ends with ".hl", or Content-Type is explicitly supplied request.ContentType = args.GetExChildValue( "Content-Type", context, filename.EndsWithEx(".hl") ? "application/x-hyperlambda" : "application/octet-stream"); // Setting other HTTP request headers SetRequestHeaders(context, request, args); // Retrieving root node of web application var rootFolder = context.RaiseEvent(".p5.core.application-folder").Get <string> (context); // Copying FileStream to RequestStream using (Stream fileStream = File.OpenRead(rootFolder + filename)) { // Sending file to server end-point fileStream.CopyTo(stream); } } }
public static void p5_mime_save_file(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up after ourselves using (new Utilities.ArgsRemover(e.Args, true)) { // Keeping base folder to application around string baseFolder = Common.GetRootFolder(context); // Retrieving filename supplied by caller to serialize MimeEntity to var filename = XUtil.Single <string> (context, e.Args, true); // Verifying user is authorized to saving to the specified file context.Raise(".p5.io.authorize.modify-file", new Node("", filename).Add("args", e.Args)); // Retrieving root MIME entity from args var mimeNode = e.Args [0]; // Making sure we keep track of, closes, and disposes all streams created during process List <Stream> streams = new List <Stream> (); try { // Creating and returning MIME message to caller as string MimeCreator creator = new MimeCreator( context, mimeNode, streams); var mimeEntity = creator.Create(); // Creating file to store MIME entity into using (var stream = File.Create(baseFolder + filename)) { // Writing MimeEntity to file stream mimeEntity.WriteTo(stream); } } finally { // Disposing all streams created during process foreach (var idxStream in streams) { // Closing and disposing currently iterated stream idxStream.Close(); idxStream.Dispose(); } } } }
public void p5_web_page_set_title(ApplicationContext context, ActiveEventArgs e) { // Retrieving the new Title of our page. var title = XUtil.Single <string> (context, e.Args); // Checking if this is ajax request, at which point we'll have to update title using JavaScript. if (IsAjaxRequest) { // Passing title to client as JavaScript update, making sure we escape string SendJavaScript(string.Format("document.title='{0}';", title.Replace("\\", "\\\\").Replace("'", "\\'"))); } else { // Updating Title element of page. Title = title; } // Storing Title in ViewState such that we can retrieve the correct title later. ViewState ["_pf_title"] = Title; }
public static void p5_string_match(ApplicationContext context, ActiveEventArgs e) { // Sanity check. if (e.Args.Value == null) { throw new LambdaException("[p5.string.match] requires an expression or constant as its value", e.Args, context); } // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Figuring out source value for [match], and returning early if there is no source. string source = XUtil.Single <string> (context, e.Args); if (source == null) { return; } // Retrieving what source to look for, and returning early if there is none. var src = XUtil.Source(context, e.Args); if (src == null) { return; } // Sanity check. if (!(src is Regex)) { throw new LambdaException("[match] requires a regular expression source", e.Args, context); } // Evaluating regular expression, and returning results. foreach (System.Text.RegularExpressions.Match idxMatch in (src as Regex).Matches(source)) { // Returning all groups matches. foreach (Group idxGroup in idxMatch.Groups) { e.Args.Add(idxGroup.Value); } } } }
public static void html2pdf(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new ArgsRemover(e.Args, true)) { // Assumes there's only one document, or creates one result of it. var filename = XUtil.Single <string> (context, e.Args); filename = context.RaiseEvent(".p5.io.unroll-path", new Node("", filename)).Get <string> (context); // Figuring out source. var html = XUtil.Source(context, e.Args, "css-file") as string; // Retrieving root path of app. var rootPath = context.RaiseEvent(".p5.core.application-folder").Get <string> (context); // Loading up all CSS, which we'll need to pass into ParseXhtml further down. var css = ""; foreach (var idxCssFile in e.Args.Children.Where(ix => ix.Name == "css-file")) { var cssFile = idxCssFile.GetExValue <string> (context); cssFile = context.RaiseEvent(".p5.io.unroll-path", new Node("", cssFile)).Get <string> (context); using (TextReader reader = File.OpenText(rootPath + cssFile)) { css += reader.ReadToEnd() + "\r\n"; } } // Creating our document. using (var stream = new FileStream(rootPath + filename, FileMode.Create)) { using (var document = new Document(PageSize.A4, 55, 55, 70, 70)) { using (var writer = PdfWriter.GetInstance(document, stream)) { document.Open(); using (var htmlStream = new MemoryStream(Encoding.UTF8.GetBytes(html))) { using (var cssStream = new MemoryStream(Encoding.UTF8.GetBytes(css))) { XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, htmlStream, cssStream); } } document.Close(); } } } } }
public static void p5_events_create(ApplicationContext context, ActiveEventArgs e) { // Acquire write lock, since we're consuming object shared amongst more than one thread (_events). _lock.EnterWriteLock(); try { // Checking to see if this event has no lambda objects, at which case it is a delete event invocation. if (!e.Args.Children.Any(ix => ix.Name != "")) { // Deleting event, if existing, since it doesn't have any lambda objects associated with it. DeleteEvent(XUtil.Single <string> (context, e.Args), context, e.Args); } else { // Creating new event. CreateEvent(XUtil.Single <string> (context, e.Args), e.Args, context); } } finally { // Making sure we release lock in a finally, such that we can never exit method, without releasing our lock. _lock.ExitWriteLock(); } }
public static void p5_string_split(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new Utilities.ArgsRemover(e.Args, true)) { // Figuring out source value of [p5.string.split], and returning early if there is none. string source = XUtil.Single <string> (context, e.Args); if (source == null) { return; } // Checking if we should explicitly keep empty items. StringSplitOptions options = e.Args.GetExChildValue("keep-empty", context, false) ? StringSplitOptions.None : StringSplitOptions.RemoveEmptyEntries; // Checking if each item should be trimmed before returned. var trim = e.Args.GetExChildValue("trim", context, false); // Retrieving separator objects, which might be multiple integers, multiple strings, or a single regular expression. var sepObjects = e.Args.Children .Where(ix => ix.Name == "=") .Select(ix => ix.GetExValue <object> (context)) .ToList(); // Checking if there were any separators. if (sepObjects.Count > 0) { // We have separators, meaning we should actually perform a split operation. RunSplit(context, e.Args, source, options, trim, sepObjects); } else { // Special case, no separators, splitting entire string into characters. // Which is actually the only way we can iterate over each character in a string in P5. e.Args.AddRange(source.Select(ix => new Node(ix.ToString()))); } } }