add DepIterator to list dependencies of package versions

Mostly the same boilerplate as the other iterators, but with a special
SinglePkgView type introduced to allow direct access to the nested
PkgIterator returned from target_pkg.
This commit is contained in:
Stefan Reiter 2020-10-20 16:07:24 +02:00 committed by Chris West (Faux)
parent 7b2d146e8d
commit edc7008762
3 changed files with 182 additions and 0 deletions

View File

@ -41,6 +41,17 @@ struct PVerIterator {
PCache *cache;
};
struct PDepIterator {
// Owned by us.
pkgCache::DepIterator iterator;
// Borrowed from PCache.
pkgCache::VerIterator *ver;
// Borrow of "static" PCache.
PCache *cache;
};
struct PVerFileIterator {
// Owned by us.
pkgCache::VerFileIterator iterator;
@ -103,6 +114,20 @@ extern "C" {
int32_t ver_iter_priority(PVerIterator *iterator);
#endif
// dep_iter creation and deletion
PDepIterator *ver_iter_dep_iter(PVerIterator *iterator);
void dep_iter_release(PDepIterator *iterator);
// dep_iter mutation
void dep_iter_next(PDepIterator *iterator);
bool dep_iter_end(PDepIterator *iterator);
// dep_iter access
PPkgIterator *dep_iter_target_pkg(PDepIterator *iterator);
const char *dep_iter_target_ver(PDepIterator *iterator);
const char *dep_iter_comp_type(PDepIterator *iterator);
const char *dep_iter_dep_type(PDepIterator *iterator);
// ver_file_iter creation and deletion
PVerFileIterator *ver_iter_ver_file_iter(PVerIterator *iterator);
void ver_file_iter_release(PVerFileIterator *iterator);
@ -283,6 +308,45 @@ const char *ver_iter_arch(PVerIterator *wrapper) {
}
PDepIterator *ver_iter_dep_iter(PVerIterator *wrapper) {
PDepIterator *new_wrapper = new PDepIterator();
new_wrapper->iterator = wrapper->iterator.DependsList();
new_wrapper->cache = wrapper->cache;
return new_wrapper;
}
void dep_iter_release(PDepIterator *wrapper) {
delete wrapper;
}
void dep_iter_next(PDepIterator *wrapper) {
++wrapper->iterator;
}
bool dep_iter_end(PDepIterator *wrapper) {
return wrapper->iterator.end();
}
PPkgIterator *dep_iter_target_pkg(PDepIterator *wrapper) {
PPkgIterator *new_wrapper = new PPkgIterator();
new_wrapper->iterator = wrapper->iterator.TargetPkg();
new_wrapper->cache = wrapper->cache;
return new_wrapper;
}
const char *dep_iter_target_ver(PDepIterator *wrapper) {
return wrapper->iterator.TargetVer();
}
const char *dep_iter_comp_type(PDepIterator *wrapper) {
return wrapper->iterator.CompType();
}
const char *dep_iter_dep_type(PDepIterator *wrapper) {
return wrapper->iterator.DepType();
}
PVerFileIterator *ver_iter_ver_file_iter(PVerIterator *wrapper) {
PVerFileIterator *new_wrapper = new PVerFileIterator();
new_wrapper->iterator = wrapper->iterator.FileList();

View File

@ -11,6 +11,7 @@ use libc::c_void;
pub type PCache = *mut c_void;
pub type PPkgIterator = *mut c_void;
pub type PVerIterator = *mut c_void;
pub type PDepIterator = *mut c_void;
pub type PVerFileIterator = *mut c_void;
pub type PPkgFileIterator = *mut c_void;
pub type PVerFileParser = *mut c_void;
@ -78,6 +79,23 @@ extern "C" {
#[cfg(not(feature = "ye-olde-apt"))]
pub fn ver_iter_priority(iterator: PVerIterator) -> i32;
// Dependency iterators
// ====================
pub fn ver_iter_dep_iter(iterator: PVerIterator) -> PDepIterator;
pub fn dep_iter_release(iterator: PDepIterator);
pub fn dep_iter_next(iterator: PDepIterator);
pub fn dep_iter_end(iterator: PDepIterator) -> bool;
// Dependency accessors
// ====================
pub fn dep_iter_target_pkg(iterator: PDepIterator) -> PPkgIterator;
pub fn dep_iter_target_ver(iterator: PDepIterator) -> *const c_char;
pub fn dep_iter_comp_type(iterator: PDepIterator) -> *const c_char;
pub fn dep_iter_dep_type(iterator: PDepIterator) -> *const c_char;
pub fn ver_iter_ver_file_iter(iterator: PVerIterator) -> PVerFileIterator;
pub fn ver_file_iter_release(iterator: PVerFileIterator);

View File

@ -181,6 +181,26 @@ impl<'c> PkgView<'c> {
}
}
/// Represents a single PkgView without associated PkgIterator. Derefs to
/// regular PkgView and releases the internal iterator on drop.
pub struct SinglePkgView<'c> {
view: PkgView<'c>,
}
impl<'c> std::ops::Deref for SinglePkgView<'c> {
type Target = PkgView<'c>;
fn deref(&self) -> &Self::Target {
&self.view
}
}
impl<'c> Drop for SinglePkgView<'c> {
fn drop(&mut self) {
unsafe { raw::pkg_iter_release(self.view.ptr); }
}
}
/// An "iterator"/pointer to a point in a version list.
pub struct VerIterator<'c> {
cache: PhantomData<&'c MutexGuard<'c, raw::CacheHolder>>,
@ -271,6 +291,86 @@ impl<'c> VerView<'c> {
},
}
}
pub fn dep_iter(&self) -> CIterator<DepIterator> {
CIterator {
first: true,
raw: DepIterator {
cache: PhantomData,
ptr: unsafe { raw::ver_iter_dep_iter(self.ptr) },
},
}
}
}
/// An "iterator"/pointer to a point in a dependency list.
pub struct DepIterator<'c> {
cache: PhantomData<&'c MutexGuard<'c, raw::CacheHolder>>,
ptr: raw::PDepIterator,
}
pub struct DepView<'c> {
cache: PhantomData<&'c MutexGuard<'c, raw::CacheHolder>>,
ptr: raw::PDepIterator,
}
impl<'c> RawIterator for DepIterator<'c> {
type View = DepView<'c>;
fn is_end(&self) -> bool {
unsafe { raw::dep_iter_end(self.ptr) }
}
fn next(&mut self) {
unsafe { raw::dep_iter_next(self.ptr) }
}
fn as_view(&self) -> Self::View {
assert!(!self.is_end());
DepView {
ptr: self.ptr,
cache: self.cache,
}
}
fn release(&mut self) {
unsafe { raw::dep_iter_release(self.ptr) }
}
}
/// Actual accessors
impl<'c> DepView<'c> {
pub fn target_pkg(&self) -> SinglePkgView {
let ptr = unsafe { raw::dep_iter_target_pkg(self.ptr) };
SinglePkgView {
view: PkgView {
cache: self.cache,
ptr,
}
}
}
pub fn target_ver(&self) -> String {
unsafe {
make_owned_ascii_string(raw::dep_iter_target_ver(self.ptr))
.expect("dependency always has target version")
}
}
pub fn comp_type(&self) -> String {
unsafe {
make_owned_ascii_string(raw::dep_iter_comp_type(self.ptr))
.expect("dependency always has comp type")
}
}
pub fn dep_type(&self) -> String {
unsafe {
make_owned_ascii_string(raw::dep_iter_dep_type(self.ptr))
.expect("dependency always has dep type")
}
}
}
/// An "iterator"/pointer to a point in a version's file list(?).