Introduce CxxGObjectArray, use in lockfile code
cxx-rs only supports a few basic types in `Vec<T>`/`CxxVector<T>` and we need to pass an array of GObjects in a few cases. Add a wrapper class hack instead of using `u64` so we at least have some basic safety here and have a convenient place to grep for later when we want to improve this.
This commit is contained in:
parent
5c1911445c
commit
60e605b34e
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -676,6 +676,7 @@ dependencies = [
|
||||
"cmake",
|
||||
"cxx",
|
||||
"cxx-build",
|
||||
"glib",
|
||||
"system-deps 3.0.0",
|
||||
]
|
||||
|
||||
@ -1236,6 +1237,7 @@ dependencies = [
|
||||
"gio-sys",
|
||||
"glib",
|
||||
"glib-sys",
|
||||
"gobject-sys",
|
||||
"indicatif",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
|
@ -34,6 +34,7 @@ cxx = "1.0.32"
|
||||
envsubst = "0.2.0"
|
||||
gio = "0.9.1"
|
||||
gio-sys = "0.10.1"
|
||||
gobject-sys = "0.10.0"
|
||||
glib = "0.10.3"
|
||||
glib-sys = "0.10.1"
|
||||
indicatif = "0.15.0"
|
||||
|
@ -7,6 +7,7 @@ links = "dnf"
|
||||
|
||||
[dependencies]
|
||||
cxx = "1.0.32"
|
||||
glib = "0.10.3"
|
||||
|
||||
[lib]
|
||||
name = "libdnf_sys"
|
||||
|
@ -80,7 +80,7 @@ macro_rules! cxxrs_bind {
|
||||
paste! {
|
||||
$(
|
||||
#[repr(transparent)]
|
||||
pub struct [<FFI $ns $i>]($sys::[<$ns $i>]);
|
||||
pub struct [<FFI $ns $i>](pub(crate) $sys::[<$ns $i>]);
|
||||
|
||||
unsafe impl ExternType for [<FFI $ns $i>] {
|
||||
type Id = type_id!(rpmostreecxx::[<$ns $i>]);
|
||||
@ -96,6 +96,7 @@ macro_rules! cxxrs_bind {
|
||||
// This macro is special to ostree types currently.
|
||||
cxxrs_bind!(Ostree, ostree, ostree_sys, [Sysroot, Repo, Deployment]);
|
||||
cxxrs_bind!(G, gio, gio_sys, [Cancellable]);
|
||||
cxxrs_bind!(G, glib, gobject_sys, [Object]);
|
||||
cxxrs_bind!(G, glib, glib_sys, [VariantDict]);
|
||||
|
||||
// An error type helper; separate from the GObject bridging
|
||||
|
@ -35,6 +35,7 @@ pub mod ffi {
|
||||
#[allow(dead_code)]
|
||||
type OstreeRepo = crate::FFIOstreeRepo;
|
||||
type OstreeDeployment = crate::FFIOstreeDeployment;
|
||||
type GObject = crate::FFIGObject;
|
||||
type GCancellable = crate::FFIGCancellable;
|
||||
type GVariantDict = crate::FFIGVariantDict;
|
||||
|
||||
@ -258,8 +259,8 @@ pub mod ffi {
|
||||
fn ror_lockfile_read(filenames: &Vec<String>) -> Result<Vec<StringMapping>>;
|
||||
fn ror_lockfile_write(
|
||||
filename: &str,
|
||||
packages: Vec<u64>,
|
||||
rpmmd_repos: Vec<u64>,
|
||||
packages: Pin<&mut CxxGObjectArray>,
|
||||
rpmmd_repos: Pin<&mut CxxGObjectArray>,
|
||||
) -> Result<()>;
|
||||
}
|
||||
|
||||
@ -268,6 +269,13 @@ pub mod ffi {
|
||||
fn cache_branch_to_nevra(nevra: &str) -> String;
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
include!("rpmostree-cxxrsutil.hpp");
|
||||
type CxxGObjectArray;
|
||||
fn length(self: Pin<&mut CxxGObjectArray>) -> u32;
|
||||
fn get(self: Pin<&mut CxxGObjectArray>, i: u32) -> &mut GObject;
|
||||
}
|
||||
|
||||
unsafe extern "C++" {
|
||||
include!("rpmostree-util.h");
|
||||
// Currently only used in unit tests
|
||||
|
@ -21,6 +21,7 @@ use std::convert::TryInto;
|
||||
use std::io;
|
||||
use std::iter::Extend;
|
||||
use std::path::Path;
|
||||
use std::pin::Pin;
|
||||
|
||||
/// Given a lockfile filename, parse it
|
||||
fn lockfile_parse<P: AsRef<Path>>(filename: P) -> Result<LockfileConfig> {
|
||||
@ -208,8 +209,8 @@ pub(crate) fn ror_lockfile_read(filenames: &Vec<String>) -> CxxResult<Vec<String
|
||||
|
||||
pub(crate) fn ror_lockfile_write(
|
||||
filename: &str,
|
||||
packages: Vec<u64>,
|
||||
rpmmd_repos: Vec<u64>,
|
||||
mut packages: Pin<&mut crate::ffi::CxxGObjectArray>,
|
||||
mut rpmmd_repos: Pin<&mut crate::ffi::CxxGObjectArray>,
|
||||
) -> CxxResult<()> {
|
||||
// get current time, but scrub nanoseconds; it's overkill to serialize that
|
||||
let now = {
|
||||
@ -225,8 +226,9 @@ pub(crate) fn ror_lockfile_write(
|
||||
}),
|
||||
};
|
||||
|
||||
for pkg in packages {
|
||||
let pkg_ref = unsafe { &mut *(pkg as *mut libdnf_sys::DnfPackage) };
|
||||
for i in 0..(packages.as_mut().length()) {
|
||||
let pkg = packages.as_mut().get(i);
|
||||
let pkg_ref = unsafe { &mut *(&mut pkg.0 as *mut _ as *mut libdnf_sys::DnfPackage) };
|
||||
let name = dnf_package_get_name(pkg_ref).unwrap();
|
||||
let evr = dnf_package_get_evr(pkg_ref).unwrap();
|
||||
let arch = dnf_package_get_arch(pkg_ref).unwrap();
|
||||
@ -250,8 +252,9 @@ pub(crate) fn ror_lockfile_write(
|
||||
.as_mut()
|
||||
.unwrap();
|
||||
|
||||
for rpmmd_repo in rpmmd_repos {
|
||||
let repo_ref = unsafe { &mut *(rpmmd_repo as *mut libdnf_sys::DnfRepo) };
|
||||
for i in 0..rpmmd_repos.as_mut().length() {
|
||||
let repo_ref = rpmmd_repos.as_mut().get(i);
|
||||
let repo_ref = unsafe { &mut *(&mut repo_ref.0 as *mut _ as *mut libdnf_sys::DnfRepo) };
|
||||
let id = dnf_repo_get_id(repo_ref).unwrap();
|
||||
let generated = dnf_repo_get_timestamp_generated(repo_ref).unwrap();
|
||||
let generated: i64 = match generated.try_into() {
|
||||
|
@ -382,12 +382,8 @@ install_packages (RpmOstreeTreeComposeContext *self,
|
||||
g_autoptr(GPtrArray) rpmmd_repos =
|
||||
rpmostree_get_enabled_rpmmd_repos (rpmostree_context_get_dnf (self->corectx),
|
||||
DNF_REPO_ENABLED_PACKAGES);
|
||||
auto pkgs_v = rust::Vec<guint64>();
|
||||
for (guint i = 0; i < pkgs->len; i++)
|
||||
pkgs_v.push_back((guint64)pkgs->pdata[i]);
|
||||
auto repos_v = rust::Vec<guint64>();
|
||||
for (guint i = 0; i < rpmmd_repos->len; i++)
|
||||
repos_v.push_back((guint64)rpmmd_repos->pdata[i]);
|
||||
auto pkgs_v = rpmostreecxx::CxxGObjectArray(pkgs);
|
||||
auto repos_v = rpmostreecxx::CxxGObjectArray(rpmmd_repos);
|
||||
rpmostreecxx::ror_lockfile_write(opt_write_lockfile_to, pkgs_v, repos_v);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ namespace rpmostreecxx {
|
||||
typedef ::OstreeRepo OstreeRepo;
|
||||
typedef ::OstreeDeployment OstreeDeployment;
|
||||
typedef ::GCancellable GCancellable;
|
||||
typedef ::GObject GObject;
|
||||
typedef ::GVariantDict GVariantDict;
|
||||
}
|
||||
|
||||
|
53
src/libpriv/rpmostree-cxxrsutil.hpp
Normal file
53
src/libpriv/rpmostree-cxxrsutil.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the licence or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <sstream>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "rust/cxx.h"
|
||||
|
||||
// Helpers corresponding to cxxrsutil.rs
|
||||
namespace rpmostreecxx {
|
||||
|
||||
// Wrapper for an array of GObjects. This is a hack until
|
||||
// cxx-rs gains support for either std::vector<> or Vec<T>
|
||||
// with nontrivial types.
|
||||
class CxxGObjectArray final {
|
||||
public:
|
||||
CxxGObjectArray(GPtrArray *arr_p) : arr(arr_p) {
|
||||
g_ptr_array_ref(arr);
|
||||
};
|
||||
~CxxGObjectArray() {
|
||||
g_ptr_array_unref(arr);
|
||||
}
|
||||
|
||||
unsigned int length() {
|
||||
return (unsigned int)arr->len;
|
||||
}
|
||||
|
||||
::GObject& get(unsigned int i) {
|
||||
g_assert_cmpuint(i, <, arr->len);
|
||||
return *(::GObject*)arr->pdata[i];
|
||||
}
|
||||
GPtrArray* arr;
|
||||
};
|
||||
|
||||
} // namespace
|
Loading…
Reference in New Issue
Block a user