aconfig: add flag value query pub function
Bug: b/321077378
Test: atest aconfig_storage_file.test
Change-Id: I83dd93c5f8d640ddbe85493a470af68df1e3e69d
diff --git a/tools/aconfig/aconfig_storage_file/src/flag_value.rs b/tools/aconfig/aconfig_storage_file/src/flag_value.rs
index 86f75ce..c8b52a9 100644
--- a/tools/aconfig/aconfig_storage_file/src/flag_value.rs
+++ b/tools/aconfig/aconfig_storage_file/src/flag_value.rs
@@ -18,7 +18,7 @@
//! and deserialization
use crate::{read_str_from_bytes, read_u32_from_bytes, read_u8_from_bytes};
-use anyhow::Result;
+use anyhow::{anyhow, Result};
/// Flag value header struct
#[derive(PartialEq, Debug)]
@@ -86,6 +86,29 @@
}
}
+/// Query flag value
+pub fn get_boolean_flag_value(buf: &[u8], flag_offset: u32) -> Result<bool> {
+ let interpreted_header = FlagValueHeader::from_bytes(buf)?;
+ if interpreted_header.version > crate::FILE_VERSION {
+ return Err(anyhow!(
+ "Cannot read storage file with a higher version of {} with lib version {}",
+ interpreted_header.version,
+ crate::FILE_VERSION
+ ));
+ }
+
+ let mut head = (interpreted_header.boolean_value_offset + flag_offset) as usize;
+
+ // TODO: right now, there is only boolean flags, with more flag value types added
+ // later, the end of boolean flag value section should be updated (b/322826265).
+ if head >= interpreted_header.file_size as usize {
+ return Err(anyhow!("Flag value offset goes beyond the end of the file."));
+ }
+
+ let val = read_u8_from_bytes(buf, &mut head)?;
+ Ok(val == 1)
+}
+
#[cfg(test)]
mod tests {
use super::*;
@@ -116,4 +139,47 @@
assert!(reinterpreted_value_list.is_ok());
assert_eq!(&flag_value_list, &reinterpreted_value_list.unwrap());
}
+
+ #[test]
+ // this test point locks down flag value query
+ fn test_flag_value_query() {
+ let flag_value_list = create_test_flag_value_list().unwrap().as_bytes();
+ let baseline: Vec<bool> = vec![false, true, false, false, true, true, false, true];
+ for (offset, expected_value) in baseline.into_iter().enumerate() {
+ let flag_value =
+ get_boolean_flag_value(&flag_value_list[..], offset as u32)
+ .unwrap();
+ assert_eq!(flag_value, expected_value);
+ }
+ }
+
+ #[test]
+ // this test point locks down query beyond the end of boolean section
+ fn test_boolean_out_of_range() {
+ let flag_value_list = create_test_flag_value_list().unwrap().as_bytes();
+ let error = get_boolean_flag_value(&flag_value_list[..], 8)
+ .unwrap_err();
+ assert_eq!(
+ format!("{:?}", error),
+ "Flag value offset goes beyond the end of the file."
+ );
+ }
+
+ #[test]
+ // this test point locks down query error when file has a higher version
+ fn test_higher_version_storage_file() {
+ let mut value_list = create_test_flag_value_list().unwrap();
+ value_list.header.version = crate::FILE_VERSION + 1;
+ let flag_value = value_list.as_bytes();
+ let error = get_boolean_flag_value(&flag_value[..], 4)
+ .unwrap_err();
+ assert_eq!(
+ format!("{:?}", error),
+ format!(
+ "Cannot read storage file with a higher version of {} with lib version {}",
+ crate::FILE_VERSION + 1,
+ crate::FILE_VERSION
+ )
+ );
+ }
}