diff --git a/exif/exif.h b/exif/exif.h index fdd7053..0d0d706 100644 --- a/exif/exif.h +++ b/exif/exif.h @@ -75,6 +75,7 @@ EXIF_API void exif_data_ref_sort_by_key(ExifDataRef* d); EXIF_API void exif_data_ref_sort_by_tag(ExifDataRef* d); EXIF_API ExifDataItor* exif_data_ref_iter(ExifDataRef* d); EXIF_API ExifDatumRef* exif_data_itor_next(ExifDataItor* itor); +EXIF_API ExifDatumRef* exif_data_itor_next_back(ExifDataItor* itor); EXIF_API char* exif_datum_key(ExifDatumRef* d); EXIF_API ExifValueRef* exif_datum_value(ExifDatumRef *d); EXIF_API void exif_free_value(ExifValue* value); diff --git a/exif/src/exif.cpp b/exif/src/exif.cpp index 5cabeae..9de3513 100644 --- a/exif/src/exif.cpp +++ b/exif/src/exif.cpp @@ -358,7 +358,6 @@ ExifDataItor* exif_data_ref_iter(ExifDataRef* d) { auto re = new ExifDataItor; re->ref = (Exiv2::ExifData*)d; re->itor = re->ref->begin(); - re->begin = re->ref->begin(); re->end = re->ref->end(); return re; } @@ -376,6 +375,14 @@ ExifDatumRef* exif_data_itor_next(ExifDataItor* itor) { return (ExifDatumRef*)&data; } +ExifDatumRef* exif_data_itor_next_back(ExifDataItor* itor) { + if (!itor->ref) return nullptr; + if (itor->itor == itor->end) return nullptr; + itor->end--; + auto& data = (*itor->end); + return (ExifDatumRef*)&data; +} + char* exif_datum_key(ExifDatumRef* d) { if (!d) return nullptr; auto data = (Exiv2::Exifdatum*)d; diff --git a/exif/src/exif_priv.h b/exif/src/exif_priv.h index 76f5205..cea32d7 100644 --- a/exif/src/exif_priv.h +++ b/exif/src/exif_priv.h @@ -19,7 +19,6 @@ typedef struct ExifDatum { } ExifDatum; typedef struct ExifDataItor { Exiv2::ExifData* ref; - Exiv2::ExifMetadata::const_iterator begin; Exiv2::ExifMetadata::const_iterator itor; Exiv2::ExifMetadata::const_iterator end; } ExifDataItor; diff --git a/src/exif.rs b/src/exif.rs index cf46e7d..248c057 100644 --- a/src/exif.rs +++ b/src/exif.rs @@ -16,7 +16,7 @@ use std::ffi::OsStr; use std::fs::copy; #[cfg(test)] use std::fs::create_dir; -use std::iter::Iterator; +use std::iter::{DoubleEndedIterator, Iterator}; use std::marker::PhantomData; use std::ops::Deref; use std::ops::DerefMut; @@ -829,6 +829,19 @@ impl<'a> Iterator for ExifDataItor<'a> { } } +impl<'a> DoubleEndedIterator for ExifDataItor<'a> { + fn next_back(&mut self) -> Option { + if self.itor.is_null() { + return None; + } + let r = unsafe { _exif::exif_data_itor_next_back(self.itor) }; + if r.is_null() { + return None; + } + Some(unsafe { ExifDatumRef::from_const_handle(r as *const ExifDatumRef) }) + } +} + /// An image pub struct ExifImage { img: *mut _exif::ExifImage, @@ -1057,6 +1070,16 @@ fn test_exif_data() { let f2 = i.next().unwrap(); assert_eq!(f.key(), Some(String::from("Exif.Image.XPTitle"))); assert_eq!(f2.key(), Some(String::from("Exif.Image.PageName"))); + let mut i = d.iter().unwrap(); + assert_eq!( + i.next_back().unwrap().key(), + Some(String::from("Exif.Image.PageName")) + ); + assert_eq!( + i.next().unwrap().key(), + Some(String::from("Exif.Image.XPTitle")) + ); + assert!(i.next().is_none()); } #[test]