[niepce] npc-fwk: bind FileList with cxx



commit 5ef485175ccc1ae787700f445ecdc47bb8226cf1
Author: Hubert Figuière <hub figuiere net>
Date:   Sat Oct 15 16:07:38 2022 -0400

    npc-fwk: bind FileList with cxx

 crates/npc-fwk/src/lib.rs                          |  47 ++++++++++
 crates/npc-fwk/src/utils/files.rs                  | 101 +++++----------------
 niepce-main/build.rs                               |   1 +
 src/engine/importer/cameraimporter.cpp             |   4 +-
 src/engine/importer/directoryimporter.cpp          |  22 ++---
 src/engine/importer/iimporter.hpp                  |   2 +
 src/fwk/toolkit/gphoto.hpp                         |   2 +
 src/fwk/utils/files.cpp                            |  35 +------
 src/fwk/utils/files.hpp                            |  19 +---
 src/fwk/utils/modulemanager.cpp                    |  15 +--
 .../ui/dialogs/importers/cameraimporterui.cpp      |   1 +
 src/niepce/ui/workspacecontroller.cpp              |   2 +-
 src/rust_bindings.hpp                              |   3 +-
 13 files changed, 91 insertions(+), 163 deletions(-)
---
diff --git a/crates/npc-fwk/src/lib.rs b/crates/npc-fwk/src/lib.rs
index 69dc9db1..9f8d0ada 100644
--- a/crates/npc-fwk/src/lib.rs
+++ b/crates/npc-fwk/src/lib.rs
@@ -54,6 +54,7 @@ use glib::translate::*;
 use crate::base::date::Date;
 use crate::toolkit::thumbnail::Thumbnail;
 use crate::toolkit::Configuration;
+use crate::utils::files::FileList;
 
 fn make_config_path(file: &str) -> String {
     Configuration::make_config_path(file)
@@ -99,6 +100,36 @@ fn thumbnail_to_pixbuf(self_: &Thumbnail) -> *mut c_char {
     pixbuf as *mut c_char
 }
 
+/// Get the files in directory dir with extension ext
+/// `ext` has no dot
+pub fn file_list_get_files_from_directory_with_ext(dir: &str, ext: String) -> Box<FileList> {
+    Box::new(FileList::get_files_from_directory(dir, move |file| {
+        if let Some(file_ext) = file.name().extension() {
+            if file_ext.to_string_lossy().to_lowercase() == ext {
+                return true;
+            }
+        }
+        false
+    }))
+}
+
+/// Get all the files in directory dir.
+pub fn file_list_get_files_from_directory(dir: &str) -> Box<FileList> {
+    Box::new(FileList::get_files_from_directory(dir, |_| true))
+}
+
+/// Get all the files in directory dir.
+pub fn file_list_get_media_files_from_directory(dir: &str) -> Box<FileList> {
+    Box::new(FileList::get_files_from_directory(
+        dir,
+        FileList::file_is_media,
+    ))
+}
+
+pub fn file_list_new() -> Box<FileList> {
+    Box::new(FileList::default())
+}
+
 #[cxx::bridge(namespace = "fwk")]
 mod ffi {
     struct SharedConfiguration {
@@ -152,4 +183,20 @@ mod ffi {
         #[cxx_name = "Thumbnail_to_pixbuf"]
         fn thumbnail_to_pixbuf(self_: &Thumbnail) -> *mut c_char;
     }
+
+    extern "Rust" {
+        type FileList;
+
+        #[cxx_name = "FileList_get_files_from_directory"]
+        fn file_list_get_files_from_directory(dir: &str) -> Box<FileList>;
+        #[cxx_name = "FileList_get_files_from_directory_with_ext"]
+        fn file_list_get_files_from_directory_with_ext(dir: &str, ext: String) -> Box<FileList>;
+        #[cxx_name = "FileList_get_media_files_from_directory"]
+        fn file_list_get_media_files_from_directory(dir: &str) -> Box<FileList>;
+        #[cxx_name = "FileList_new"]
+        fn file_list_new() -> Box<FileList>;
+        fn size(&self) -> usize;
+        fn at(&self, idx: usize) -> String;
+        fn push_back(&mut self, value: &str);
+    }
 }
diff --git a/crates/npc-fwk/src/utils/files.rs b/crates/npc-fwk/src/utils/files.rs
index 28014ab3..85cdd151 100644
--- a/crates/npc-fwk/src/utils/files.rs
+++ b/crates/npc-fwk/src/utils/files.rs
@@ -17,12 +17,9 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-use libc::c_char;
-use std::ffi::{CStr, CString};
 use std::path::{Path, PathBuf};
 
 use gio::prelude::*;
-use glib::translate::*;
 
 use crate::toolkit::mimetype::{guess_type, MType};
 
@@ -30,6 +27,27 @@ use crate::toolkit::mimetype::{guess_type, MType};
 pub struct FileList(pub Vec<PathBuf>);
 
 impl FileList {
+    // cxx
+    pub fn size(&self) -> usize {
+        self.0.len()
+    }
+
+    // cxx
+    /// Return the path string at index %idx
+    /// The resulting string must be freeed with %rust_cstring_delete
+    pub fn at(&self, idx: usize) -> String {
+        self.0[idx].to_string_lossy().into()
+    }
+
+    // cxx
+    /// Push a file path to the list
+    pub fn push_back(&mut self, value: &str) {
+        self.0.push(PathBuf::from(value));
+    }
+
+    /// Get the files matching `filter` from `dir`.
+    ///
+    /// `filter` is a function that will return `true` for files to keep
     pub fn get_files_from_directory<P, F>(dir: P, filter: F) -> Self
     where
         P: AsRef<Path>,
@@ -84,83 +102,6 @@ impl FileList {
     }
 }
 
-/// Tell is the file pointed by finfo is a media file
-///
-/// # Safety
-/// Dereference the finfo pointer.
-#[no_mangle]
-pub unsafe extern "C" fn fwk_file_is_media(finfo: *mut gio_sys::GFileInfo) -> bool {
-    let fileinfo = gio::FileInfo::from_glib_none(finfo);
-    FileList::file_is_media(&fileinfo)
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_file_list_new() -> *mut FileList {
-    Box::into_raw(Box::new(FileList::default()))
-}
-
-/// Delete the file list object from ffi code
-///
-/// # Safety
-/// Dereference the pointer
-#[no_mangle]
-pub unsafe extern "C" fn fwk_file_list_delete(l: *mut FileList) {
-    drop(Box::from_raw(l));
-}
-
-/// Get the files in directory dir
-///
-/// # Safety
-/// Dereference the dir pointer (C String)
-#[no_mangle]
-pub unsafe extern "C" fn fwk_file_list_get_files_from_directory(
-    dir: *const c_char,
-    filter: Option<extern "C" fn(*mut gio_sys::GFileInfo) -> bool>,
-) -> *mut FileList {
-    let cstr = CStr::from_ptr(dir);
-    match filter {
-        Some(filter) => {
-            let f = Box::new(filter);
-            Box::into_raw(Box::new(FileList::get_files_from_directory(
-                &PathBuf::from(&*cstr.to_string_lossy()),
-                move |finfo| f(finfo.to_glib_none().0),
-            )))
-        }
-        None => Box::into_raw(Box::new(FileList::get_files_from_directory(
-            &PathBuf::from(&*cstr.to_string_lossy()),
-            move |_| true,
-        ))),
-    }
-}
-
-#[no_mangle]
-pub extern "C" fn fwk_file_list_size(l: &FileList) -> usize {
-    l.0.len()
-}
-
-/// Return the path string at index %idx
-/// The resulting string must be freeed with %rust_cstring_delete
-#[no_mangle]
-pub extern "C" fn fwk_file_list_at(l: &FileList, idx: usize) -> *mut c_char {
-    CString::new(l.0[idx].to_string_lossy().as_bytes())
-        .unwrap()
-        .into_raw()
-}
-
-#[no_mangle]
-/// Push a file path to the list
-///
-/// # Safety
-/// Dereference the value pointer (C string)
-pub unsafe extern "C" fn fwk_file_list_push_back(l: &mut FileList, value: *const c_char) {
-    assert!(!value.is_null());
-    if value.is_null() {
-        return;
-    }
-    let s = CStr::from_ptr(value);
-    l.0.push(PathBuf::from(&*s.to_string_lossy()));
-}
-
 #[cfg(test)]
 mod tests {
 
diff --git a/niepce-main/build.rs b/niepce-main/build.rs
index 0018a9f0..e6a303fd 100644
--- a/niepce-main/build.rs
+++ b/niepce-main/build.rs
@@ -26,6 +26,7 @@ fn main() {
             .exclude_item("Managed")
             .exclude_item("NiepcePropertyIdx")
             .exclude_item("FileStatus")
+            .exclude_item("FileList")
             .exclude_item("RgbColour")
             .exclude_item("CUSTOM_START")
             .exclude_item("INTERNAL_START")
diff --git a/src/engine/importer/cameraimporter.cpp b/src/engine/importer/cameraimporter.cpp
index 4a6d3b98..294bfe70 100644
--- a/src/engine/importer/cameraimporter.cpp
+++ b/src/engine/importer/cameraimporter.cpp
@@ -123,7 +123,7 @@ bool CameraImporter::do_import(const std::string& source, const std::string& des
             DBG_ASSERT(!tmp_dir_path.empty(), "Dest dir is empty");
             // XXX check we don't return an empty string.
 
-            fwk::FileListPtr files = fwk::wrapFileList(ffi::fwk_file_list_new());
+            fwk::FileListPtr files = fwk::FileList_new();
             for (auto file: file_list) {
                 auto imported_camera_file =
                     std::dynamic_pointer_cast<CameraImportedFile>(file);
@@ -137,7 +137,7 @@ bool CameraImporter::do_import(const std::string& source, const std::string& des
                 if (this->m_camera->download_file(imported_camera_file->folder(),
                                                   imported_camera_file->name(),
                                                   output_path)) {
-                    ffi::fwk_file_list_push_back(files.get(), output_path.c_str());
+                    files->push_back(output_path);
                 }
             }
 
diff --git a/src/engine/importer/directoryimporter.cpp b/src/engine/importer/directoryimporter.cpp
index 2e37caa5..0c881ce1 100644
--- a/src/engine/importer/directoryimporter.cpp
+++ b/src/engine/importer/directoryimporter.cpp
@@ -62,23 +62,15 @@ const std::string& DirectoryImporter::id() const
     return _id;
 }
 
-static bool filter_only_media(GFileInfo* info)
-{
-    return fwk::filter_only_media(Glib::wrap(info, true));
-}
-
 bool DirectoryImporter::list_source_content(const std::string & source,
                                             const SourceContentReady& callback)
 {
-    auto files =
-        fwk::wrapFileList(ffi::fwk_file_list_get_files_from_directory(
-                              source.c_str(), &filter_only_media));
-    DBG_OUT("files size: %lu", ffi::fwk_file_list_size(files.get()));
+    auto files = fwk::FileList_get_media_files_from_directory(source);
+    DBG_OUT("files size: %lu", files->size());
     std::list<ImportedFilePtr> content;
-    for (size_t i = 0; i < ffi::fwk_file_list_size(files.get()); i++)
-    {
-        auto entry = fwk::RustFfiString(ffi::fwk_file_list_at(files.get(), i));
-        content.push_back(ImportedFilePtr(new DirectoryImportedFile(entry.str())));
+    for (size_t i = 0; i < files->size(); i++) {
+        auto entry = files->at(i);
+        content.push_back(ImportedFilePtr(new DirectoryImportedFile(std::string(entry))));
     }
     callback(std::move(content));
 
@@ -100,9 +92,7 @@ bool DirectoryImporter::get_previews_for(const std::string& /*source*/,
 bool DirectoryImporter::do_import(const std::string& source, const std::string& /*dest_dir*/,
                                   const FileImporter& callback)
 {
-    fwk::FileListPtr files;
-    files = fwk::wrapFileList(ffi::fwk_file_list_get_files_from_directory(
-                                  source.c_str(), nullptr));
+    fwk::FileListPtr files = fwk::FileList_get_files_from_directory(source);
 
     return callback(source, files, Managed::NO);
 }
diff --git a/src/engine/importer/iimporter.hpp b/src/engine/importer/iimporter.hpp
index 267a493d..1d23c097 100644
--- a/src/engine/importer/iimporter.hpp
+++ b/src/engine/importer/iimporter.hpp
@@ -27,6 +27,8 @@
 #include "fwk/utils/files.hpp"
 #include "engine/importer/importedfile.hpp"
 
+#include "rust_bindings.hpp"
+
 namespace eng {
 
 /**
diff --git a/src/fwk/toolkit/gphoto.hpp b/src/fwk/toolkit/gphoto.hpp
index 9616ba3f..a4f68eba 100644
--- a/src/fwk/toolkit/gphoto.hpp
+++ b/src/fwk/toolkit/gphoto.hpp
@@ -33,6 +33,8 @@
 #include "fwk/base/singleton.hpp"
 #include "fwk/base/util.hpp"
 
+#include "rust_bindings.hpp"
+
 namespace fwk {
 
 namespace gp {
diff --git a/src/fwk/utils/files.cpp b/src/fwk/utils/files.cpp
index a4971d98..43eed0d2 100644
--- a/src/fwk/utils/files.cpp
+++ b/src/fwk/utils/files.cpp
@@ -2,7 +2,7 @@
 /*
  * niepce - fwk/utils/files.cpp
  *
- * Copyright (C) 2007-2018 Hubert Figuiere
+ * Copyright (C) 2007-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -47,38 +47,5 @@ std::string make_tmp_dir(const std::string& base)
     return tmp_dir_path;
 }
 
-bool filter_none(const Glib::RefPtr<Gio::FileInfo> & )
-{
-    return true;
-}
-
-
-bool filter_ext(const Glib::RefPtr<Gio::FileInfo> & file, const std::string & ext)
-{
-    std::string file_ext = fwk::path_extension(file->get_name());
-    boost::to_lower(file_ext);
-    if(file_ext == ext) {
-        return false;
-    }
-    return true;
-}
-
-bool filter_xmp_out(const Glib::RefPtr<Gio::FileInfo> & file)
-{
-    static const std::string ext(".xmp");
-    return filter_ext(file, ext);
-}
-
-bool filter_only_media(const Glib::RefPtr<Gio::FileInfo> & file)
-{
-    return ffi::fwk_file_is_media(file->gobj());
-}
-
-
-FileListPtr wrapFileList(ffi::FileList* list)
-{
-    return FileListPtr(list, ffi::fwk_file_list_delete);
-}
-
 }
 
diff --git a/src/fwk/utils/files.hpp b/src/fwk/utils/files.hpp
index 1d3be813..417148ef 100644
--- a/src/fwk/utils/files.hpp
+++ b/src/fwk/utils/files.hpp
@@ -2,7 +2,7 @@
 /*
  * niepce - fwk/utils/files.hpp
  *
- * Copyright (C) 2007-2018 Hubert Figuiere
+ * Copyright (C) 2007-2022 Hubert Figuière
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -20,14 +20,7 @@
 
 #pragma once
 
-#include <algorithm>
-#include <vector>
 #include <string>
-#include <memory>
-
-#include <functional>
-
-#include <giomm/fileinfo.h>
 
 #include "rust_bindings.hpp"
 
@@ -36,14 +29,4 @@ namespace fwk {
 /** wrapper around g_dir_make_tmp() */
 std::string make_tmp_dir(const std::string& base);
 
-bool filter_none(const Glib::RefPtr<Gio::FileInfo> & file);
-bool filter_ext(const Glib::RefPtr<Gio::FileInfo> & file,
-                const std::string & ext);
-bool filter_xmp_out(const Glib::RefPtr<Gio::FileInfo> & file);
-bool filter_only_media(const Glib::RefPtr<Gio::FileInfo> & file);
-
-typedef std::shared_ptr<ffi::FileList> FileListPtr;
-
-FileListPtr wrapFileList(ffi::FileList* list);
-
 }
diff --git a/src/fwk/utils/modulemanager.cpp b/src/fwk/utils/modulemanager.cpp
index 875ea2a9..3f782c2b 100644
--- a/src/fwk/utils/modulemanager.cpp
+++ b/src/fwk/utils/modulemanager.cpp
@@ -57,24 +57,17 @@ namespace fwk {
     DBG_OUT("add path %s", dir.c_str());
   }
 
-
-  static bool filter(GFileInfo* f)
-  {
-    return fwk::filter_ext(Glib::wrap(f, true), std::string(".") + G_MODULE_SUFFIX);
-  }
-
   void ModuleManager::load_modules()
   {
     for(auto iter = m_dirs.cbegin();
         iter != m_dirs.cend(); ++iter) {
 
-      fwk::FileListPtr l;
-      l = wrapFileList(ffi::fwk_file_list_get_files_from_directory(
-                         iter->c_str(), filter));
+      fwk::FileListPtr l = fwk::FileList_get_files_from_directory_with_ext(
+                         *iter, G_MODULE_SUFFIX);
 
-      for(size_t i = 0; i < ffi::fwk_file_list_size(l.get()); i++) {
+      for(size_t i = 0; i < l->size(); i++) {
 
-        auto file_path = fwk::RustFfiString(ffi::fwk_file_list_at(l.get(), i));
+        auto file_path = l->at(i);
         Glib::Module module(*iter + "/" + path_basename(file_path.c_str()),
                             Glib::Module::Flags::LOCAL);
         DBG_OUT("load module %s", path_basename(file_path.c_str()).c_str());
diff --git a/src/niepce/ui/dialogs/importers/cameraimporterui.cpp 
b/src/niepce/ui/dialogs/importers/cameraimporterui.cpp
index dbf99a5a..879609b5 100644
--- a/src/niepce/ui/dialogs/importers/cameraimporterui.cpp
+++ b/src/niepce/ui/dialogs/importers/cameraimporterui.cpp
@@ -21,6 +21,7 @@
 #include <boost/format.hpp>
 
 #include <glibmm/i18n.h>
+#include <glibmm/datetime.h>
 #include <gtkmm/label.h>
 #include <gtkmm/grid.h>
 #include <gtkmm/comboboxtext.h>
diff --git a/src/niepce/ui/workspacecontroller.cpp b/src/niepce/ui/workspacecontroller.cpp
index 10098be6..6aaf52ce 100644
--- a/src/niepce/ui/workspacecontroller.cpp
+++ b/src/niepce/ui/workspacecontroller.cpp
@@ -137,7 +137,7 @@ void WorkspaceController::perform_file_import(ImportDialog::Ptr dialog)
             source, dest_dir,
             [this] (const std::string& path, const fwk::FileListPtr& files, Managed manage) -> bool {
                 ffi::libraryclient_import_files(
-                    getLibraryClient()->client(), path.c_str(), files.get(), manage);
+                    getLibraryClient()->client(), path.c_str(), &*files, manage);
                 // XXX the libraryclient function returns void
                 return true;
             });
diff --git a/src/rust_bindings.hpp b/src/rust_bindings.hpp
index 27d036ce..f64d91f7 100644
--- a/src/rust_bindings.hpp
+++ b/src/rust_bindings.hpp
@@ -32,6 +32,7 @@ template <class T>
 struct DateTime;
 typedef fwk::Date Date;
 typedef rust_str str;
+typedef fwk::FileList FileList;
 struct NiepcePropertyBag;
 struct NiepcePropertySet;
 }
@@ -44,12 +45,12 @@ namespace fwk {
 typedef std::shared_ptr<SharedConfiguration> ConfigurationPtr;
 typedef rust::Box<fwk::Date> DatePtr;
 typedef rust::Box<Thumbnail> ThumbnailPtr;
+typedef rust::Box<FileList> FileListPtr;
 
 typedef ffi::PropertyValue PropertyValue;
 typedef ffi::NiepcePropertyBag PropertyBag;
 typedef ffi::NiepcePropertySet PropertySet;
 typedef ffi::RgbColour RgbColour;
-typedef ffi::FileList FileList;
 }
 
 namespace eng {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]