[niepce] eng+rust: LibMetadata::to_properties now implemented in Rust
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] eng+rust: LibMetadata::to_properties now implemented in Rust
- Date: Thu, 28 Sep 2017 13:41:02 +0000 (UTC)
commit c200bbb47fd67b0ab7101babfdc4752c90f1c0c7
Author: Hubert Figuière <hub figuiere net>
Date: Sun Sep 24 19:36:41 2017 -0400
eng+rust: LibMetadata::to_properties now implemented in Rust
- PropertySet is now a Rust type
src/engine/db/libmetadata.cpp | 113 ++----------------------------
src/engine/db/libmetadata.hpp | 14 ++---
src/engine/db/libmetadata.rs | 98 ++++++++++++++++++++++++--
src/fwk/base/mod.rs | 18 +++++
src/fwk/base/propertybag.cpp | 10 +++
src/fwk/base/propertybag.hpp | 12 ++--
src/fwk/mod.rs | 1 +
src/niepce/modules/map/mapmodule.cpp | 9 ++-
src/niepce/ui/metadatapanecontroller.cpp | 18 +++---
src/niepce/ui/metadatapanecontroller.hpp | 2 +-
src/rust_bindings.hpp | 1 +
11 files changed, 152 insertions(+), 144 deletions(-)
---
diff --git a/src/engine/db/libmetadata.cpp b/src/engine/db/libmetadata.cpp
index 681cec4..f05efb8 100644
--- a/src/engine/db/libmetadata.cpp
+++ b/src/engine/db/libmetadata.cpp
@@ -61,122 +61,21 @@ IndexToXmp property_index_to_xmp(fwk::PropertyIndex index)
PropsToXmpMap::const_iterator iter = propmap.find(index);
if (iter == propmap.end()) {
// not found
- return {ns : nullptr, property : nullptr};
+ return {ns: nullptr, property: nullptr};
}
if (iter->second.first == NULL || iter->second.second == NULL) {
// no XMP equivalent
- return {ns : nullptr, property : nullptr};
+ return {ns: nullptr, property: nullptr};
}
- return {ns : iter->second.first, property : iter->second.second};
+ return {ns: iter->second.first, property: iter->second.second};
}
-bool get_meta_data(const LibMetadata *meta, fwk::PropertyIndex p,
- fwk::PropertyValuePtr &value)
+fwk::PropertyBagPtr libmetadata_to_properties(const LibMetadata* meta,
+ const fwk::PropertySet& propset)
{
- const PropsToXmpMap &propmap = props_to_xmp_map();
- PropsToXmpMap::const_iterator iter = propmap.find(p);
- if (iter == propmap.end()) {
- // not found
- return false;
- }
- if (iter->second.first == NULL || iter->second.second == NULL) {
- // no XMP equivalent
- return false;
- }
- xmp::ScopedPtr<XmpStringPtr> xmp_value(xmp_string_new());
- uint32_t prop_bits = 0;
- const char *ns = iter->second.first;
- const char *xmp_prop = iter->second.second;
- bool found = xmp_get_property(engine_libmetadata_get_xmp(meta), ns,
- xmp_prop, xmp_value, &prop_bits);
- if (found && XMP_IS_ARRAY_ALTTEXT(prop_bits)) {
- found = xmp_get_localized_text(engine_libmetadata_get_xmp(meta), ns,
- xmp_prop, "", "x-default", nullptr,
- xmp_value, nullptr);
- }
- if (found) {
- const char *v = NULL;
- v = xmp_string_cstr(xmp_value);
- if (v) {
- value = fwk::property_value_new(v);
- return true;
- }
- }
- // not found in XMP
- return false;
+ return fwk::property_bag_wrap(ffi::engine_libmetadata_to_properties(meta, &propset));
}
-void libmetadata_to_properties(const LibMetadata *meta,
- const fwk::PropertySet &propset,
- fwk::PropertyBagPtr &props)
-{
- if (!props) {
- props = fwk::property_bag_new();
- }
- std::for_each(
- propset.begin(), propset.end(),
- [&props, meta](fwk::PropertySet::key_type prop_id) {
- auto xmpmeta = engine_libmetadata_get_xmpmeta(meta);
- switch (prop_id) {
- case NpXmpRatingProp:
- fwk::set_value_for_property(
- *props, prop_id,
- *fwk::property_value_new(fwk_xmp_meta_get_rating(xmpmeta)));
- break;
- case NpXmpLabelProp: {
- char *str = fwk_xmp_meta_get_label(xmpmeta);
- if (str) {
- fwk::set_value_for_property(*props, prop_id,
- *fwk::property_value_new(str));
- rust_cstring_delete(str);
- } else {
- fwk::set_value_for_property(*props, prop_id,
- *fwk::property_value_new(""));
- }
- break;
- }
- case NpTiffOrientationProp:
- fwk::set_value_for_property(
- *props, prop_id,
- *fwk::property_value_new(fwk_xmp_meta_get_orientation(xmpmeta)));
- break;
- case NpExifDateTimeOriginalProp: {
- fwk::DatePtr date =
- fwk::date_wrap(fwk_xmp_meta_get_creation_date(xmpmeta));
- if (date) {
- fwk::set_value_for_property(*props, prop_id, *fwk::property_value_new(date));
- }
- break;
- }
- case NpIptcKeywordsProp: {
- xmp::ScopedPtr<XmpIteratorPtr> iter(
- xmp_iterator_new(engine_libmetadata_get_xmp(meta), NS_DC,
- "subject", XMP_ITER_JUSTLEAFNODES));
- std::vector<std::string> vec;
- xmp::ScopedPtr<XmpStringPtr> value(xmp_string_new());
- while (xmp_iterator_next(iter, NULL, NULL, value, NULL)) {
- vec.push_back(xmp_string_cstr(value));
- }
- fwk::PropertyValuePtr v = fwk::property_value_new(vec);
- // DBG_ASSERT(check_property_type(prop_id, v.type()), "wrong
- // type");
- fwk::set_value_for_property(*props, prop_id, *v);
- break;
- }
- default: {
- fwk::PropertyValuePtr propval;
- if (get_meta_data(meta, prop_id, propval)) {
- // DBG_ASSERT(check_property_type(prop_id, propval.type()),
- // "wrong type");
- fwk::set_value_for_property(*props, prop_id, *propval);
- } else {
- DBG_OUT("missing prop %u", prop_id);
- }
- break;
- }
- }
- });
-}
}
/*
diff --git a/src/engine/db/libmetadata.hpp b/src/engine/db/libmetadata.hpp
index fc32282..273a2d9 100644
--- a/src/engine/db/libmetadata.hpp
+++ b/src/engine/db/libmetadata.hpp
@@ -36,23 +36,19 @@ namespace eng {
class LibMetadata;
#endif
-void libmetadata_to_properties(const LibMetadata *meta,
- const fwk::PropertySet &propset,
- fwk::PropertyBagPtr &props);
-
struct IndexToXmp {
const char *ns;
const char *property;
};
IndexToXmp property_index_to_xmp(fwk::PropertyIndex index);
-}
-extern "C" {
-eng::library_id_t engine_libmetadata_get_id(const eng::LibMetadata *meta);
-XmpPtr engine_libmetadata_get_xmp(const eng::LibMetadata *meta);
-fwk::XmpMeta *engine_libmetadata_get_xmpmeta(const eng::LibMetadata *meta);
+
+fwk::PropertyBagPtr libmetadata_to_properties(const LibMetadata *meta,
+ const fwk::PropertySet &propset);
+
}
+
/*
Local Variables:
mode:c++
diff --git a/src/engine/db/libmetadata.rs b/src/engine/db/libmetadata.rs
index 846b6f0..f80b332 100644
--- a/src/engine/db/libmetadata.rs
+++ b/src/engine/db/libmetadata.rs
@@ -18,16 +18,19 @@
*/
use std::ffi::CStr;
+use std::mem::transmute;
use rusqlite;
use exempi;
use fwk;
use fwk::{
PropertyValue,
+ PropertyBag,
+ PropertySet,
XmpMeta,
make_xmp_date_time
};
-use fwk::utils::exempi::NS_XAP;
+use fwk::utils::exempi::{NS_XAP, NS_DC};
use super::{
FromDb,
LibraryId
@@ -56,7 +59,6 @@ fn property_index_to_xmp(meta: Np) -> Option<IndexToXmp> {
})
}
-
impl LibMetadata {
pub fn new(id: LibraryId) -> LibMetadata {
@@ -77,6 +79,32 @@ impl LibMetadata {
self.xmp.serialize_inline()
}
+ fn get_metadata(&self, meta: Np) -> Option<PropertyValue> {
+
+ let index_to_xmp = property_index_to_xmp(meta);
+ if index_to_xmp.is_none() {
+ return None;
+ }
+ let index_to_xmp = index_to_xmp.unwrap();
+
+ let mut prop_flags = exempi::PROP_NONE;
+ let mut xmp_result = self.xmp.xmp.get_property(&index_to_xmp.ns, &index_to_xmp.property,
+ &mut prop_flags);
+ if xmp_result.is_some() && prop_flags.contains(exempi::ARRAY_IS_ALTTEXT) {
+ let mut value = exempi::XmpString::new();
+ let mut actual_lang = exempi::XmpString::new();
+ if self.xmp.xmp.get_localized_text(&index_to_xmp.ns, &index_to_xmp.property, "",
+ "x-default", &mut actual_lang,
+ &mut value, &mut prop_flags) {
+ xmp_result = Some(value);
+ }
+ }
+ if xmp_result.is_some() {
+ return Some(PropertyValue::String(String::from(xmp_result.unwrap().to_str())));
+ }
+ None
+ }
+
pub fn set_metadata(&mut self, meta: Np, value: &PropertyValue) -> bool {
if let Some(ix) = property_index_to_xmp(meta) {
match value {
@@ -122,6 +150,53 @@ impl LibMetadata {
false
}
+ pub fn to_properties(&self, propset: &PropertySet) -> PropertyBag {
+ let mut props = PropertyBag::new();
+ for prop_id in propset {
+ let prop_id_np: Np = unsafe { transmute(*prop_id) };
+ match prop_id_np {
+ Np::NpXmpRatingProp =>
+ if let Some(rating) = self.xmp.rating() {
+ props.set_value(*prop_id, PropertyValue::Int(rating));
+ },
+ Np::NpXmpLabelProp =>
+ if let Some(label) = self.xmp.label() {
+ props.set_value(*prop_id, PropertyValue::String(label));
+ },
+ Np::NpTiffOrientationProp =>
+ if let Some(orientation) = self.xmp.orientation() {
+ props.set_value(*prop_id, PropertyValue::Int(orientation));
+ },
+ Np::NpExifDateTimeOriginalProp =>
+ if let Some(date) = self.xmp.creation_date() {
+ props.set_value(*prop_id, PropertyValue::Date(date));
+ },
+ Np::NpIptcKeywordsProp => {
+ let mut iter = exempi::XmpIterator::new(&self.xmp.xmp, NS_DC,
+ "subject",
+ exempi::ITER_JUST_LEAF_NODES);
+ let mut keywords: Vec<String> = vec!();
+ let mut schema = exempi::XmpString::new();
+ let mut name = exempi::XmpString::new();
+ let mut value = exempi::XmpString::new();
+ let mut flags = exempi::IterFlags::empty();
+ while iter.next(&mut schema, &mut name, &mut value, &mut flags) {
+ keywords.push(String::from(value.to_str()));
+ }
+ props.set_value(*prop_id, PropertyValue::StringArray(keywords));
+ },
+ _ => {
+ if let Some(propval) = self.get_metadata(prop_id_np) {
+ props.set_value(*prop_id, propval);
+ } else {
+ dbg_out!("missing prop {}", prop_id);
+ }
+ }
+ }
+ }
+ props
+ }
+
pub fn touch(&mut self) -> bool {
let mut xmpdate = exempi::DateTime::new();
if make_xmp_date_time(fwk::Date::now(), &mut xmpdate) {
@@ -154,16 +229,23 @@ impl FromDb for LibMetadata {
}
#[no_mangle]
-pub fn engine_libmetadata_get_id(meta: &LibMetadata) -> LibraryId {
- return meta.id;
+pub extern "C" fn engine_libmetadata_get_id(meta: &LibMetadata) -> LibraryId {
+ meta.id
+}
+
+#[no_mangle]
+pub extern "C" fn engine_libmetadata_get_xmp(meta: &LibMetadata) -> exempi::Xmp {
+ meta.xmp.xmp.clone()
}
#[no_mangle]
-pub fn engine_libmetadata_get_xmp(meta: &LibMetadata) -> exempi::Xmp {
- return meta.xmp.xmp.clone();
+pub extern "C" fn engine_libmetadata_get_xmpmeta(meta: &LibMetadata) -> *const XmpMeta {
+ &meta.xmp
}
#[no_mangle]
-pub fn engine_libmetadata_get_xmpmeta(meta: &LibMetadata) -> *const XmpMeta {
- return &meta.xmp;
+pub extern "C" fn engine_libmetadata_to_properties(meta: &LibMetadata, propset: &PropertySet)
+ -> *mut PropertyBag {
+ let result = Box::new(meta.to_properties(propset));
+ Box::into_raw(result)
}
diff --git a/src/fwk/base/mod.rs b/src/fwk/base/mod.rs
index 799a9dc..f845971 100644
--- a/src/fwk/base/mod.rs
+++ b/src/fwk/base/mod.rs
@@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+use std::collections::BTreeSet;
+
pub mod date;
#[macro_use]
pub mod debug;
@@ -26,3 +28,19 @@ pub mod propertyvalue;
pub mod rgbcolour;
pub type PropertyIndex = u32;
+pub type PropertySet = BTreeSet<PropertyIndex>;
+
+#[no_mangle]
+pub extern "C" fn fwk_property_set_new() -> *mut PropertySet {
+ Box::into_raw(Box::new(PropertySet::new()))
+}
+
+#[no_mangle]
+pub extern "C" fn fwk_property_set_delete(set: *mut PropertySet) {
+ unsafe { Box::from_raw(set); }
+}
+
+#[no_mangle]
+pub extern "C" fn fwk_property_set_add(set: &mut PropertySet, v: PropertyIndex) {
+ set.insert(v);
+}
diff --git a/src/fwk/base/propertybag.cpp b/src/fwk/base/propertybag.cpp
index 8574119..2e2e034 100644
--- a/src/fwk/base/propertybag.cpp
+++ b/src/fwk/base/propertybag.cpp
@@ -23,6 +23,16 @@
namespace fwk {
+PropertySetPtr property_set_wrap(PropertySet* s)
+{
+ return PropertySetPtr(s, &ffi::fwk_property_set_delete);
+}
+
+PropertySetPtr property_set_new()
+{
+ return property_set_wrap(ffi::fwk_property_set_new());
+}
+
PropertyValuePtr property_value_wrap(PropertyValue* v)
{
return PropertyValuePtr(v, &ffi::fwk_property_value_delete);
diff --git a/src/fwk/base/propertybag.hpp b/src/fwk/base/propertybag.hpp
index 6b355de..ac535f9 100644
--- a/src/fwk/base/propertybag.hpp
+++ b/src/fwk/base/propertybag.hpp
@@ -34,8 +34,6 @@ namespace fwk {
typedef uint32_t PropertyIndex;
-typedef std::set<PropertyIndex> PropertySet;
-
#if !RUST_BINDGEN
typedef std::shared_ptr<PropertyValue> PropertyValuePtr;
@@ -50,8 +48,13 @@ std::vector<std::string> property_value_get_string_array(const PropertyValue &va
#if RUST_BINDGEN
class PropertyBag;
+class PropertySet;
#endif
+typedef std::shared_ptr<PropertySet> PropertySetPtr;
+
+PropertySetPtr property_set_new();
+
/** a property bag
* It is important that the values for PropertyIndex be properly name spaced
* by the caller.
@@ -60,6 +63,7 @@ typedef std::shared_ptr<PropertyBag> PropertyBagPtr;
#if !RUST_BINDGEN
PropertyBagPtr property_bag_new();
+PropertyBagPtr property_bag_wrap(PropertyBag*);
PropertyValuePtr property_bag_value(const PropertyBagPtr& bag, PropertyIndex key);
@@ -69,10 +73,6 @@ std::string property_value_get_string(const PropertyValue& v);
bool set_value_for_property(PropertyBag&, PropertyIndex idx, const PropertyValue & value);
/** return property or an empty option */
fwk::Option<PropertyValuePtr> get_value_for_property(const PropertyBag&, PropertyIndex idx);
-/** return true if property exist */
-bool has_value_for_property(const PropertyBag&, PropertyIndex idx);
-/** return true if the property was removed */
-bool remove_value_for_property(PropertyBag&, PropertyIndex idx);
#endif
}
diff --git a/src/fwk/mod.rs b/src/fwk/mod.rs
index 9c5fe5d..581d3ed 100644
--- a/src/fwk/mod.rs
+++ b/src/fwk/mod.rs
@@ -30,6 +30,7 @@ pub use self::utils::exempi::{
};
pub use self::base::propertyvalue::PropertyValue;
pub use self::base::propertybag::PropertyBag;
+pub use self::base::PropertySet;
pub use self::base::fractions::{
fraction_to_decimal
};
diff --git a/src/niepce/modules/map/mapmodule.cpp b/src/niepce/modules/map/mapmodule.cpp
index 47847c0..a816268 100644
--- a/src/niepce/modules/map/mapmodule.cpp
+++ b/src/niepce/modules/map/mapmodule.cpp
@@ -78,10 +78,11 @@ MapModule::on_lib_notification(const eng::LibNotification &ln)
DBG_OUT("received metadata in MapModule");
if (lm) {
- fwk::PropertyBagPtr properties;
- const fwk::PropertySet propset = { eng::NpExifGpsLongProp,
- eng::NpExifGpsLatProp };
- eng::libmetadata_to_properties(lm, propset, properties);
+ fwk::PropertySetPtr propset = fwk::property_set_new();
+ ffi::fwk_property_set_add(propset.get(), eng::NpExifGpsLongProp);
+ ffi::fwk_property_set_add(propset.get(), eng::NpExifGpsLatProp);
+
+ fwk::PropertyBagPtr properties = eng::libmetadata_to_properties(lm, *propset);
double latitude, longitude;
latitude = longitude = NAN;
auto result = fwk::get_value_for_property(*properties, eng::NpExifGpsLongProp);
diff --git a/src/niepce/ui/metadatapanecontroller.cpp b/src/niepce/ui/metadatapanecontroller.cpp
index 6e25e9f..fb8fb5f 100644
--- a/src/niepce/ui/metadatapanecontroller.cpp
+++ b/src/niepce/ui/metadatapanecontroller.cpp
@@ -79,17 +79,18 @@ MetaDataPaneController::get_format()
return s_format;
}
-const fwk::PropertySet & MetaDataPaneController::get_property_set()
+const fwk::PropertySet* MetaDataPaneController::get_property_set()
{
- static fwk::PropertySet propset;
- if(propset.empty()) {
+ static fwk::PropertySet* propset = nullptr;
+ if(!propset) {
+ propset = ffi::fwk_property_set_new();
const fwk::MetaDataSectionFormat * formats = get_format();
-
+
const fwk::MetaDataSectionFormat * current = formats;
while(current->section) {
const fwk::MetaDataFormat * format = current->formats;
while(format && format->label) {
- propset.insert(format->id);
+ ffi::fwk_property_set_add(propset, format->id);
format++;
}
current++;
@@ -98,9 +99,8 @@ const fwk::PropertySet & MetaDataPaneController::get_property_set()
return propset;
}
-
MetaDataPaneController::MetaDataPaneController()
- : Dockable("Metadata", _("Image Properties"),
+ : Dockable("Metadata", _("Image Properties"),
"document-properties" /*, DockItem::DOCKED_STATE*/),
m_fileid(0)
{
@@ -149,8 +149,8 @@ void MetaDataPaneController::display(eng::library_id_t file_id, const eng::LibMe
DBG_OUT("displaying metadata");
fwk::PropertyBagPtr properties;
if(meta) {
- const fwk::PropertySet & propset = get_property_set();
- eng::libmetadata_to_properties(meta, propset, properties);
+ const fwk::PropertySet* propset = get_property_set();
+ properties = eng::libmetadata_to_properties(meta, *propset);
}
std::for_each(m_widgets.begin(), m_widgets.end(),
[properties] (auto w) {
diff --git a/src/niepce/ui/metadatapanecontroller.hpp b/src/niepce/ui/metadatapanecontroller.hpp
index 2a6145a..03d0e44 100644
--- a/src/niepce/ui/metadatapanecontroller.hpp
+++ b/src/niepce/ui/metadatapanecontroller.hpp
@@ -56,7 +56,7 @@ private:
std::vector<fwk::MetaDataWidget *> m_widgets;
static const fwk::MetaDataSectionFormat * get_format();
- static const fwk::PropertySet & get_property_set();
+ static const fwk::PropertySet* get_property_set();
eng::library_id_t m_fileid;
};
diff --git a/src/rust_bindings.hpp b/src/rust_bindings.hpp
index f68c5b2..fc3f95e 100644
--- a/src/rust_bindings.hpp
+++ b/src/rust_bindings.hpp
@@ -33,6 +33,7 @@ namespace fwk {
typedef ffi::PropertyValue PropertyValue;
typedef ffi::PropertyBag PropertyBag;
+typedef ffi::PropertySet PropertySet;
typedef ffi::Date Date;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]