pub struct Axml { /* private fields */ }Expand description
The main AXML object representing a binary Android XML file.
§Dual-state synchronization
Axml carries two representations of the same data that must be kept in sync:
- Decoded state:
stringblocks,resource_map,elements. These fields are the ground truth during parsing and editing. - Proto state:
protois aprost-generated message used for protobuf serialization. It is populated lazily byupdate_proto().
Rule: after any mutation to the decoded state (e.g. modifying elements or
calling import_stringblocks_json), callers must invoke update_proto()
before calling get_proto() or any proto-based serialization path.
Failing to do so will return a stale proto that does not reflect the current state.
Implementations§
Source§impl Axml
impl Axml
Sourcepub fn get_proto(&self) -> &Axml
pub fn get_proto(&self) -> &Axml
Return a reference to the cached prost-generated protobuf message.
The proto is populated during from_axml() / from_xml().
Call update_proto() first if the internal state has been modified.
Sourcepub fn string_count(&self) -> usize
pub fn string_count(&self) -> usize
Number of strings in the string pool.
Sourcepub fn export_stringblocks_json(&self) -> String
pub fn export_stringblocks_json(&self) -> String
Serialize the string pool as a JSON object for use with --stringblocks-file.
Sourcepub fn import_stringblocks_json(&mut self, json: &str)
pub fn import_stringblocks_json(&mut self, json: &str)
Pre-populate the string pool from a JSON object previously produced by
export_stringblocks_json.
Sourcepub fn from_axml(data: &[u8]) -> Result<Self, AxmlError>
pub fn from_axml(data: &[u8]) -> Result<Self, AxmlError>
Parse binary AXML data into an Axml object.
Sourcepub fn pack(&self) -> Vec<u8> ⓘ
pub fn pack(&self) -> Vec<u8> ⓘ
Serialize the AXML object back to binary format.
Bytes 4..8 of the output (the chunk total-size field) come from
self.total_size verbatim. Set that field to an arbitrary value
before calling pack() to produce intentionally malformed output.
Call compute() first to write the correct size.
Sourcepub fn to_xml(&self) -> Result<String, AxmlError>
pub fn to_xml(&self) -> Result<String, AxmlError>
Decode the AXML to a human-readable XML string.
Sourcepub fn from_xml(&mut self, xml: &str) -> Result<(), AxmlError>
pub fn from_xml(&mut self, xml: &str) -> Result<(), AxmlError>
Build binary AXML from a plain XML string.
Two-pass implementation: the first pass collects all xmlns: declarations so that StartNamespace elements can be emitted before any StartElement. The second pass builds the binary elements. Android attribute → resource-ID mappings are collected inline and the resource map is assembled after the loop.
Sourcepub fn compute(&mut self)
pub fn compute(&mut self)
Recalculate all chunk-size header fields and store them in the struct.
Updates self.total_size (AXML outer header) and marks the string pool
dirty so pack() produces a fully correct binary.
Without calling compute(), pack() uses whatever sizes were last stored
either the original parsed values, values set manually, or a stale size
left by apply_stringblocks_no_compute().
Sourcepub fn apply_stringblocks_no_compute(&mut self, new_strings: Vec<Vec<u8>>)
pub fn apply_stringblocks_no_compute(&mut self, new_strings: Vec<Vec<u8>>)
Apply new string pool content without updating the pool’s chunk-size header.
new_strings must be the data bytes from each StringBlock proto entry
(raw UTF-8 or UTF-16-LE bytes, no length prefix, no null terminator).
After this call pack() returns a binary where string content reflects
the new values but the chunk total-size field is stale, an intentionally
corrupted file useful for security testing. Call compute() before
pack() to produce a correctly-sized output instead.
Sourcepub fn to_proto_text(&self) -> String
pub fn to_proto_text(&self) -> String
Serialize to proto text format using the native prost-reflect formatter.
Requires update_proto() to have been called (automatically done by
from_axml() and from_xml()).
Sourcepub fn to_proto_text_pretty(&self) -> String
pub fn to_proto_text_pretty(&self) -> String
Serialize to indented proto text format (one field per line).
Sourcepub fn export_proto_file(&self, path: &str) -> Result<(), AxmlError>
pub fn export_proto_file(&self, path: &str) -> Result<(), AxmlError>
Write the binary proto representation of this AXML file to path.
Sourcepub fn from_proto_file(path: &str) -> Result<Self, AxmlError>
pub fn from_proto_file(path: &str) -> Result<Self, AxmlError>
Load an AXML from a binary proto file written by [export_proto_file].
Source§impl Axml
impl Axml
Sourcepub fn to_proto_bytes(&self) -> Vec<u8> ⓘ
pub fn to_proto_bytes(&self) -> Vec<u8> ⓘ
Serialize this AXML file as a binary protobuf message (proto encoding, not the Android binary AXML format).
Sourcepub fn from_proto_bytes(data: &[u8]) -> Result<Self, AxmlError>
pub fn from_proto_bytes(data: &[u8]) -> Result<Self, AxmlError>
Deserialize an AXML file from binary protobuf bytes produced by
[to_proto_bytes].
Sourcepub fn to_proto(&self) -> Axml
pub fn to_proto(&self) -> Axml
Convert to the prost-generated [proto::Axml] message for in-process
manipulation.
Sourcepub fn from_proto(p: Axml) -> Result<Self, AxmlError>
pub fn from_proto(p: Axml) -> Result<Self, AxmlError>
Reconstruct an Axml from a prost-generated [proto::Axml] message.
Sourcepub fn update_proto(&mut self)
pub fn update_proto(&mut self)
Recompute self.proto and self.stringblocks.proto from the current
in-memory state. Called automatically at the end of from_axml() and
from_xml(). Call manually if you modify stringblocks.inner or
elements directly.