namespace Owl { public delegate bool VisitFileLambda (Owl.Path file); public class Path { static string ALPHABET_STRING = "abcdefghijklmnopqrstuvwxyz"; GLib.File file; bool is_tmp; private static string get_random_string () { var random_generator = new GLib.Rand (); string final_string = "valatmp-"; for (uint64 i = 0; i < 12; i++) { var random_number = random_generator.next_int () % ALPHABET_STRING.length; final_string += ALPHABET_STRING[random_number].to_string (); } return final_string; } public Path (GLib.File file) { this.file = file; } public Path.tempdir () throws GLib.Error { this.is_tmp = true; var file = GLib.File.new_for_path(GLib.Environment.get_tmp_dir () + Config.WS + get_random_string ()); while (file.query_exists ()) { file = GLib.File.new_for_path(GLib.Environment.get_tmp_dir () + Config.WS + get_random_string ()); } file.make_directory (); this.file = file; } ~Path () { if (this.is_tmp) { try { this.@delete (); } catch (GLib.Error error) { GLib.critical (error.message); } } } public void spew (string content) throws GLib.Error { GLib.FileUtils.set_contents (this.get_path (), content); } public string slurp () throws GLib.Error { string output; GLib.FileUtils.get_contents (this.get_path (), out output); return output; } public GLib.FileOutputStream replace () throws GLib.Error { return this.file.replace (null, false, GLib.FileCreateFlags.PRIVATE); } public GLib.FileOutputStream create () throws GLib.Error { return this.file.create (GLib.FileCreateFlags.PRIVATE); } public Owl.Path child (string relative_path) throws GLib.Error { GLib.File child_file = this.file.resolve_relative_path (relative_path); return new Owl.Path (child_file); } public void mkpath () throws GLib.Error { this.file.make_directory_with_parents (); } public bool exists () { return this.file.query_exists (); } public Owl.Path parent () { return new Owl.Path (this.file.get_parent ()); } public void @delete () throws GLib.Error { if (!this.is_dir ()) { this.file.delete (); return; } foreach (Owl.Path inner_file in this.children ()) { inner_file.delete (); } this.file.delete (); } public GLib.File get_file () { return this.file; } public string? get_path () { return this.file.get_path (); } public string basename () { return this.file.get_basename (); } public GLib.List children() { var children = new GLib.List (); if (!this.is_dir ()) { GLib.critical ("You cannot list children if the target is not a directory.\n"); return children; } try { GLib.FileEnumerator enumerator = this.file.enumerate_children ( "standard::*", FileQueryInfoFlags.NONE); GLib.FileInfo info; while ((info = enumerator.next_file (null)) != null) { GLib.File inner_file = file.resolve_relative_path (info.get_name ()); children.append (new Owl.Path (inner_file)); } } catch (GLib.Error error) { GLib.critical (error.message); return children; } return children; } public bool visit (bool recursive, Owl.VisitFileLambda lambda, bool visit_upper_dir = true) { if (!this.is_dir ()) { GLib.critical ("Unable to visit non directory\n"); return false; } if (visit_upper_dir) { bool continue_visit = lambda (this); if (!continue_visit) { return false; } } foreach (Owl.Path inner_file in this.children ()) { bool continue_visit = lambda (inner_file); if (!continue_visit) { return false; } if (recursive && inner_file.is_dir ()) { continue_visit = inner_file.visit (true, lambda, false); if (!continue_visit) { return false; } } } return true; } public bool is_dir () { return this.query () == GLib.FileType.DIRECTORY; } private GLib.FileType query () { return this.file.query_file_type (GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS); } } }