Merge "aconfig: create c++ interlop from rust flag apis" into main
This commit is contained in:
@@ -89,3 +89,52 @@ rust_protobuf {
|
|||||||
source_stem: "aconfig_storage_protos",
|
source_stem: "aconfig_storage_protos",
|
||||||
host_supported: true,
|
host_supported: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "libaconfig_storage_protos_cc",
|
||||||
|
proto: {
|
||||||
|
export_proto_headers: true,
|
||||||
|
type: "lite",
|
||||||
|
},
|
||||||
|
srcs: ["protos/aconfig_storage_metadata.proto"],
|
||||||
|
apex_available: [
|
||||||
|
"//apex_available:platform",
|
||||||
|
"//apex_available:anyapex",
|
||||||
|
],
|
||||||
|
host_supported: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "libcxx_aconfig_storage_bridge_code",
|
||||||
|
tools: ["cxxbridge"],
|
||||||
|
cmd: "$(location cxxbridge) $(in) > $(out)",
|
||||||
|
srcs: ["src/lib.rs"],
|
||||||
|
out: ["aconfig_storage/lib.rs.cc"],
|
||||||
|
}
|
||||||
|
|
||||||
|
genrule {
|
||||||
|
name: "libcxx_aconfig_storage_bridge_header",
|
||||||
|
tools: ["cxxbridge"],
|
||||||
|
cmd: "$(location cxxbridge) $(in) --header > $(out)",
|
||||||
|
srcs: ["src/lib.rs"],
|
||||||
|
out: ["aconfig_storage/lib.rs.h"],
|
||||||
|
}
|
||||||
|
|
||||||
|
rust_ffi_static {
|
||||||
|
name: "libaconfig_storage_cxx_bridge",
|
||||||
|
crate_name: "aconfig_storage_cxx_bridge",
|
||||||
|
host_supported: true,
|
||||||
|
defaults: ["aconfig_storage_file.defaults"],
|
||||||
|
}
|
||||||
|
|
||||||
|
cc_library_static {
|
||||||
|
name: "libaconfig_storage_cc",
|
||||||
|
srcs: ["aconfig_storage.cpp"],
|
||||||
|
generated_headers: [
|
||||||
|
"cxx-bridge-header",
|
||||||
|
"libcxx_aconfig_storage_bridge_header"
|
||||||
|
],
|
||||||
|
generated_sources: ["libcxx_aconfig_storage_bridge_code"],
|
||||||
|
whole_static_libs: ["libaconfig_storage_cxx_bridge"],
|
||||||
|
export_include_dirs: ["include"],
|
||||||
|
}
|
||||||
|
@@ -18,3 +18,4 @@ thiserror = "1.0.56"
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
protobuf-codegen = "3.2.0"
|
protobuf-codegen = "3.2.0"
|
||||||
|
cxx-build = "1.0"
|
||||||
|
106
tools/aconfig/aconfig_storage_file/aconfig_storage.cpp
Normal file
106
tools/aconfig/aconfig_storage_file/aconfig_storage.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#include "aconfig_storage/aconfig_storage.hpp"
|
||||||
|
|
||||||
|
#include "rust/cxx.h"
|
||||||
|
#include "aconfig_storage/lib.rs.h"
|
||||||
|
|
||||||
|
namespace aconfig_storage {
|
||||||
|
|
||||||
|
/// Get package offset
|
||||||
|
PackageOffsetQuery get_package_offset(
|
||||||
|
std::string const& container,
|
||||||
|
std::string const& package) {
|
||||||
|
auto offset_cxx = get_package_offset_cxx(
|
||||||
|
rust::Str(container.c_str()),
|
||||||
|
rust::Str(package.c_str()));
|
||||||
|
auto offset = PackageOffsetQuery();
|
||||||
|
offset.query_success = offset_cxx.query_success;
|
||||||
|
offset.error_message = std::string(offset_cxx.error_message.c_str());
|
||||||
|
offset.package_exists = offset_cxx.package_exists;
|
||||||
|
offset.package_id = offset_cxx.package_id;
|
||||||
|
offset.boolean_offset = offset_cxx.boolean_offset;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get flag offset
|
||||||
|
FlagOffsetQuery get_flag_offset(
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t package_id,
|
||||||
|
std::string const& flag_name) {
|
||||||
|
auto offset_cxx = get_flag_offset_cxx(
|
||||||
|
rust::Str(container.c_str()),
|
||||||
|
package_id,
|
||||||
|
rust::Str(flag_name.c_str()));
|
||||||
|
auto offset = FlagOffsetQuery();
|
||||||
|
offset.query_success = offset_cxx.query_success;
|
||||||
|
offset.error_message = std::string(offset_cxx.error_message.c_str());
|
||||||
|
offset.flag_exists = offset_cxx.flag_exists;
|
||||||
|
offset.flag_offset = offset_cxx.flag_offset;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get boolean flag value
|
||||||
|
BooleanFlagValueQuery get_boolean_flag_value(
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t offset) {
|
||||||
|
auto value_cxx = get_boolean_flag_value_cxx(
|
||||||
|
rust::Str(container.c_str()),
|
||||||
|
offset);
|
||||||
|
auto value = BooleanFlagValueQuery();
|
||||||
|
value.query_success = value_cxx.query_success;
|
||||||
|
value.error_message = std::string(value_cxx.error_message.c_str());
|
||||||
|
value.flag_value = value_cxx.flag_value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace test_only_api {
|
||||||
|
PackageOffsetQuery get_package_offset_impl(
|
||||||
|
std::string const& pb_file,
|
||||||
|
std::string const& container,
|
||||||
|
std::string const& package) {
|
||||||
|
auto offset_cxx = get_package_offset_cxx_impl(
|
||||||
|
rust::Str(pb_file.c_str()),
|
||||||
|
rust::Str(container.c_str()),
|
||||||
|
rust::Str(package.c_str()));
|
||||||
|
auto offset = PackageOffsetQuery();
|
||||||
|
offset.query_success = offset_cxx.query_success;
|
||||||
|
offset.error_message = std::string(offset_cxx.error_message.c_str());
|
||||||
|
offset.package_exists = offset_cxx.package_exists;
|
||||||
|
offset.package_id = offset_cxx.package_id;
|
||||||
|
offset.boolean_offset = offset_cxx.boolean_offset;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlagOffsetQuery get_flag_offset_impl(
|
||||||
|
std::string const& pb_file,
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t package_id,
|
||||||
|
std::string const& flag_name) {
|
||||||
|
auto offset_cxx = get_flag_offset_cxx_impl(
|
||||||
|
rust::Str(pb_file.c_str()),
|
||||||
|
rust::Str(container.c_str()),
|
||||||
|
package_id,
|
||||||
|
rust::Str(flag_name.c_str()));
|
||||||
|
auto offset = FlagOffsetQuery();
|
||||||
|
offset.query_success = offset_cxx.query_success;
|
||||||
|
offset.error_message = std::string(offset_cxx.error_message.c_str());
|
||||||
|
offset.flag_exists = offset_cxx.flag_exists;
|
||||||
|
offset.flag_offset = offset_cxx.flag_offset;
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
BooleanFlagValueQuery get_boolean_flag_value_impl(
|
||||||
|
std::string const& pb_file,
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t offset) {
|
||||||
|
auto value_cxx = get_boolean_flag_value_cxx_impl(
|
||||||
|
rust::Str(pb_file.c_str()),
|
||||||
|
rust::Str(container.c_str()),
|
||||||
|
offset);
|
||||||
|
auto value = BooleanFlagValueQuery();
|
||||||
|
value.query_success = value_cxx.query_success;
|
||||||
|
value.error_message = std::string(value_cxx.error_message.c_str());
|
||||||
|
value.flag_value = value_cxx.flag_value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
} // namespace test_only_api
|
||||||
|
} // namespace aconfig_storage
|
@@ -14,4 +14,7 @@ fn main() {
|
|||||||
.inputs(proto_files)
|
.inputs(proto_files)
|
||||||
.cargo_out_dir("aconfig_storage_protos")
|
.cargo_out_dir("aconfig_storage_protos")
|
||||||
.run_from_script();
|
.run_from_script();
|
||||||
|
|
||||||
|
let _ = cxx_build::bridge("src/lib.rs");
|
||||||
|
println!("cargo:rerun-if-changed=src/lib.rs");
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace aconfig_storage {
|
||||||
|
|
||||||
|
/// Package offset query result
|
||||||
|
struct PackageOffsetQuery {
|
||||||
|
bool query_success;
|
||||||
|
std::string error_message;
|
||||||
|
bool package_exists;
|
||||||
|
uint32_t package_id;
|
||||||
|
uint32_t boolean_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Flag offset query result
|
||||||
|
struct FlagOffsetQuery {
|
||||||
|
bool query_success;
|
||||||
|
std::string error_message;
|
||||||
|
bool flag_exists;
|
||||||
|
uint16_t flag_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Boolean flag value query result
|
||||||
|
struct BooleanFlagValueQuery {
|
||||||
|
bool query_success;
|
||||||
|
std::string error_message;
|
||||||
|
bool flag_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Get package offset
|
||||||
|
/// \input container: the flag container name
|
||||||
|
/// \input package: the flag package name
|
||||||
|
/// \returns a PackageOffsetQuery
|
||||||
|
PackageOffsetQuery get_package_offset(
|
||||||
|
std::string const& container,
|
||||||
|
std::string const& package);
|
||||||
|
|
||||||
|
/// Get flag offset
|
||||||
|
/// \input container: the flag container name
|
||||||
|
/// \input package_id: the flag package id obtained from package offset query
|
||||||
|
/// \input flag_name: flag name
|
||||||
|
/// \returns a FlagOffsetQuery
|
||||||
|
FlagOffsetQuery get_flag_offset(
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t package_id,
|
||||||
|
std::string const& flag_name);
|
||||||
|
|
||||||
|
/// Get boolean flag value
|
||||||
|
/// \input container: the flag container name
|
||||||
|
/// \input offset: the boolean flag value byte offset in the file
|
||||||
|
/// \returns a BooleanFlagValueQuery
|
||||||
|
BooleanFlagValueQuery get_boolean_flag_value(
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t offset);
|
||||||
|
|
||||||
|
/// DO NOT USE APIS IN THE FOLLOWING NAMESPACE, TEST ONLY
|
||||||
|
namespace test_only_api {
|
||||||
|
PackageOffsetQuery get_package_offset_impl(
|
||||||
|
std::string const& pb_file,
|
||||||
|
std::string const& container,
|
||||||
|
std::string const& package);
|
||||||
|
|
||||||
|
FlagOffsetQuery get_flag_offset_impl(
|
||||||
|
std::string const& pb_file,
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t package_id,
|
||||||
|
std::string const& flag_name);
|
||||||
|
|
||||||
|
BooleanFlagValueQuery get_boolean_flag_value_impl(
|
||||||
|
std::string const& pb_file,
|
||||||
|
std::string const& container,
|
||||||
|
uint32_t offset);
|
||||||
|
} // namespace test_only_api
|
||||||
|
} // namespace aconfig_storage
|
@@ -256,6 +256,185 @@ pub fn get_boolean_flag_value(container: &str, offset: u32) -> Result<bool, Acon
|
|||||||
get_boolean_flag_value_impl(STORAGE_LOCATION_FILE, container, offset)
|
get_boolean_flag_value_impl(STORAGE_LOCATION_FILE, container, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cxx::bridge]
|
||||||
|
mod ffi {
|
||||||
|
// Package table query return for cc interlop
|
||||||
|
pub struct PackageOffsetQueryCXX {
|
||||||
|
pub query_success: bool,
|
||||||
|
pub error_message: String,
|
||||||
|
pub package_exists: bool,
|
||||||
|
pub package_id: u32,
|
||||||
|
pub boolean_offset: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag table query return for cc interlop
|
||||||
|
pub struct FlagOffsetQueryCXX {
|
||||||
|
pub query_success: bool,
|
||||||
|
pub error_message: String,
|
||||||
|
pub flag_exists: bool,
|
||||||
|
pub flag_offset: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag value query return for cc interlop
|
||||||
|
pub struct BooleanFlagValueQueryCXX {
|
||||||
|
pub query_success: bool,
|
||||||
|
pub error_message: String,
|
||||||
|
pub flag_value: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rust export to c++
|
||||||
|
extern "Rust" {
|
||||||
|
pub fn get_package_offset_cxx_impl(
|
||||||
|
pb_file: &str,
|
||||||
|
container: &str,
|
||||||
|
package: &str,
|
||||||
|
) -> PackageOffsetQueryCXX;
|
||||||
|
|
||||||
|
pub fn get_flag_offset_cxx_impl(
|
||||||
|
pb_file: &str,
|
||||||
|
container: &str,
|
||||||
|
package_id: u32,
|
||||||
|
flag: &str,
|
||||||
|
) -> FlagOffsetQueryCXX;
|
||||||
|
|
||||||
|
pub fn get_boolean_flag_value_cxx_impl(
|
||||||
|
pb_file: &str,
|
||||||
|
container: &str,
|
||||||
|
offset: u32,
|
||||||
|
) -> BooleanFlagValueQueryCXX;
|
||||||
|
|
||||||
|
pub fn get_package_offset_cxx(container: &str, package: &str) -> PackageOffsetQueryCXX;
|
||||||
|
|
||||||
|
pub fn get_flag_offset_cxx(
|
||||||
|
container: &str,
|
||||||
|
package_id: u32,
|
||||||
|
flag: &str,
|
||||||
|
) -> FlagOffsetQueryCXX;
|
||||||
|
|
||||||
|
pub fn get_boolean_flag_value_cxx(container: &str, offset: u32)
|
||||||
|
-> BooleanFlagValueQueryCXX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get package start offset impl cc interlop
|
||||||
|
pub fn get_package_offset_cxx_impl(
|
||||||
|
pb_file: &str,
|
||||||
|
container: &str,
|
||||||
|
package: &str,
|
||||||
|
) -> ffi::PackageOffsetQueryCXX {
|
||||||
|
ffi::PackageOffsetQueryCXX::new(get_package_offset_impl(pb_file, container, package))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get flag start offset impl cc interlop
|
||||||
|
pub fn get_flag_offset_cxx_impl(
|
||||||
|
pb_file: &str,
|
||||||
|
container: &str,
|
||||||
|
package_id: u32,
|
||||||
|
flag: &str,
|
||||||
|
) -> ffi::FlagOffsetQueryCXX {
|
||||||
|
ffi::FlagOffsetQueryCXX::new(get_flag_offset_impl(pb_file, container, package_id, flag))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get boolean flag value impl cc interlop
|
||||||
|
pub fn get_boolean_flag_value_cxx_impl(
|
||||||
|
pb_file: &str,
|
||||||
|
container: &str,
|
||||||
|
offset: u32,
|
||||||
|
) -> ffi::BooleanFlagValueQueryCXX {
|
||||||
|
ffi::BooleanFlagValueQueryCXX::new(get_boolean_flag_value_impl(pb_file, container, offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get package start offset cc interlop
|
||||||
|
pub fn get_package_offset_cxx(container: &str, package: &str) -> ffi::PackageOffsetQueryCXX {
|
||||||
|
ffi::PackageOffsetQueryCXX::new(get_package_offset(container, package))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get flag start offset cc interlop
|
||||||
|
pub fn get_flag_offset_cxx(
|
||||||
|
container: &str,
|
||||||
|
package_id: u32,
|
||||||
|
flag: &str,
|
||||||
|
) -> ffi::FlagOffsetQueryCXX {
|
||||||
|
ffi::FlagOffsetQueryCXX::new(get_flag_offset(container, package_id, flag))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get boolean flag value cc interlop
|
||||||
|
pub fn get_boolean_flag_value_cxx(container: &str, offset: u32) -> ffi::BooleanFlagValueQueryCXX {
|
||||||
|
ffi::BooleanFlagValueQueryCXX::new(get_boolean_flag_value(container, offset))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ffi::PackageOffsetQueryCXX {
|
||||||
|
pub(crate) fn new(offset_result: Result<Option<PackageOffset>, AconfigStorageError>) -> Self {
|
||||||
|
match offset_result {
|
||||||
|
Ok(offset_opt) => match offset_opt {
|
||||||
|
Some(offset) => Self {
|
||||||
|
query_success: true,
|
||||||
|
error_message: String::from(""),
|
||||||
|
package_exists: true,
|
||||||
|
package_id: offset.package_id,
|
||||||
|
boolean_offset: offset.boolean_offset,
|
||||||
|
},
|
||||||
|
None => Self {
|
||||||
|
query_success: true,
|
||||||
|
error_message: String::from(""),
|
||||||
|
package_exists: false,
|
||||||
|
package_id: 0,
|
||||||
|
boolean_offset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(errmsg) => Self {
|
||||||
|
query_success: false,
|
||||||
|
error_message: format!("{:?}", errmsg),
|
||||||
|
package_exists: false,
|
||||||
|
package_id: 0,
|
||||||
|
boolean_offset: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ffi::FlagOffsetQueryCXX {
|
||||||
|
pub(crate) fn new(offset_result: Result<Option<FlagOffset>, AconfigStorageError>) -> Self {
|
||||||
|
match offset_result {
|
||||||
|
Ok(offset_opt) => match offset_opt {
|
||||||
|
Some(offset) => Self {
|
||||||
|
query_success: true,
|
||||||
|
error_message: String::from(""),
|
||||||
|
flag_exists: true,
|
||||||
|
flag_offset: offset,
|
||||||
|
},
|
||||||
|
None => Self {
|
||||||
|
query_success: true,
|
||||||
|
error_message: String::from(""),
|
||||||
|
flag_exists: false,
|
||||||
|
flag_offset: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Err(errmsg) => Self {
|
||||||
|
query_success: false,
|
||||||
|
error_message: format!("{:?}", errmsg),
|
||||||
|
flag_exists: false,
|
||||||
|
flag_offset: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ffi::BooleanFlagValueQueryCXX {
|
||||||
|
pub(crate) fn new(value_result: Result<bool, AconfigStorageError>) -> Self {
|
||||||
|
match value_result {
|
||||||
|
Ok(value) => {
|
||||||
|
Self { query_success: true, error_message: String::from(""), flag_value: value }
|
||||||
|
}
|
||||||
|
Err(errmsg) => Self {
|
||||||
|
query_success: false,
|
||||||
|
error_message: format!("{:?}", errmsg),
|
||||||
|
flag_value: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
Reference in New Issue
Block a user