### Example Usage of get_services_names Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_services_names.html Demonstrates how to use `get_services_names` to retrieve the number of services from an AndroidManifest.xml file. This function is only valid for APK manifest files. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::get_services_names(&axml).len(), 2) ``` -------------------------------- ### Create Cursor from APK and Parse AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.create_cursor_from_apk.html Opens an APK file, reads its contents into a byte cursor, and then parses the AXML data. This example also demonstrates how to check for requested permissions. ```rust let cursor = rusty_axml::create_cursor_from_apk("tests/assets/app.apk").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert!(rusty_axml::get_requested_permissions(&axml) .contains(&"android.permission.ACCESS_FINE_LOCATION".to_string())) ``` -------------------------------- ### Rust Rc clone Example Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Shows how to clone an Rc pointer, which increases the strong reference count and creates another owner for the same allocation. ```rust use std::rc::Rc; let five = Rc::new(5); let _ = Rc::clone(&five); ``` -------------------------------- ### Parse Start Namespace Source: https://docs.rs/rusty-axml/latest/src/rusty_axml/parser.rs.html Parses the start of an XML namespace chunk from the AXML buffer. It reads chunk header information, line number, comment, and indices for prefix and URI, then inserts them into the provided namespaces HashMap. ```Rust pub fn parse_start_namespace(axml_buff: &mut Cursor>, strings: &[String], namespaces: &mut HashMap::) -> Result<(), AxmlError> { // Go back 2 bytes, to account from the block type let offset = axml_buff.position(); axml_buff.set_position(offset - 2); // Parse chunk header let _header = ChunkHeader::from_buff(axml_buff, ChunkType::ResXmlStartNamespaceType)?; let _line_number = axml_buff.read_u32::()?; let _comment = axml_buff.read_u32::()?; let prefix = axml_buff.read_u32::()?; let uri = axml_buff.read_u32::()?; let prefix_str = strings.get(prefix as usize).ok_or(AxmlError::StringPoolError)?; let uri_str = strings.get(uri as usize).ok_or(AxmlError::StringPoolError)?; namespaces.insert(uri_str.to_string(), prefix_str.to_string()); Ok(()) } ``` -------------------------------- ### Rust Rc Default Example Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Illustrates creating a new Rc with the default value for T using the Default trait. ```rust use std::rc::Rc; let x: Rc = Default::default(); assert_eq!(*x, 0); ``` -------------------------------- ### parse_start_element Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/fn.parse_start_element.html Parses the start of an XML element from a byte buffer, utilizing provided string data and namespace mappings. ```APIDOC ## Function: parse_start_element ### Description Parses the start of an element from a byte buffer. ### Signature ```rust pub fn parse_start_element( axml_buff: &mut Cursor>, strings: &[String], namespace_prefixes: &HashMap, ) -> Result ``` ### Parameters * `axml_buff`: A mutable reference to a `Cursor>` containing the XML data. * `strings`: A slice of `String` containing string data referenced in the XML. * `namespace_prefixes`: A `HashMap` mapping namespace URIs to their prefixes. ### Returns A `Result` which is either an `XmlElement` on success or an `AxmlError` on failure. ``` -------------------------------- ### Find Activity Nodes in AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.find_nodes_by_type.html This example demonstrates how to use find_nodes_by_type to count the number of 'activity' elements within an AXML document. It requires creating a cursor from an AXML file and then parsing it. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::find_nodes_by_type(&axml, "activity").len(), 1) ``` -------------------------------- ### Parse Start Element Source: https://docs.rs/rusty-axml/latest/src/rusty_axml/parser.rs.html Parses the start of an XML element chunk. It reads element name, attribute count, and then iterates through attributes, decoding their namespace, name, raw value, and data type. ```Rust pub fn parse_start_element(axml_buff: &mut Cursor>, strings: &[String], namespace_prefixes: &HashMap::) -> Result { // Go back 2 bytes, to account from the block type let offset = axml_buff.position(); axml_buff.set_position(offset - 2); // Parse chunk header let _header = ChunkHeader::from_buff(axml_buff, ChunkType::ResXmlStartElementType)?; let _line_number = axml_buff.read_u32::()?; let _comment = axml_buff.read_u32::()?; let _namespace = axml_buff.read_u32::()?; let name = axml_buff.read_u32::()?; let _attribute_size = axml_buff.read_u32::()?; let attribute_count = axml_buff.read_u16::()?; let _id_index = axml_buff.read_u16::()?; let _class_index = axml_buff.read_u16::()?; let _style_index = axml_buff.read_u16::()?; let element_type = strings.get(name as usize).ok_or(AxmlError::StringPoolError)?.to_string(); let mut decoded_attrs = HashMap::::new(); for _ in 0..attribute_count { let attr_namespace = axml_buff.read_u32::()?; let attr_name = axml_buff.read_u32::()?; let attr_raw_val = axml_buff.read_u32::()?; let data_value_type = ResValue::from_buff(axml_buff)?; let mut decoded_attr_key = String::new(); let mut decoded_attr_val = String::new(); if attr_namespace != 0xffffffff { let namespace = strings.get(attr_namespace as usize).ok_or(AxmlError::StringPoolError)?; let ns_prefix = namespace_prefixes.get(namespace).ok_or(AxmlError::NamespaceError)?; decoded_attr_key.push_str(ns_prefix); decoded_attr_key.push(':'); } else { // TODO } decoded_attr_key.push_str(strings.get(attr_name as usize).ok_or(AxmlError::StringPoolError)?); if attr_raw_val != 0xffffffff { decoded_attr_val.push_str(&strings.get(attr_raw_val as usize).ok_or(AxmlError::StringPoolError)?.to_string()); } else { match data_value_type.data_type { DataValueType::TypeNull => { decoded_attr_val.push_str("(null)"); }, DataValueType::TypeReference => { decoded_attr_val.push_str("0x"); ``` -------------------------------- ### parse_start_namespace Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/fn.parse_start_namespace.html Parses the start of a namespace from an XML buffer. It takes a mutable cursor to the XML data, a slice of strings (likely from a string pool), and a mutable HashMap to store the parsed namespaces. It returns a Result indicating success or an AxmlError. ```APIDOC ## Function parse_start_namespace ### Description Parses the start of a namespace from an XML buffer. ### Signature ```rust pub fn parse_start_namespace( axml_buff: &mut Cursor>, strings: &[String], namespaces: &mut HashMap, ) -> Result<(), AxmlError> ``` ### Parameters * `axml_buff`: A mutable reference to a `Cursor>` representing the XML data buffer. * `strings`: A slice of `String` containing the string pool. * `namespaces`: A mutable reference to a `HashMap` to store the parsed namespaces. ### Returns * `Result<(), AxmlError>`: Returns `Ok(())` on success, or an `AxmlError` if parsing fails. ``` -------------------------------- ### Axml Methods Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.Axml.html Provides methods to interact with the Axml document, such as writing to a file, converting to a string, getting the root node, and iterating through elements. ```APIDOC ## pub fn write_to_file(&self, file: &mut File) -> Result<(), AxmlError> ### Description Write the whole parsed XML to a file. ### Method `write_to_file` ### Parameters - `file`: A mutable reference to a `File` object where the XML will be written. ### Returns - `Result<(), AxmlError>`: Ok if the write operation is successful, or an `AxmlError` if an error occurs during writing. ## pub fn to_string(&self) -> Result ### Description Convert the whole parsed XML into a string. ### Method `to_string` ### Returns - `Result`: A `String` containing the XML representation, or an `AxmlError` if the conversion fails. ## pub fn root(&self) -> &XmlNode ### Description Get a reference to the root of the AXML document. ### Method `root` ### Returns - `&XmlNode`: A reference to the root `XmlNode` of the document. ## pub fn iter(&self) -> AxmlIterator ### Description Returns a non-consuming iterator over the AXML document elements. ### Method `iter` ### Returns - `AxmlIterator`: An iterator that yields elements of the AXML document. ``` -------------------------------- ### Get Exposed Components from AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_exposed_components.html Demonstrates how to parse an AXML file and retrieve its exposed components. This snippet shows how to use the function and assert the expected number of components of each type. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); let exposed_components = rusty_axml::get_exposed_components(&axml).unwrap(); assert_eq!(exposed_components.get("activity").unwrap().len(), 1); assert_eq!(exposed_components.get("service").unwrap().len(), 1); assert_eq!(exposed_components.get("receiver").unwrap().len(), 2); assert_eq!(exposed_components.get("provider").unwrap().len(), 0); ``` -------------------------------- ### Get Provider Names from AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_providers_names.html Demonstrates how to parse an AXML file and retrieve the count of provider names. This function is only valid for APK manifest files. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::get_providers_names(&axml).len(), 2) ``` -------------------------------- ### Get Strong Reference Count of an Rc Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates how to get the number of strong (Rc) references to an allocation. This helps understand shared ownership. ```rust use std::rc::Rc; let five = Rc::new(5); let _also_five = Rc::clone(&five); assert_eq!(2, Rc::strong_count(&five)); ``` -------------------------------- ### Parse APK and Check Permissions Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.parse_from_apk.html Demonstrates how to parse an APK's manifest using `parse_from_apk` and then check for specific requested permissions. ```rust let axml = rusty_axml::parse_from_apk("tests/assets/app.apk").unwrap(); assert!(rusty_axml::get_requested_permissions(&axml) .contains(&"android.permission.ACCESS_FINE_LOCATION".to_string())); ``` -------------------------------- ### Create Rc from Box Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates creating an Rc from a Box. ```rust let original: Box = Box::new(1); let shared: Rc = Rc::from(original); assert_eq!(1, *shared); ``` -------------------------------- ### Get Element Name Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.XmlElement.html Retrieves the name of the XML element from its attributes, if it exists. ```rust pub fn get_name(&self) -> Option<&str> ``` -------------------------------- ### pub fn new_uninit() -> Rc> Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new `Rc` with uninitialized contents. ```APIDOC ## pub fn new_uninit() -> Rc> ### Description Constructs a new `Rc` with uninitialized contents. ### Method Associated function ### Response #### Success Response (Rc>) - **Rc>** - A new reference-counted pointer to an uninitialized value. ``` -------------------------------- ### Get Root XmlNode Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.Axml.html Retrieves a reference to the root node of the AXML document. ```rust pub fn root(&self) -> &XmlNode ``` -------------------------------- ### Get Element Type Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.XmlElement.html Retrieves the type of the XML element as a string slice. ```rust pub fn element_type(&self) -> &str ``` -------------------------------- ### Create Rc from Cow Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Shows how to create an Rc from a Cow<'_, str> by copying its content. ```rust let cow: Cow<'_, str> = Cow::Borrowed("eggplant"); let shared: Rc = Rc::from(cow); assert_eq!("eggplant", &shared[..]); ``` -------------------------------- ### Get Element Children Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.XmlElement.html Retrieves a slice of XmlNode representing the children of the XML element. ```rust pub fn children(&self) -> &[XmlNode] ⓘ ``` -------------------------------- ### Rc::weak_count Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Gets the number of Weak pointers to this allocation. This count does not keep the allocation alive. ```APIDOC ## Rc::weak_count ### Description Gets the number of `Weak` pointers to this allocation. This count does not keep the allocation alive. ### Method `weak_count` ### Parameters #### Path Parameters - **this** (`&Rc`) - Required - The `Rc` to query the weak count for. ### Response #### Success Response - **usize** - The number of `Weak` pointers. ``` -------------------------------- ### pub fn try_new_uninit() -> Result>, AllocError> Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new `Rc` with uninitialized contents, returning an error if the allocation fails. This is a nightly-only experimental API. ```APIDOC ## pub fn try_new_uninit() -> Result>, AllocError> ### Description Constructs a new `Rc` with uninitialized contents, returning an error if the allocation fails. This is a nightly-only experimental API. (`allocator_api`) ### Method Associated function ### Response #### Success Response (Rc>) - **Rc>** - A new reference-counted pointer to an uninitialized value if allocation succeeds. #### Error Response (AllocError) - **AllocError** - An error indicating that the allocation failed. ``` -------------------------------- ### Constructing Rc with a Specific Allocator Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Shows how to create a new `Rc` instance using a specified allocator, leveraging the `allocator_api` feature. This allows for custom memory management strategies. ```rust #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let five = Rc::new_in(5, System); ``` -------------------------------- ### Get Specific Attribute Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.XmlElement.html Retrieves a specific attribute's value from an XmlElement by its name, if it exists. ```rust pub fn get_attr(&self, attr_name: &str) -> Option<&str> ``` -------------------------------- ### Get Element Attributes Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.XmlElement.html Retrieves a HashMap containing the attributes of the XML element, where keys and values are strings. ```rust pub fn attributes(&self) -> &HashMap ``` -------------------------------- ### Create Rc with Custom Allocator and Convert to Raw Pointer Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates creating an Rc with a specific allocator and converting it to a raw pointer. The raw pointer is then converted back to an Rc to prevent memory leaks. ```rust #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let x = Rc::new_in("hello".to_owned(), System); let (x_ptr, _alloc) = Rc::into_raw_with_allocator(x); unsafe { // Convert back to an `Rc` to prevent leak. let x = Rc::from_raw_in(x_ptr, System); assert_eq!(&*x, "hello"); // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe. } // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling! ``` -------------------------------- ### parse_start_namespace Function Signature Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/fn.parse_start_namespace.html This is the function signature for parse_start_namespace. It takes a mutable cursor to the AXML buffer, a slice of strings, and a mutable hash map for namespaces, returning a Result. ```rust pub fn parse_start_namespace( axml_buff: &mut Cursor>, strings: &[String], namespaces: &mut HashMap, ) -> Result<(), AxmlError> ``` -------------------------------- ### Rc::strong_count Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Gets the number of strong (Rc) pointers to this allocation. This count determines if the allocation is kept alive. ```APIDOC ## Rc::strong_count ### Description Gets the number of strong (`Rc`) pointers to this allocation. This count determines if the allocation is kept alive. ### Method `strong_count` ### Parameters #### Path Parameters - **this** (`&Rc`) - Required - The `Rc` to query the strong count for. ### Response #### Success Response - **usize** - The number of strong (`Rc`) pointers. ``` -------------------------------- ### new_uninit_in Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new `Rc` with uninitialized contents within a specified allocator. This is an experimental API. ```APIDOC ## pub fn new_uninit_in(alloc: A) -> Rc, A> ### Description Constructs a new `Rc` with uninitialized contents in the provided allocator. This is a nightly-only experimental API. ### Method `Rc::new_uninit_in` ### Parameters #### Path Parameters - **alloc** (`A`) - Required - The allocator to use. ### Response #### Success Response (Rc, A>) - A new `Rc` instance with uninitialized contents, using the specified allocator. ### Request Example ```rust #![feature(get_mut_unchecked)] #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let mut five = Rc::::new_uninit_in(System); let five = unsafe { // Deferred initialization: Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); five.assume_init() }; assert_eq!(*five, 5) ``` ``` -------------------------------- ### try_new_uninit_in Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new Rc with uninitialized contents, in the provided allocator, returning an error if the allocation fails. This is a nightly-only experimental API. ```APIDOC ## pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> ### Description Constructs a new `Rc` with uninitialized contents, in the provided allocator, returning an error if the allocation fails. This is a nightly-only experimental API. ### Method `try_new_uninit_in` ### Parameters #### Path Parameters - **alloc** (A) - Required - The allocator to use for memory allocation. ### Response #### Success Response - **Result, A>, AllocError>** - `Ok(Rc, A>)` if successful, `Err(AllocError)` if allocation fails. ### Examples ```rust #![feature(allocator_api)] #![feature(get_mut_unchecked)] use std::rc::Rc; use std::alloc::System; let mut five = Rc::::try_new_uninit_in(System)?; let five = unsafe { // Deferred initialization: Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); five.assume_init() }; assert_eq!(*five, 5); ``` ``` -------------------------------- ### Get Weak Reference Count of an Rc Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Shows how to retrieve the number of weak references pointing to an Rc's allocation. This is useful for monitoring. ```rust use std::rc::Rc; let five = Rc::new(5); let _weak_five = Rc::downgrade(&five); assert_eq!(1, Rc::weak_count(&five)); ``` -------------------------------- ### Compare Rc for Ordering Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Compares two Rc instances to determine their ordering. ```rust use std::rc::Rc; use std::cmp::Ordering; let five = Rc::new(5); assert_eq!(Ordering::Less, five.cmp(&Rc::new(6))); ``` -------------------------------- ### take Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.AxmlIterator.html Creates an iterator that yields the first `n` elements, or fewer if the underlying iterator ends sooner. ```APIDOC ## fn take(self, n: usize) -> Take ### Description Creates an iterator that yields the first `n` elements, or fewer if the underlying iterator ends sooner. ### Method `take` ### Parameters #### Path Parameters - **n** (usize) - Description: The number of elements to take. ### Returns - **Take** - An iterator that yields the first `n` elements. ``` -------------------------------- ### try_new_zeroed_in Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new Rc with uninitialized contents, with the memory being filled with 0 bytes, in the provided allocator, returning an error if the allocation fails. This is a nightly-only experimental API. ```APIDOC ## pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> ### Description Constructs a new `Rc` with uninitialized contents, with the memory being filled with `0` bytes, in the provided allocator, returning an error if the allocation fails. This is a nightly-only experimental API. ### Method `try_new_zeroed_in` ### Parameters #### Path Parameters - **alloc** (A) - Required - The allocator to use for memory allocation. ### Response #### Success Response - **Result, A>, AllocError>** - `Ok(Rc, A>)` if successful, `Err(AllocError)` if allocation fails. ### Examples ```rust #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let zero = Rc::::try_new_zeroed_in(System)?; let zero = unsafe { zero.assume_init() }; assert_eq!(*zero, 0); ``` ``` -------------------------------- ### From> for Rc Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Creates a reference-counted pointer from a clone-on-write pointer by copying its content. ```APIDOC ## fn from(cow: Cow<'a, B>) -> Rc ### Description Creates a reference-counted pointer from a clone-on-write pointer by copying its content. ### Method `from` ### Parameters - **cow** (Cow<'a, B>) - The clone-on-write pointer to convert. ### Response - **Rc** - A new reference-counted pointer containing the copied content. ``` -------------------------------- ### Get Mutable Reference if Unique Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Safely obtains a mutable reference to the inner value of an Rc if it's the only strong reference. Returns None otherwise. ```rust use std::rc::Rc; let mut x = Rc::new(3); *Rc::get_mut(&mut x).unwrap() = 4; assert_eq!(*x, 4); let _y = Rc::clone(&x); assert!(Rc::get_mut(&mut x).is_none()); ``` -------------------------------- ### pub fn try_new_zeroed() -> Result>, AllocError> Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new `Rc` with uninitialized contents, memory filled with `0` bytes, returning an error if allocation fails. This is a nightly-only experimental API. ```APIDOC ## pub fn try_new_zeroed() -> Result>, AllocError> ### Description Constructs a new `Rc` with uninitialized contents, with the memory being filled with `0` bytes, returning an error if the allocation fails. See `MaybeUninit::zeroed` for examples of correct and incorrect usage of this method. This is a nightly-only experimental API. (`allocator_api`) ### Method Associated function ### Response #### Success Response (Rc>) - **Rc>** - A new reference-counted pointer to an uninitialized value, zeroed out, if allocation succeeds. #### Error Response (AllocError) - **AllocError** - An error indicating that the allocation failed. ``` -------------------------------- ### get_exposed_components Source: https://docs.rs/rusty-axml/latest/index.html Parses an app's manifest and returns a list of all exposed components. ```APIDOC ## Function: get_exposed_components ### Description Parse an app’s manifest and get the list of exposed components. ### Signature get_exposed_components(root: &XmlNode) -> Vec ``` -------------------------------- ### Rust Rc Drop Example Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates the behavior of the Drop trait for Rc. The inner value is dropped only when the strong reference count reaches zero. ```rust use std::rc::Rc; struct Foo; impl Drop for Foo { fn drop(&mut self) { println!("dropped!"); } } let foo = Rc::new(Foo); let foo2 = Rc::clone(&foo); drop(foo); // Doesn't print anything drop(foo2); // Prints "dropped!" ``` -------------------------------- ### Constructing Uninitialized Rc with a Specific Allocator Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates the creation of an `Rc` with uninitialized contents using a specified allocator, utilizing the `allocator_api` and `get_mut_unchecked` features. This is useful for deferred initialization scenarios. ```rust #![feature(get_mut_unchecked)] #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let mut five = Rc::::new_uninit_in(System); let five = unsafe { // Deferred initialization: Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5); five.assume_init() }; assert_eq!(*five, 5) ``` -------------------------------- ### Rust Rc into_inner Example Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates using Rc::into_inner to consume an Rc and retrieve the inner value if it's the sole owner. If other Rc pointers exist, it returns None. ```rust use std::rc::Rc; let x = Rc::new(3); assert_eq!(Rc::into_inner(x), Some(3)); let x = Rc::new(4); let y = Rc::clone(&x); assert_eq!(Rc::into_inner(y), None); assert_eq!(Rc::into_inner(x), Some(4)); ``` -------------------------------- ### partition Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.AxmlIterator.html Consumes an iterator, creating two collections from it. ```APIDOC ## fn partition(self, f: F) -> (B, B) ### Description Splits the iterator's elements into two collections based on a predicate. ### Method `partition` ### Parameters #### Path Parameters - **f** (F) - Description: A closure that returns `true` if an element belongs to the first collection, and `false` otherwise. ### Type Parameters - **B**: The type of the collections, which must implement `Default` and `Extend`. ### Returns - **(B, B)** - A tuple containing two collections: one for elements satisfying the predicate, and one for those that do not. ``` -------------------------------- ### pub fn map(this: Rc, f: impl FnOnce(&T) -> U) -> Rc Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Maps the value in an `Rc`, reusing the allocation if possible. This is a nightly-only experimental API. ```APIDOC ## pub fn map(this: Rc, f: impl FnOnce(&T) -> U) -> Rc ### Description Maps the value in an `Rc`, reusing the allocation if possible. `f` is called on a reference to the value in the `Rc`, and the result is returned, also in an `Rc`. Note: this is an associated function, which means that you have to call it as `Rc::map(r, f)` instead of `r.map(f)`. This is so that there is no conflict with a method on the inner type. This is a nightly-only experimental API. (`smart_pointer_try_map`) ### Method Associated function ### Parameters #### Path Parameters - **this** (Rc) - Required - The `Rc` to map. - **f** (impl FnOnce(&T) -> U) - Required - A closure that takes a reference to the inner value and returns a new value. ### Response #### Success Response (Rc) - **Rc** - A new `Rc` containing the result of the closure. ``` -------------------------------- ### new_zeroed_in Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new Rc with uninitialized contents, with the memory being filled with 0 bytes, in the provided allocator. This is a nightly-only experimental API. ```APIDOC ## pub fn new_zeroed_in(alloc: A) -> Rc, A> ### Description Constructs a new `Rc` with uninitialized contents, with the memory being filled with `0` bytes, in the provided allocator. This is a nightly-only experimental API. ### Method `new_zeroed_in` ### Parameters #### Path Parameters - **alloc** (A) - Required - The allocator to use for memory allocation. ### Response #### Success Response - **Rc, A>** - A new `Rc` with zeroed uninitialized contents. ### Examples ```rust #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let zero = Rc::::new_zeroed_in(System); let zero = unsafe { zero.assume_init() }; assert_eq!(*zero, 0) ``` ``` -------------------------------- ### Get Receiver Names from AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_receivers_names.html Demonstrates how to use `get_receivers_names` to extract receiver names from an AXML file. This function is specifically for APK manifest files and returns an empty vector for other XML types. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::get_receivers_names(&axml).len(), 2) ``` -------------------------------- ### parse_start_element Function Signature Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/fn.parse_start_element.html This is the function signature for `parse_start_element`. It takes a mutable cursor to a byte vector, a slice of strings, and a hash map of namespace prefixes, returning a Result containing an XmlElement or an AxmlError. ```rust pub fn parse_start_element( axml_buff: &mut Cursor>, strings: &[String], namespace_prefixes: &HashMap, ) -> Result ``` -------------------------------- ### Unsafe Mutability with Rc::get_mut_unchecked Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates how to get a mutable reference to the inner value of an `Rc` when it's the only strong reference. This requires the `get_mut_unchecked` feature and must be used with extreme caution to avoid undefined behavior. ```rust #![feature(get_mut_unchecked)] use std::rc::Rc; let mut x = Rc::new(String::new()); unsafe { Rc::get_mut_unchecked(&mut x).push_str("foo") } assert_eq!(*x, "foo"); ``` -------------------------------- ### Get Activity Names from AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_activities_names.html Use this snippet to extract a list of activity names from a parsed AXML object, typically from an APK's manifest file. It returns an empty vector if the AXML is not an APK manifest. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::get_activities_names(&axml).len(), 1) ``` -------------------------------- ### Getting a raw pointer to Rc data Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Provides a raw pointer to the data contained within an Rc. The reference count is not affected, and the pointer remains valid as long as strong counts exist. This method is available on stable Rust. ```rust use std::rc::Rc; let x = Rc::new(0); let y = Rc::clone(&x); let x_ptr = Rc::as_ptr(&x); assert_eq!(x_ptr, Rc::as_ptr(&y)); assert_eq!(unsafe { *x_ptr }, 0); ``` -------------------------------- ### pub fn pin(value: T) -> Pin> Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new `Pin>`. If `T` does not implement `Unpin`, then `value` will be pinned in memory and unable to be moved. ```APIDOC ## pub fn pin(value: T) -> Pin> ### Description Constructs a new `Pin>`. If `T` does not implement `Unpin`, then `value` will be pinned in memory and unable to be moved. ### Method Associated function ### Parameters #### Path Parameters - **value** (T) - Required - The value to be pinned and wrapped in an `Rc`. ### Response #### Success Response (Pin>) - **Pin>** - A pinned reference-counted pointer to the value. ``` -------------------------------- ### Get Declared Permissions from AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_declared_permissions.html Retrieves a list of declared permissions from an AXML file. This function is specifically for APK manifest files; it returns an empty vector for other XML types. Ensure the AXML is correctly parsed before calling this function. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::get_declared_permissions(&axml).len(), 2) ``` -------------------------------- ### pub fn try_new(value: T) -> Result, AllocError> Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new `Rc`, returning an error if the allocation fails. This is a nightly-only experimental API. ```APIDOC ## pub fn try_new(value: T) -> Result, AllocError> ### Description Constructs a new `Rc`, returning an error if the allocation fails. This is a nightly-only experimental API. (`allocator_api`) ### Method Associated function ### Parameters #### Path Parameters - **value** (T) - Required - The value to be wrapped in an `Rc`. ### Response #### Success Response (Rc) - **Rc** - A new reference-counted pointer to the value if allocation succeeds. #### Error Response (AllocError) - **AllocError** - An error indicating that the allocation failed. ``` -------------------------------- ### Rc::into_raw_with_allocator Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Consumes the Rc, returning the raw pointer to the data and the allocator. The pointer must be converted back to an Rc using `Rc::from_raw_in` to avoid memory leaks. This is a nightly-only experimental API. ```APIDOC ## Rc::into_raw_with_allocator ### Description Consumes the `Rc`, returning the wrapped pointer and allocator. To avoid a memory leak, the pointer must be converted back to an `Rc` using `Rc::from_raw_in`. ### Method Associated function (called as `Rc::into_raw_with_allocator(r)`) ### Parameters - **this** (Rc) - The `Rc` to consume. ### Type Parameters - **T**: The type of the value. - **A**: The allocator type. ### Returns - `(*const T, A)` - A tuple containing the raw pointer and the allocator. ### Examples ```rust #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let x = Rc::new_in("hello".to_owned(), System); let (ptr, alloc) = Rc::into_raw_with_allocator(x); assert_eq!(unsafe { &*ptr }, "hello"); let x = unsafe { Rc::from_raw_in(ptr, alloc) }; assert_eq!(&*x, "hello"); ``` ``` -------------------------------- ### Undefined Behavior with Lifetime Mismatches in Rc::get_mut_unchecked Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Shows undefined behavior resulting from lifetime mismatches when using `Rc::get_mut_unchecked` with `Rc<&str>`. This example emphasizes that `Rc` pointers must refer to allocations with identical types and lifetimes. ```rust #![feature(get_mut_unchecked)] use std::rc::Rc; let x: Rc<&str> = Rc::new("Hello, world!"); { let s = String::from("Oh, no!"); let mut y: Rc<&str> = x.clone(); unsafe { // this is Undefined Behavior, because x's inner type // is &'long str, not &'short str *Rc::get_mut_unchecked(&mut y) = &s; } } println!("{}", &*x); // Use-after-free ``` -------------------------------- ### Get Requested Permissions from AXML Source: https://docs.rs/rusty-axml/latest/rusty_axml/fn.get_requested_permissions.html Retrieves a list of requested permissions from a parsed AXML object. This function is specifically for APK manifest files; it returns an empty vector for other XML types or if no permissions are declared. Ensure the AXML is correctly parsed before calling. ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert_eq!(rusty_axml::get_requested_permissions(&axml).len(), 3) ``` -------------------------------- ### Write XmlElement to Writer Source: https://docs.rs/rusty-axml/latest/src/rusty_axml/parser.rs.html Writes an XmlElement, including its attributes and children, to a quick_xml Writer. Handles empty elements and recursively writes child elements. ```rust fn write_element(&self, writer: &mut Writer) -> Result<(), Error> { let mut element = writer.create_element(&self.element_type); element = if self.attributes.is_empty() { element } else { element.with_attributes( self.attributes .iter() .map(|(k, v)| (k.as_str(), v.as_str())) .collect::>() ) }; if self.children.is_empty() { element.write_empty().unwrap(); } else { element .write_inner_content(|writer| -> Result<(), Error> { for child in self.children.iter() { child.as_ref().borrow().write_element(writer).unwrap(); } Ok(()) }) .unwrap(); } Ok(()) } ``` -------------------------------- ### create_cursor_from_axml Source: https://docs.rs/rusty-axml/latest/src/rusty_axml/lib.rs.html Creates a cursor of bytes from an AXML file. This function opens an AXML file, reads its contents, and creates a `Cursor` of the raw data for easier handling when parsing the XML data. It expects the file path to point to an AXML file. To read the manifest from an APK file use [`create_cursor_from_apk`] instead. ```APIDOC ## create_cursor_from_axml ### Description Creates a cursor of bytes from an AXML file. This function opens an AXML file, reads its contents, and creates a `Cursor` of the raw data for easier handling when parsing the XML data. It expects the file path to point to an AXML file. To read the manifest from an APK file use [`create_cursor_from_apk`] instead. ### Method ``` pub fn create_cursor_from_axml>(file_path: P) -> Result>, AxmlError> ``` ### Parameters * `file_path` (P: AsRef): The path to the AXML file. ### Returns * `Result>, AxmlError>`: A `Cursor` containing the raw AXML data if successful, otherwise an `AxmlError`. ### Example ```rust let cursor = rusty_axml::create_cursor_from_axml("tests/assets/AndroidManifest.xml").unwrap(); let axml = rusty_axml::parse_from_cursor(cursor).unwrap(); assert!(rusty_axml::get_requested_permissions(&axml) .contains(&"android.permission.ACCESS_FINE_LOCATION".to_string())) ``` ``` -------------------------------- ### by_ref Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/struct.AxmlIterator.html Creates a “by reference” adapter for this instance of `Iterator`. ```APIDOC ## fn by_ref(&mut self) -> &mut Self ### Description Creates an adapter that allows borrowing the iterator by reference, enabling methods that consume `&mut self` to be called on a mutable reference to the iterator. ### Method `by_ref` ### Returns - **&mut Self** - A mutable reference to the iterator. ``` -------------------------------- ### Handling XML Element Chunks in Rusty AXML Parser Source: https://docs.rs/rusty-axml/latest/src/rusty_axml/parser.rs.html Illustrates the logic for processing `ResXmlStartElementType` and `ResXmlEndElementType` chunks within the AXML parsing loop. It shows how elements are added to the stack and how the cursor is updated. ```rust ChunkType::ResXmlStartElementType => { let new_element = parse_start_element(&mut axml_cursor, &global_strings)?; if let Some(parent) = stack.last() { parent.borrow_mut().children.push(Rc::clone(&new_element)); } stack.push(new_element); }, ChunkType::ResXmlEndElementType => { parse_end_element(&mut axml_cursor, &global_strings)?; stack.pop(); }, ``` -------------------------------- ### Convert AXML to String Source: https://docs.rs/rusty-axml/latest/src/rusty_axml/parser.rs.html Converts the entire parsed AXML document into a formatted XML string. Initializes a quick_xml Writer with indentation and writes the XML declaration and root element. ```rust pub fn to_string(&self) -> Result { let mut writer = Writer::new_with_indent(Vec::new(), b' ', 4); writer .write_event(Event::Decl(BytesDecl::new("1.0", Some("utf-8"), None)))?; self.root.borrow().write_element(&mut writer)?; let result = std::str::from_utf8(&writer.into_inner())? .to_string(); Ok(result) } ``` -------------------------------- ### Try Clone Rc from Reference with Allocator API (Nightly) Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Attempts to construct a new Rc by cloning the referenced value, returning an error if allocation fails. Requires nightly and allocator_api feature. ```rust #![feature(clone_from_ref)] #![feature(allocator_api)] use std::rc::Rc; let hello: Rc = Rc::try_clone_from_ref("hello")?; ``` -------------------------------- ### Attempting to construct an uninitialized Rc> with fallible allocation Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Use `Rc::try_new_uninit` for a fallible construction of an uninitialized `Rc` that returns a `Result>, AllocError>` if the allocation fails. This is an experimental API. ```rust #![feature(allocator_api)] use std::rc::Rc; let mut five = Rc::::try_new_uninit()?; // Deferred initialization: Rc::get_mut(&mut five).unwrap().write(5); let five = unsafe { five.assume_init() }; assert_eq!(*five, 5); ``` -------------------------------- ### create_cursor_from_apk Source: https://docs.rs/rusty-axml/latest/index.html Creates a cursor of bytes from an APK file, which can then be used for parsing AXML data. ```APIDOC ## Function: create_cursor_from_apk ### Description Create cursor of bytes from an APK. ### Signature create_cursor_from_apk(apk_path: &str) -> Result ``` -------------------------------- ### try_new_in Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new Rc in the provided allocator, returning an error if the allocation fails. This is a nightly-only experimental API. ```APIDOC ## pub fn try_new_in(value: T, alloc: A) -> Result, AllocError> ### Description Constructs a new `Rc` in the provided allocator, returning an error if the allocation fails. This is a nightly-only experimental API. ### Method `try_new_in` ### Parameters #### Path Parameters - **value** (T) - Required - The value to be placed in the `Rc`. - **alloc** (A) - Required - The allocator to use for memory allocation. ### Response #### Success Response - **Result, AllocError>** - `Ok(Rc)` if successful, `Err(AllocError)` if allocation fails. ### Examples ```rust #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let five = Rc::try_new_in(5, System); ``` ``` -------------------------------- ### Rc::clone_from_ref_in Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Constructs a new Rc with a clone of the provided value, using the specified allocator. This is a nightly-only experimental API. ```APIDOC ## Rc::clone_from_ref_in ### Description Constructs a new `Rc` with a clone of `value` in the provided allocator. This is a nightly-only experimental API. ### Method Associated function (called as `Rc::clone_from_ref_in(value, alloc)`) ### Parameters - **value** (&T) - A reference to the value to be cloned. - **alloc** (A) - The allocator to use for the new `Rc`. ### Type Parameters - **T**: The type of the value. - **A**: The allocator type. ### Returns - `Rc` - A new `Rc` containing a clone of the value. ### Examples ```rust #![feature(clone_from_ref)] #![feature(allocator_api)] use std::rc::Rc; use std::alloc::System; let hello: Rc = Rc::clone_from_ref_in("hello", System); ``` ``` -------------------------------- ### Create Weak Pointer from Rc Source: https://docs.rs/rusty-axml/latest/rusty_axml/parser/type.XmlNode.html Demonstrates creating a weak pointer from an existing Rc. Weak pointers do not keep the allocation alive. ```rust use std::rc::Rc; let five = Rc::new(5); let weak_five = Rc::downgrade(&five); ```