소스 검색

AK: Add a canonicalized_path() convenience function.

This is the same as calling FileSystemPath(foo).string(). The majority of
clients only care about canonicalizing a path, so let's have an easy way
to express that.
Andreas Kling 6 년 전
부모
커밋
954a0b8efe

+ 15 - 9
AK/FileSystemPath.cpp

@@ -8,14 +8,14 @@ namespace AK {
 FileSystemPath::FileSystemPath(const StringView& s)
     : m_string(s)
 {
-    m_is_valid = canonicalize();
+    canonicalize();
+    m_is_valid = true;
 }
 
-bool FileSystemPath::canonicalize(bool resolve_symbolic_links)
+void FileSystemPath::canonicalize()
 {
-    // FIXME: Implement "resolve_symbolic_links"
-    (void)resolve_symbolic_links;
-    auto parts = m_string.split('/');
+    auto parts = m_string.split_view('/');
+    int approximate_canonical_length = 0;
     Vector<String> canonical_parts;
 
     for (auto& part : parts) {
@@ -26,23 +26,24 @@ bool FileSystemPath::canonicalize(bool resolve_symbolic_links)
                 canonical_parts.take_last();
             continue;
         }
-        if (!part.is_empty())
+        if (!part.is_empty()) {
+            approximate_canonical_length += part.length() + 1;
             canonical_parts.append(part);
+        }
     }
     if (canonical_parts.is_empty()) {
         m_string = m_basename = "/";
-        return true;
+        return;
     }
 
     m_basename = canonical_parts.last();
-    StringBuilder builder;
+    StringBuilder builder(approximate_canonical_length);
     for (auto& cpart : canonical_parts) {
         builder.append('/');
         builder.append(cpart);
     }
     m_parts = move(canonical_parts);
     m_string = builder.to_string();
-    return true;
 }
 
 bool FileSystemPath::has_extension(StringView extension) const
@@ -52,4 +53,9 @@ bool FileSystemPath::has_extension(StringView extension) const
     return m_string.to_lowercase().ends_with(extension_string.to_lowercase());
 }
 
+String canonicalized_path(const StringView& path)
+{
+    return FileSystemPath(path).string();
+}
+
 }

+ 4 - 1
AK/FileSystemPath.h

@@ -19,7 +19,7 @@ public:
     bool has_extension(StringView) const;
 
 private:
-    bool canonicalize(bool resolve_symbolic_links = false);
+    void canonicalize();
 
     Vector<String> m_parts;
     String m_string;
@@ -27,6 +27,9 @@ private:
     bool m_is_valid { false };
 };
 
+String canonicalized_path(const StringView&);
+
 };
 
 using AK::FileSystemPath;
+using AK::canonicalized_path;

+ 6 - 6
Applications/FileManager/DirectoryView.cpp

@@ -10,14 +10,14 @@ void DirectoryView::handle_activation(const GModelIndex& index)
         return;
     dbgprintf("on activation: %d,%d, this=%p, m_model=%p\n", index.row(), index.column(), this, m_model.ptr());
     auto& entry = model().entry(index.row());
-    FileSystemPath path(String::format("%s/%s", model().path().characters(), entry.name.characters()));
+    auto path = canonicalized_path(String::format("%s/%s", model().path().characters(), entry.name.characters()));
     if (entry.is_directory()) {
-        open(path.string());
+        open(path);
         return;
     }
     if (entry.is_executable()) {
         if (fork() == 0) {
-            int rc = execl(path.string().characters(), path.string().characters(), nullptr);
+            int rc = execl(path.characters(), path.characters(), nullptr);
             if (rc < 0)
                 perror("exec");
             ASSERT_NOT_REACHED();
@@ -25,9 +25,9 @@ void DirectoryView::handle_activation(const GModelIndex& index)
         return;
     }
 
-    if (path.string().to_lowercase().ends_with(".png")) {
+    if (path.to_lowercase().ends_with(".png")) {
         if (fork() == 0) {
-            int rc = execl("/bin/qs", "/bin/qs", path.string().characters(), nullptr);
+            int rc = execl("/bin/qs", "/bin/qs", path.characters(), nullptr);
             if (rc < 0)
                 perror("exec");
             ASSERT_NOT_REACHED();
@@ -36,7 +36,7 @@ void DirectoryView::handle_activation(const GModelIndex& index)
     }
 
     if (fork() == 0) {
-        int rc = execl("/bin/TextEditor", "/bin/TextEditor", path.string().characters(), nullptr);
+        int rc = execl("/bin/TextEditor", "/bin/TextEditor", path.characters(), nullptr);
         if (rc < 0)
             perror("exec");
         ASSERT_NOT_REACHED();

+ 4 - 4
Applications/FileManager/main.cpp

@@ -91,10 +91,10 @@ int main(int argc, char** argv)
     auto mkdir_action = GAction::create("New directory...", GraphicsBitmap::load_from_file("/res/icons/16x16/mkdir.png"), [&](const GAction&) {
         GInputBox input_box("Enter name:", "New directory", window);
         if (input_box.exec() == GInputBox::ExecOK && !input_box.text_value().is_empty()) {
-            auto new_dir_path = FileSystemPath(String::format("%s/%s",
-                                                   directory_view->path().characters(),
-                                                   input_box.text_value().characters()))
-                                    .string();
+            auto new_dir_path = canonicalized_path(
+                String::format("%s/%s",
+                    directory_view->path().characters(),
+                    input_box.text_value().characters()));
             int rc = mkdir(new_dir_path.characters(), 0777);
             if (rc < 0) {
                 GMessageBox::show(String::format("mkdir(\"%s\") failed: %s", new_dir_path.characters(), strerror(errno)), "Error", GMessageBox::Type::Error, window);

+ 1 - 2
Libraries/LibGUI/GDirectoryModel.cpp

@@ -301,8 +301,7 @@ void GDirectoryModel::update()
 
 void GDirectoryModel::open(const StringView& a_path)
 {
-    FileSystemPath canonical_path(a_path);
-    auto path = canonical_path.string();
+    auto path = canonicalized_path(a_path);
     if (m_path == path)
         return;
     DIR* dirp = opendir(path.characters());

+ 2 - 2
Libraries/LibGUI/GFileSystemModel.cpp

@@ -92,7 +92,7 @@ struct GFileSystemModel::Node {
         }
         builder.append('/');
         builder.append(name);
-        return FileSystemPath(builder.to_string()).string();
+        return canonicalized_path(builder.to_string());
     }
 };
 
@@ -130,7 +130,7 @@ String GFileSystemModel::path(const GModelIndex& index) const
 }
 
 GFileSystemModel::GFileSystemModel(const StringView& root_path, Mode mode)
-    : m_root_path(FileSystemPath(root_path).string())
+    : m_root_path(canonicalized_path(root_path))
     , m_mode(mode)
 {
     m_open_folder_icon = GIcon::default_icon("filetype-folder-open");

+ 1 - 1
SharedGraphics/PNGLoader.cpp

@@ -108,7 +108,7 @@ RefPtr<GraphicsBitmap> load_png(const StringView& path)
         return nullptr;
     auto bitmap = load_png_impl((const u8*)mapped_file.pointer(), mapped_file.size());
     if (bitmap)
-        bitmap->set_mmap_name(String::format("GraphicsBitmap [%dx%d] - Decoded PNG: %s", bitmap->width(), bitmap->height(), FileSystemPath(path).string().characters()));
+        bitmap->set_mmap_name(String::format("GraphicsBitmap [%dx%d] - Decoded PNG: %s", bitmap->width(), bitmap->height(), canonicalized_path(path).characters()));
     return bitmap;
 }