[niepce: 11/29] engine+rust: implement FileBundle and MimeType in Rust
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce: 11/29] engine+rust: implement FileBundle and MimeType in Rust
- Date: Fri, 22 Sep 2017 00:42:38 +0000 (UTC)
commit a0158e2300bf59ea304aa90ff4d5df1f9b1c0916
Author: Hubert Figuière <hub figuiere net>
Date: Fri Jun 16 22:16:15 2017 -0400
engine+rust: implement FileBundle and MimeType in Rust
Cargo.toml | 6 ++-
build.rs | 7 ++-
src/engine/Makefile.am | 2 +-
src/engine/db/bindings.hpp | 3 +
src/engine/db/filebundle.cpp | 91 +++++++-----------------
src/engine/db/filebundle.hpp | 52 +++-----------
src/engine/db/filebundle.rs | 140 +++++++++++++++++++++++++++++++++++++
src/engine/db/library.cpp | 12 ++--
src/engine/db/library.hpp | 2 +-
src/engine/db/mod.rs | 1 +
src/engine/db/test_filebundle.cpp | 18 +++--
src/engine/library/commands.cpp | 8 +-
src/fwk/mod.rs | 4 +
src/fwk/toolkit/mimetype.cpp | 28 +++++---
src/fwk/toolkit/mimetype.hpp | 12 ++--
src/fwk/toolkit/mimetype.rs | 120 +++++++++++++++++++++++++++++++
src/fwk/toolkit/mod.rs | 2 +
src/lib.rs | 3 +
src/libraryclient/Makefile.am | 2 +-
src/niepce/Makefile.am | 2 +-
20 files changed, 370 insertions(+), 145 deletions(-)
---
diff --git a/Cargo.toml b/Cargo.toml
index dddc75e..43a3478 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,12 +7,16 @@ authors = ["Hubert Figuière <hub figuiere net>"]
libc = "0.2.23"
sqlite = "0.23.4"
exempi = "2.4.1"
+glib-sys = { git = "https://github.com/gtk-rs/sys" }
+gio-sys = { git = "https://github.com/gtk-rs/sys" }
+gio = { git = "https://github.com/gtk-rs/gio" }
#gphoto = "0.1.1"
[build-dependencies]
# We need git master as currently it the crate version fail on shared_ptr<>
bindgen = { git = "https://github.com/servo/rust-bindgen.git" }
+pkg-config = "0.3.9"
[lib]
-name = "niece_rust"
+name = "niepce_rust"
crate-type = ["staticlib"]
diff --git a/build.rs b/build.rs
index c48b426..ac28afb 100644
--- a/build.rs
+++ b/build.rs
@@ -1,10 +1,10 @@
extern crate bindgen;
+extern crate pkg_config;
use std::env;
use std::path::PathBuf;
fn main() {
-
// The bindgen::Builder is the main entry point
// to bindgen, and lets you build up options for
// the resulting bindings.
@@ -18,9 +18,12 @@ fn main() {
// The input header we would like to generate
// bindings for.
.whitelisted_type("eng::NiepceProperties")
- .header("src/engine/db/properties-enum.hpp")
+ .header("src/engine/db/bindings.hpp")
+ .clang_arg("--std=c++11")
+ .clang_arg("-DRUST_BINDGEN=1")
.clang_arg("-I./src");
+
// Finish the builder and generate the bindings.
let bindings = builder.generate()
// Unwrap the Result and panic on failure.
diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am
index 8123f1c..9e6e83e 100644
--- a/src/engine/Makefile.am
+++ b/src/engine/Makefile.am
@@ -8,10 +8,10 @@ TESTS = test_library test_filebundle test_opqueue
TEST_LIBS = \
libniepceengine.a \
+ $(top_builddir)/target/debug/libniepce_rust.a \
$(top_builddir)/src/fwk/utils/libniepceutils.a \
$(top_builddir)/src/fwk/toolkit/libniepceframework.a \
$(top_builddir)/src/fwk/base/libfwkbase.a \
- $(top_builddir)/target/debug/libniece_rust.a \
@BOOST_UNIT_TEST_FRAMEWORK_LIBS@ \
@FRAMEWORK_LIBS@ \
@OPENRAW_LIBS@ \
diff --git a/src/engine/db/bindings.hpp b/src/engine/db/bindings.hpp
new file mode 100644
index 0000000..1d234bc
--- /dev/null
+++ b/src/engine/db/bindings.hpp
@@ -0,0 +1,3 @@
+/** @brief what to generate bindings for in Rust */
+
+#include "properties-enum.hpp"
diff --git a/src/engine/db/filebundle.cpp b/src/engine/db/filebundle.cpp
index 9b2611e..64ec299 100644
--- a/src/engine/db/filebundle.cpp
+++ b/src/engine/db/filebundle.cpp
@@ -24,81 +24,42 @@
#include "fwk/utils/pathutils.hpp"
#include "fwk/toolkit/mimetype.hpp"
+extern "C" eng::FileBundle* engine_db_filebundle_new();
+extern "C" void engine_db_filebundle_delete(eng::FileBundle*);
namespace eng {
-bool
-FileBundle::add(const std::string & path)
-{
- // TODO make it more reliable with more tests.
- fwk::MimeType mime_type(path);
- bool added = true;
-
- if(mime_type.isImage()) {
- if(mime_type.isDigicamRaw()) {
- if(!m_main.empty() && m_jpeg.empty()) {
- m_jpeg = m_main;
- m_type = LibFileType::RAW_JPEG;
- }
- else {
- m_type = LibFileType::RAW;
- }
- m_main = path;
- }
- else {
- if(!m_main.empty()) {
- m_jpeg = path;
- m_type = LibFileType::RAW_JPEG;
- }
- else {
- m_main = path;
- m_type = LibFileType::IMAGE;
- }
- }
- }
- else if(mime_type.isXmp()) {
- m_xmp_sidecar = path;
- }
- else if(mime_type.isMovie()) {
- m_main = path;
- m_type = LibFileType::VIDEO;
- }
- else {
- DBG_OUT("Unkown file %s of type %s\n", path.c_str(),
- mime_type.string().c_str());
- added = false;
- }
- return added;
+FileBundlePtr filebundle_new() {
+ return FileBundlePtr(engine_db_filebundle_new(), &engine_db_filebundle_delete);
}
-
-FileBundle::ListPtr
-FileBundle::filter_bundles(const fwk::FileList::Ptr & files)
+FileBundleListPtr
+filebundle_filter_bundles(const fwk::FileList::Ptr & files)
{
- FileBundle::ListPtr bundles(new FileBundle::List());
- FileBundle::Ptr current_bundle;
+ FileBundleListPtr bundles(new FileBundleList);
+ FileBundlePtr current_bundle;
std::string current_base;
files->sort();
- std::for_each(files->cbegin(), files->cend(),
- [¤t_base, &bundles, ¤t_bundle]
- (const std::string & f) {
- std::string basename = fwk::path_stem(f);
-
- if(basename != current_base) {
- FileBundle::Ptr new_bundle(new FileBundle());
- if(new_bundle->add(f)) {
- bundles->push_back(new_bundle);
- current_bundle = new_bundle;
- current_base = basename;
- }
- }
- else {
- current_bundle->add(f);
- }
- }
- );
+ std::for_each(
+ files->cbegin(), files->cend(),
+ [¤t_base, &bundles, ¤t_bundle] (const std::string & f) {
+ std::string basename = fwk::path_stem(f);
+ DBG_OUT("basename %s current_base %s", basename.c_str(), current_base.c_str());
+ if(basename != current_base) {
+ FileBundlePtr new_bundle(filebundle_new());
+ auto r = engine_db_filebundle_add(new_bundle.get(), f.c_str());
+ DBG_OUT("r = %d", r);
+ if (r) {
+ bundles->push_back(new_bundle);
+ current_bundle = new_bundle;
+ current_base = basename;
+ }
+ } else {
+ engine_db_filebundle_add(current_bundle.get(), f.c_str());
+ }
+ });
return bundles;
}
diff --git a/src/engine/db/filebundle.hpp b/src/engine/db/filebundle.hpp
index d4300f4..8785665 100644
--- a/src/engine/db/filebundle.hpp
+++ b/src/engine/db/filebundle.hpp
@@ -17,52 +17,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __DB_FILEBUNDLE_H_
-#define __DB_FILEBUNDLE_H_
+#pragma once
#include <list>
-#include <string>
#include <memory>
#include "fwk/utils/files.hpp"
-#include "engine/db/libfile.hpp"
namespace eng {
+class FileBundle;
+typedef std::shared_ptr<FileBundle> FileBundlePtr;
+typedef std::list<FileBundlePtr> FileBundleList;
+typedef std::shared_ptr<FileBundleList> FileBundleListPtr;
-class FileBundle
-{
-public:
- typedef std::shared_ptr<FileBundle> Ptr;
- typedef std::list<Ptr> List;
- typedef std::shared_ptr<List> ListPtr;
+FileBundleListPtr filebundle_filter_bundles(const fwk::FileList::Ptr & files);
- FileBundle()
- : m_type(LibFileType::UNKNOWN)
- { }
- LibFileType type() const
- { return m_type; }
-
- /** add a file to a bundle. Will determine what type it is.
- * @return false if it does not know about the file
- */
- bool add(const std::string & path);
- const std::string & main_file() const
- { return m_main; }
- const std::string & jpeg() const
- { return m_jpeg; }
- const std::string & sidecar() const
- { return m_xmp_sidecar; }
-
- static ListPtr filter_bundles(const fwk::FileList::Ptr & files);
-private:
- LibFileType m_type;
- std::string m_main;
- std::string m_xmp_sidecar;
- std::string m_jpeg;
- std::string m_thumbnail;
-};
+FileBundlePtr filebundle_new();
+}
+extern "C" const char* engine_db_filebundle_sidecar(const eng::FileBundle*);
+extern "C" const char* engine_db_filebundle_main(const eng::FileBundle*);
+extern "C" const char* engine_db_filebundle_jpeg(const eng::FileBundle*);
+extern "C" bool engine_db_filebundle_add(eng::FileBundle*, const char*);
/*
Local Variables:
@@ -73,8 +50,3 @@ private:
fill-column:99
End:
*/
-
-}
-
-#endif
-
diff --git a/src/engine/db/filebundle.rs b/src/engine/db/filebundle.rs
new file mode 100644
index 0000000..9dc4dcd
--- /dev/null
+++ b/src/engine/db/filebundle.rs
@@ -0,0 +1,140 @@
+/*
+ * niepce - engine/db/filebundle.rs
+ *
+ * Copyright (C) 2017 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
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+use libc::c_char;
+use std::ffi::CStr;
+use std::ffi::CString;
+
+use super::libfile::FileType;
+use fwk::MimeType;
+
+pub struct FileBundle {
+ file_type: FileType,
+ main: String,
+ pub main_c: CString,
+ xmp_sidecar: String,
+ pub xmp_sidecar_c: CString,
+ jpeg: String,
+ pub jpeg_c: CString,
+}
+
+impl FileBundle {
+
+ pub fn new() -> FileBundle {
+ FileBundle {
+ file_type: FileType::UNKNOWN,
+ main: String::from(""),
+ main_c: CString::new("").unwrap(),
+ xmp_sidecar: String::from(""),
+ xmp_sidecar_c: CString::new("").unwrap(),
+ jpeg: String::from(""),
+ jpeg_c: CString::new("").unwrap(),
+ }
+ }
+
+ pub fn add(&mut self, path: &str) -> bool {
+ println!("path {}", path);
+ let mime_type = MimeType::new(path);
+ let mut added = true;
+
+ if mime_type.is_image() {
+ if mime_type.is_digicam_raw() {
+ println!("is RAW");
+ if !self.main.is_empty() && self.jpeg.is_empty() {
+ println!("+JPEG");
+ self.jpeg = self.main.clone();
+ self.file_type = FileType::RAW_JPEG;
+ } else {
+ println!("just RAW");
+ self.file_type = FileType::RAW;
+ }
+ self.main = String::from(path);
+ } else {
+ println!("is JPEG?");
+ if !self.main.is_empty() {
+ println!("RAW+JPEG");
+ self.jpeg = String::from(path);
+ self.file_type = FileType::RAW_JPEG;
+ } else {
+ println!("JPEG");
+ self.main = String::from(path);
+ self.file_type = FileType::IMAGE;
+ }
+ }
+ } else if mime_type.is_xmp() {
+ self.xmp_sidecar = String::from(path);
+ } else if mime_type.is_movie() {
+ self.main = String::from(path);
+ self.file_type = FileType::VIDEO;
+ } else {
+// let cstr = &*unsafe { CStr::from_ptr(mime_type.c_str()) };
+ println!("Unknown file {} of type", path);//, cstr.to_string_lossy());
+ //DBG_OUT("Unkown file %s of type %s\n", path.c_str(),
+ // mime_type.string().c_str());
+ added = false;
+ }
+ added
+ }
+
+ pub fn main(&self) -> &str {
+ &self.main
+ }
+
+ pub fn jpeg(&self) -> &str {
+ &self.jpeg
+ }
+
+ pub fn sidecar(&self) -> &str {
+ &self.xmp_sidecar
+ }
+}
+
+#[no_mangle]
+pub extern fn engine_db_filebundle_new() -> *mut FileBundle {
+ let fb = Box::new(FileBundle::new());
+ Box::into_raw(fb)
+}
+
+#[no_mangle]
+pub extern fn engine_db_filebundle_delete(fb: *mut FileBundle) {
+ unsafe { Box::from_raw(fb) };
+}
+
+#[no_mangle]
+pub extern fn engine_db_filebundle_sidecar(this: &mut FileBundle) -> *const c_char {
+ this.xmp_sidecar_c = CString::new(this.sidecar()).unwrap();
+ this.xmp_sidecar_c.as_ptr()
+}
+
+#[no_mangle]
+pub extern fn engine_db_filebundle_main(this: &mut FileBundle) -> *const c_char {
+ this.main_c = CString::new(this.main()).unwrap();
+ this.main_c.as_ptr()
+}
+
+#[no_mangle]
+pub extern fn engine_db_filebundle_jpeg(this: &mut FileBundle) -> *const c_char {
+ this.jpeg_c = CString::new(this.jpeg()).unwrap();
+ this.jpeg_c.as_ptr()
+}
+
+#[no_mangle]
+pub extern fn engine_db_filebundle_add(this: &mut FileBundle, f: *const c_char) -> c_char {
+ this.add(&*unsafe { CStr::from_ptr(f) }.to_string_lossy()) as c_char
+}
diff --git a/src/engine/db/library.cpp b/src/engine/db/library.cpp
index 32014ae..8e6803f 100644
--- a/src/engine/db/library.cpp
+++ b/src/engine/db/library.cpp
@@ -351,24 +351,24 @@ library_id_t Library::addFileAndFolder(const std::string & folder,
}
library_id_t Library::addBundle(library_id_t folder_id,
- const eng::FileBundle::Ptr & bundle,
+ const eng::FileBundlePtr & bundle,
Managed manage)
{
library_id_t file_id = 0;
- file_id = addFile(folder_id, bundle->main_file(), manage);
+ file_id = addFile(folder_id, engine_db_filebundle_main(bundle.get()), manage);
if(file_id > 0) {
library_id_t fsfile_id;
bool success;
// addXmpSidecar
- if(!bundle->sidecar().empty()) {
- fsfile_id = addFsFile(bundle->sidecar());
+ if(engine_db_filebundle_sidecar(bundle.get())[0] == 0) {
+ fsfile_id = addFsFile(engine_db_filebundle_sidecar(bundle.get()));
if(fsfile_id > 0) {
success = addSidecarFileToBundle(file_id, fsfile_id);
}
}
// addJpeg
- if(!bundle->jpeg().empty()) {
- fsfile_id = addFsFile(bundle->jpeg());
+ if(engine_db_filebundle_jpeg(bundle.get())[0] == 0) {
+ fsfile_id = addFsFile(engine_db_filebundle_jpeg(bundle.get()));
if(fsfile_id > 0) {
success = addJpegFileToBundle(file_id, fsfile_id);
}
diff --git a/src/engine/db/library.hpp b/src/engine/db/library.hpp
index 5d91341..e551ea4 100644
--- a/src/engine/db/library.hpp
+++ b/src/engine/db/library.hpp
@@ -110,7 +110,7 @@ public:
* @param manage pass Managed::YES if the library *manage* the file. Currently unsupported.
*/
library_id_t addBundle(library_id_t folder_id,
- const eng::FileBundle::Ptr & bundle,
+ const eng::FileBundlePtr& bundle,
Managed manage);
/** add a sidecar fsfile to a bundle (file)
* @param file_id the id of the file bundle
diff --git a/src/engine/db/mod.rs b/src/engine/db/mod.rs
index 775b144..ecf0e78 100644
--- a/src/engine/db/mod.rs
+++ b/src/engine/db/mod.rs
@@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+pub mod filebundle;
pub mod fsfile;
pub mod keyword;
pub mod libfile;
diff --git a/src/engine/db/test_filebundle.cpp b/src/engine/db/test_filebundle.cpp
index 3cb17ab..91c68ce 100644
--- a/src/engine/db/test_filebundle.cpp
+++ b/src/engine/db/test_filebundle.cpp
@@ -43,21 +43,23 @@ int test_main(int, char *[])
// thelist->push_back("/tmp/some/file");
- eng::FileBundle::ListPtr bundles_list =
- eng::FileBundle::filter_bundles(thelist);
+ eng::FileBundleListPtr bundles_list =
+ eng::filebundle_filter_bundles(thelist);
+ std::cout << "list size " << bundles_list->size() << std::endl;
BOOST_CHECK(bundles_list->size() == 2);
auto iter = bundles_list->begin();
auto b = *iter;
- BOOST_CHECK(b->main_file() == "/foo/bar/dcs_0001.nef");
- BOOST_CHECK(b->jpeg() == "/foo/bar/dcs_0001.jpg");
- BOOST_CHECK(b->sidecar() == "/foo/bar/dcs_0001.xmp");
+ BOOST_CHECK(std::string(engine_db_filebundle_main(b.get())) == "/foo/bar/dcs_0001.nef");
+ printf("jpeg %s\n", engine_db_filebundle_jpeg(b.get()));
+ BOOST_CHECK(std::string(engine_db_filebundle_jpeg(b.get())) == "/foo/bar/dcs_0001.jpg");
+ BOOST_CHECK(std::string(engine_db_filebundle_sidecar(b.get())) == "/foo/bar/dcs_0001.xmp");
++iter;
b = *iter;
- BOOST_CHECK(b->main_file() == "/foo/bar/img_0001.cr2");
- BOOST_CHECK(b->jpeg() == "/foo/bar/img_0001.jpg");
- BOOST_CHECK(b->sidecar() == "/foo/bar/img_0001.xmp");
+ BOOST_CHECK(std::string(engine_db_filebundle_main(b.get())) == "/foo/bar/img_0001.cr2");
+ BOOST_CHECK(std::string(engine_db_filebundle_jpeg(b.get())) == "/foo/bar/img_0001.jpg");
+ BOOST_CHECK(std::string(engine_db_filebundle_sidecar(b.get())) == "/foo/bar/img_0001.xmp");
return 0;
}
diff --git a/src/engine/library/commands.cpp b/src/engine/library/commands.cpp
index 45bfb32..2a2c81d 100644
--- a/src/engine/library/commands.cpp
+++ b/src/engine/library/commands.cpp
@@ -62,8 +62,8 @@ void Commands::cmdImportFile(const Library::Ptr & lib,
DBG_ASSERT(manage == Library::Managed::NO,
"managing file is currently unsupported");
- FileBundle::Ptr bundle(new FileBundle);
- bundle->add(file_path);
+ FileBundlePtr bundle(filebundle_new());
+ engine_db_filebundle_add(bundle.get(), file_path.c_str());
std::string folder = fwk::path_dirname(file_path);
@@ -85,12 +85,12 @@ void Commands::cmdImportFiles(const Library::Ptr & lib,
DBG_ASSERT(manage == Library::Managed::NO,
"managing file is currently unsupported");
- FileBundle::ListPtr bundles = FileBundle::filter_bundles(files);
+ FileBundleListPtr bundles = filebundle_filter_bundles(files);
LibFolderPtr pf = lib->getFolder(folder);
if(!pf) {
pf = lib->addFolder(folder);
- LibFolderListPtr l( new LibFolderList );
+ LibFolderListPtr l(new LibFolderList);
l->push_back(pf);
lib->notify(LibNotification::make<LibNotification::Type::ADDED_FOLDERS>({l}));
}
diff --git a/src/fwk/mod.rs b/src/fwk/mod.rs
index be8726c..ebd81d5 100644
--- a/src/fwk/mod.rs
+++ b/src/fwk/mod.rs
@@ -19,6 +19,7 @@
pub mod utils;
pub mod base;
+pub mod toolkit;
pub use self::utils::exempi::{
NsDef,
@@ -31,6 +32,9 @@ pub use self::base::fractions::{
fraction_to_decimal
};
+pub use self::toolkit::mimetype::{
+ MimeType
+};
use std::f64;
use std::ffi::CStr;
diff --git a/src/fwk/toolkit/mimetype.cpp b/src/fwk/toolkit/mimetype.cpp
index 84d1fe3..744492f 100644
--- a/src/fwk/toolkit/mimetype.cpp
+++ b/src/fwk/toolkit/mimetype.cpp
@@ -28,18 +28,23 @@
namespace fwk {
+MimeType::MimeType(const char* filename)
+ : MimeType(std::string(filename))
+{
+}
+
MimeType::MimeType(const std::string & filename)
: m_name(filename)
{
try {
Glib::RefPtr<Gio::File> file = Gio::File::create_for_path(filename);
- m_fileinfo = file->query_info();
- m_type = m_fileinfo->get_content_type();
+ auto fileinfo = file->query_info();
+ m_type = fileinfo->get_content_type();
}
catch(const Glib::Exception &e) {
gboolean uncertainty = false;
gchar *content_type = g_content_type_guess(filename.c_str(),
- nullptr, 0, &uncertainty);
+ nullptr, 0, &uncertainty);
m_type = content_type;
g_free(content_type);
@@ -49,14 +54,14 @@ MimeType::MimeType(const std::string & filename)
MimeType::MimeType(const Glib::RefPtr<Gio::File> & file)
{
DBG_ASSERT(static_cast<bool>(file), "file can't be NULL");
- m_fileinfo = file->query_info();
- m_name = m_fileinfo->get_name();
- m_type = m_fileinfo->get_content_type();
+ auto fileinfo = file->query_info();
+ m_name = fileinfo->get_name();
+ m_type = fileinfo->get_content_type();
}
bool MimeType::isDigicamRaw() const
{
- return Gio::content_type_is_a(m_type, "image/x-dcraw");
+ return Gio::content_type_is_a(m_type, "image/x-dcraw");
}
@@ -68,7 +73,7 @@ bool MimeType::isImage() const
bool MimeType::isMovie() const
{
return Gio::content_type_is_a(m_type, "video/*");
-}
+}
bool MimeType::isUnknown() const
{
@@ -80,7 +85,12 @@ bool MimeType::isXmp() const
{
return fwk::path_extension(m_name) == ".xmp";
}
-
+
+const std::string & MimeType::string() const
+{
+ return m_type;
+}
+
}
/*
diff --git a/src/fwk/toolkit/mimetype.hpp b/src/fwk/toolkit/mimetype.hpp
index 2eef9ca..6f815bf 100644
--- a/src/fwk/toolkit/mimetype.hpp
+++ b/src/fwk/toolkit/mimetype.hpp
@@ -24,26 +24,26 @@
#include <string>
#include <giomm/file.h>
-#include <giomm/fileinfo.h>
namespace fwk {
class MimeType
{
public:
+ MimeType(const char* filename);
MimeType(const std::string & filename);
MimeType(const Glib::RefPtr<Gio::File> & file);
-
+
+ ~MimeType() {}
+
bool isDigicamRaw() const;
bool isImage() const;
bool isMovie() const;
bool isUnknown() const;
bool isXmp() const;
-
- const std::string & string() const
- { return m_type; }
+
+ const std::string& string() const;
private:
- Glib::RefPtr<Gio::FileInfo> m_fileinfo;
std::string m_name;
std::string m_type;
};
diff --git a/src/fwk/toolkit/mimetype.rs b/src/fwk/toolkit/mimetype.rs
new file mode 100644
index 0000000..0399cda
--- /dev/null
+++ b/src/fwk/toolkit/mimetype.rs
@@ -0,0 +1,120 @@
+
+use gio;
+use glib_sys;
+use glib_sys::gboolean;
+use gio_sys;
+use gio::prelude::*;
+
+use libc::c_void;
+use std::ffi::CStr;
+use std::ffi::CString;
+use std::ptr;
+use std::path::Path;
+
+#[derive(PartialEq, Debug)]
+pub enum IsRaw {
+ No,
+ Yes
+}
+
+#[derive(PartialEq, Debug)]
+pub enum MType {
+ None,
+ Image(IsRaw),
+ Movie,
+ Xmp
+}
+
+pub struct MimeType {
+// name: String,
+ mtype: MType,
+}
+
+fn guess_type(gmtype: &str) -> MType {
+ if gio::content_type_is_a(&gmtype, "image/*") {
+ if gio::content_type_is_a(&gmtype, "image/x-dcraw") {
+ return MType::Image(IsRaw::Yes);
+ }
+ return MType::Image(IsRaw::No);
+ } else if gio::content_type_is_a(&gmtype, "video/*") {
+ return MType::Movie;
+ }
+ MType::None
+}
+
+fn guess_type_for_file(filename: &str) -> MType {
+ let path = Path::new(filename);
+ let file = gio::File::new_for_path(path);
+ if let Ok(fileinfo) = file.query_info("*", gio::FILE_QUERY_INFO_NONE, None) {
+ if let Some(gmtype) = fileinfo.get_content_type() {
+ let t = guess_type_for_file(&gmtype);
+ if t != MType::None {
+ return t;
+ }
+ }
+ }
+ if let Some(ext) = path.extension() {
+ if let Some(sext) = ext.to_str() {
+ if sext == "xmp" {
+ return MType::Xmp;
+ }
+ }
+ }
+ // alternative
+ let mut uncertainty: gboolean = 0;
+ let content_type = unsafe {
+ gio_sys::g_content_type_guess(CString::new(filename).unwrap().as_ptr(),
+ ptr::null_mut(), 0, &mut uncertainty)
+ };
+ let content_type_real = unsafe { CStr::from_ptr(content_type) };
+ let t = guess_type(&*content_type_real.to_string_lossy());
+ unsafe {
+ glib_sys::g_free(content_type as *mut c_void)
+ };
+
+ t
+}
+
+impl MimeType {
+
+ pub fn new(filename: &str) -> MimeType {
+ MimeType {
+// name: String::from(filename),
+ mtype: guess_type_for_file(filename),
+ }
+ }
+
+ pub fn is_image(&self) -> bool {
+ if let MType::Image(_) = self.mtype {
+ true
+ } else {
+ false
+ }
+ }
+
+ pub fn is_digicam_raw(&self) -> bool {
+ if let MType::Image(ref b) = self.mtype {
+ return *b == IsRaw::Yes;
+ }
+ false
+ }
+
+ pub fn is_xmp(&self) -> bool {
+ self.mtype == MType::Xmp
+ }
+
+ pub fn is_movie(&self) -> bool {
+ self.mtype == MType::Movie
+ }
+}
+
+
+#[cfg(test)]
+#[test]
+fn mime_type_works() {
+
+ let mimetype = MimeType::new("/foo/bar/img_0001.cr2");
+ assert_eq!(guess_type_for_file("/foo/bar/img_0001.cr2"), MType::Image(IsRaw::Yes));
+ assert!(mimetype.is_image());
+ assert!(mimetype.is_digicam_raw());
+}
diff --git a/src/fwk/toolkit/mod.rs b/src/fwk/toolkit/mod.rs
new file mode 100644
index 0000000..75a93b8
--- /dev/null
+++ b/src/fwk/toolkit/mod.rs
@@ -0,0 +1,2 @@
+
+pub mod mimetype;
diff --git a/src/lib.rs b/src/lib.rs
index f511f12..f213538 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,6 +19,9 @@
extern crate exempi;
extern crate libc;
+extern crate glib_sys;
+extern crate gio_sys;
+extern crate gio;
pub mod fwk;
pub mod engine;
diff --git a/src/libraryclient/Makefile.am b/src/libraryclient/Makefile.am
index 0b01907..44d23a6 100644
--- a/src/libraryclient/Makefile.am
+++ b/src/libraryclient/Makefile.am
@@ -12,7 +12,7 @@ TEST_LIBS = \
$(top_builddir)/src/fwk/utils/libniepceutils.a \
$(top_builddir)/src/fwk/toolkit/libniepceframework.a \
$(top_builddir)/src/fwk/base/libfwkbase.a \
- $(top_builddir)/target/debug/libniece_rust.a \
+ $(top_builddir)/target/debug/libniepce_rust.a \
@BOOST_UNIT_TEST_FRAMEWORK_LIBS@ \
@FRAMEWORK_LIBS@ \
@OPENRAW_LIBS@ \
diff --git a/src/niepce/Makefile.am b/src/niepce/Makefile.am
index b9cebaf..21db85b 100644
--- a/src/niepce/Makefile.am
+++ b/src/niepce/Makefile.am
@@ -21,7 +21,7 @@ niepce_LDADD = \
$(top_builddir)/src/fwk/base/libfwkbase.a \
$(top_builddir)/src/ncr/libncr.a \
$(top_builddir)/src/ext/libview/libview.a \
- $(top_builddir)/target/debug/libniece_rust.a \
+ $(top_builddir)/target/debug/libniepce_rust.a \
@FRAMEWORK_LIBS@ \
@GPHOTO_LIBS@ \
@BABL_LIBS@ \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]