Struct UserStrings

pub struct UserStrings<'a> { /* private fields */ }
Expand description

The UserStrings object provides helper methods to access the data within the ‘#US’ heap.

This heap contains all user-defined string literals from the source code, stored in UTF-16 encoding with length prefixes. Each string is referenced by its byte offset from metadata tables like the Constant table when the constant type is a string literal.

The heap format follows ECMA-335 specification with:

  • Index 0 always contains a null byte
  • Each string prefixed by its total byte length (including terminal byte)
  • UTF-16 encoded string data followed by null terminator and terminal byte

§Examples

use dotscope::metadata::streams::UserStrings;

// Create from heap data
let data = &[0u8, 65, 0, 0, 0];
let us = UserStrings::from(data)?;
let s = us.get(1)?;
assert_eq!(s.to_string_lossy(), "A");

§Iteration Example

use dotscope::metadata::streams::UserStrings;

let data = &[0u8, 0x05, 0x48, 0x00, 0x69, 0x00, 0x00, 0x00]; // "Hi"
let heap = UserStrings::from(data)?;

for result in heap.iter() {
    let (offset, string) = result?;
    println!("String at offset {}: {}", offset, string.to_string_lossy());
}

§Reference

User strings heap data accessor

Provides safe access to UTF-16 encoded string literals stored in the #US metadata heap. The heap data must start with a null byte at index 0, followed by length-prefixed strings.

Implementations§

§

impl<'a> UserStrings<'a>

pub fn from(data: &'a [u8]) -> Result<UserStrings<'a>>

Create a UserStrings object from a sequence of bytes

Validates that the heap data starts with the required null byte at index 0 according to ECMA-335 specification. The heap may contain multiple UTF-16 strings with length prefixes.

§Arguments
  • data - The byte slice containing the user strings heap data
§Returns
§Examples
use dotscope::metadata::streams::UserStrings;

// Valid heap data
let data = &[0x00, 0x05, 0x48, 0x00, 0x69, 0x00, 0x00, 0x00]; // null + "Hi"
let heap = UserStrings::from(data)?;

pub fn get(&self, index: usize) -> Result<&'a U16CStr>

Get a view into the string contained at the provided location.

Retrieves a UTF-16 string reference from the heap at the specified byte offset. The method processes the length prefix and validates the string data according to ECMA-335 format specifications.

§Arguments
  • index - The byte offset within the heap (typically from metadata table references)
§Returns
  • Ok(&U16CStr) - Reference to the UTF-16 string at the specified offset
  • Err(crate::Error::OutOfBounds) - If index is out of bounds
  • Err(crate::Error) - If string data is malformed or has invalid UTF-16 length
§Examples
use dotscope::metadata::streams::UserStrings;

let data = &[0x00, 0x05, 0x48, 0x00, 0x69, 0x00, 0x00, 0x00]; // "Hi"
let heap = UserStrings::from(data)?;
let string = heap.get(1)?;
assert_eq!(string.to_string_lossy(), "Hi");
§Panics

May panic if the underlying slice conversion fails due to memory alignment issues

pub fn iter(&self) -> UserStringsIterator<'_>

Returns an iterator over all user strings in the heap

Provides zero-copy access to all UTF-16 user strings with their byte offsets. Each iteration yields a Result<(usize, &U16CStr)> with the offset and string content. The iterator automatically handles length prefixes and skips the initial null entry.

§Returns
§Examples
use dotscope::metadata::streams::UserStrings;

let data = &[0u8, 0x05, 0x48, 0x00, 0x69, 0x00, 0x00, 0x00]; // "Hi" in UTF-16
let user_strings = UserStrings::from(data)?;

for result in user_strings.iter() {
    match result {
        Ok((offset, string)) => println!("String at {}: '{}'", offset, string.to_string_lossy()),
        Err(e) => eprintln!("Error: {}", e),
    }
}

Trait Implementations§

§

impl<'a> IntoIterator for &'a UserStrings<'a>

§

fn into_iter(self) -> Self::IntoIter

Create an iterator over the user strings heap.

This allows using for loops directly on crate::metadata::streams::UserStrings references.

§Examples
use dotscope::metadata::streams::UserStrings;

let data = &[0u8, 0x05, 0x48, 0x00, 0x69, 0x00, 0x00, 0x00];
let heap = UserStrings::from(data)?;

for result in &heap {
    let (offset, string) = result?;
    println!("String: {}", string.to_string_lossy());
}
§

type Item = Result<(usize, &'a U16CStr), Error>

The type of the elements being iterated over.
§

type IntoIter = UserStringsIterator<'a>

Which kind of iterator are we turning this into?

Auto Trait Implementations§

§

impl<'a> Freeze for UserStrings<'a>

§

impl<'a> RefUnwindSafe for UserStrings<'a>

§

impl<'a> Send for UserStrings<'a>

§

impl<'a> Sync for UserStrings<'a>

§

impl<'a> Unpin for UserStrings<'a>

§

impl<'a> UnwindSafe for UserStrings<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.