aconfig: create flag value file

Create flag_value module to create flag value file. Flag value file
contains a header section at the start of the file, followed by a
boolean array.

Bug: b/312243587
Test: atest aconfig.test
Change-Id: If76660189d63073fbd477e1e447240e0cd029604
diff --git a/tools/aconfig/src/storage/mod.rs b/tools/aconfig/src/storage/mod.rs
index a28fccd..36ea309 100644
--- a/tools/aconfig/src/storage/mod.rs
+++ b/tools/aconfig/src/storage/mod.rs
@@ -15,6 +15,7 @@
  */
 
 pub mod flag_table;
+pub mod flag_value;
 pub mod package_table;
 
 use anyhow::{anyhow, Result};
@@ -24,7 +25,9 @@
 
 use crate::commands::OutputFile;
 use crate::protos::{ProtoParsedFlag, ProtoParsedFlags};
-use crate::storage::{flag_table::FlagTable, package_table::PackageTable};
+use crate::storage::{
+    flag_table::FlagTable, flag_value::FlagValueList, package_table::PackageTable,
+};
 
 pub const FILE_VERSION: u32 = 1;
 
@@ -128,7 +131,13 @@
     let flag_table_file =
         OutputFile { contents: flag_table.as_bytes(), path: flag_table_file_path };
 
-    Ok(vec![package_table_file, flag_table_file])
+    // create and serialize flag value
+    let flag_value = FlagValueList::new(container, &packages)?;
+    let flag_value_file_path = PathBuf::from("flag.val");
+    let flag_value_file =
+        OutputFile { contents: flag_value.as_bytes(), path: flag_value_file_path };
+
+    Ok(vec![package_table_file, flag_table_file, flag_value_file])
 }
 
 #[cfg(test)]
@@ -136,6 +145,13 @@
     use super::*;
     use crate::Input;
 
+    /// Read and parse bytes as u8
+    pub fn read_u8_from_bytes(buf: &[u8], head: &mut usize) -> Result<u8> {
+        let val = u8::from_le_bytes(buf[*head..*head + 1].try_into()?);
+        *head += 1;
+        Ok(val)
+    }
+
     /// Read and parse bytes as u16
     pub fn read_u16_from_bytes(buf: &[u8], head: &mut usize) -> Result<u16> {
         let val = u16::from_le_bytes(buf[*head..*head + 2].try_into()?);