ptr-utils

Crates.ioptr-utils
lib.rsptr-utils
version0.1.1
created_at2025-07-13 19:08:44.54171+00
updated_at2025-12-08 06:36:29.734008+00
descriptionA lightweight library providing utilities for working with raw pointers.
homepage
repositoryhttps://github.com/Sewer56/ptr-utils
max_upload_size
id1750705
size36,775
Sewer. (Sewer56)

documentation

README

ptr-utils

Crates.io Documentation CI License: MIT

Why This Library?

This library exists primarily for ergonomics. Compare writing pointer operations manually versus using ptr-utils:

Before (manual pointer casting):

/// # Safety
///
/// - input_ptr must be valid for reads of len bytes
/// - output_ptr must be valid for writes of len bytes
pub(crate) unsafe fn u32_untransform_with_separate_pointers(
    mut alpha_byte_in_ptr: *const u16,
    mut alpha_bit_in_ptr: *const u16,
    mut color_byte_in_ptr: *const u32,
    mut index_byte_in_ptr: *const u32,
    mut current_output_ptr: *mut u8,
    len: usize,
) {
    let alpha_byte_end_ptr = alpha_byte_in_ptr.add(len / 16);
    while alpha_byte_in_ptr < alpha_byte_end_ptr {
        // Alpha bytes (2 bytes)
        (current_output_ptr as *mut u16).write_unaligned(alpha_byte_in_ptr.read_unaligned());
        alpha_byte_in_ptr = alpha_byte_in_ptr.add(1);

        // Alpha bits (6 bytes)
        (current_output_ptr.add(2) as *mut u16).write_unaligned(alpha_bit_in_ptr.read_unaligned());
        (current_output_ptr.add(4) as *mut u32)
            .write_unaligned((alpha_bit_in_ptr.add(1) as *const u32).read_unaligned());
        alpha_bit_in_ptr = alpha_bit_in_ptr.add(3);

        // Color bytes (4 bytes)
        (current_output_ptr.add(8) as *mut u32).write_unaligned(color_byte_in_ptr.read_unaligned());
        color_byte_in_ptr = color_byte_in_ptr.add(1);

        // Index bytes (4 bytes)
        (current_output_ptr.add(12) as *mut u32)
            .write_unaligned(index_byte_in_ptr.read_unaligned());
        index_byte_in_ptr = index_byte_in_ptr.add(1);
        current_output_ptr = current_output_ptr.add(16);
    }
}

After (with ptr-utils):

use ptr_utils::{UnalignedRead, UnalignedWrite};

/// # Safety
///
/// - input_ptr must be valid for reads of len bytes
/// - output_ptr must be valid for writes of len bytes
pub(crate) unsafe fn u32_untransform_with_separate_pointers(
    mut alpha_byte_in_ptr: *const u16,
    mut alpha_bit_in_ptr: *const u16,
    mut color_byte_in_ptr: *const u32,
    mut index_byte_in_ptr: *const u32,
    mut current_output_ptr: *mut u8,
    len: usize,
) {
    let alpha_byte_end_ptr = alpha_byte_in_ptr.add(len / 16);
    while alpha_byte_in_ptr < alpha_byte_end_ptr {
        // Alpha bytes (2 bytes)
        current_output_ptr.write_u16_at(0, alpha_byte_in_ptr.read_u16_at(0));
        alpha_byte_in_ptr = alpha_byte_in_ptr.add(1);

        // Alpha bits (6 bytes)
        current_output_ptr.write_u16_at(2, alpha_bit_in_ptr.read_u16_at(0));
        current_output_ptr.write_u32_at(4, alpha_bit_in_ptr.read_u32_at(2));
        alpha_bit_in_ptr = alpha_bit_in_ptr.add(3);

        // Color bytes (4 bytes)
        current_output_ptr.write_u32_at(8, color_byte_in_ptr.read_u32_at(0));
        color_byte_in_ptr = color_byte_in_ptr.add(1);

        // Index bytes (4 bytes)
        current_output_ptr.write_u32_at(12, index_byte_in_ptr.read_u32_at(0));
        index_byte_in_ptr = index_byte_in_ptr.add(1);
        current_output_ptr = current_output_ptr.add(16);
    }
}

The library eliminates repetitive as *mut T and as *const T casts while maintaining the same safety contracts and zero-cost abstractions.

Installation

Add this to your Cargo.toml:

[dependencies]
ptr-utils = "0.1.0"

For no_std environments:

[dependencies]
ptr-utils = { version = "0.1.0", default-features = false }

Usage

Unaligned Read/Write Operations

Works with byte pointers as usual:

use ptr_utils::{UnalignedRead, UnalignedWrite};

let mut buffer = [0u8; 16];
let ptr = buffer.as_mut_ptr();

unsafe {
    // Write a u32 at byte offset 1 (unaligned)
    ptr.write_u32_at(1, 0x12345678);
    
    // Read it back
    let value = ptr.read_u32_at(1);
    assert_eq!(value, 0x12345678);
}

But you can also use it with pointers for other basic types:

use ptr_utils::{UnalignedRead, UnalignedWrite};

// Works with any pointer type
let mut data: [u64; 4] = [0; 4];
let typed_ptr: *mut u64 = data.as_mut_ptr();

unsafe {
    // No need to cast to *mut u8 first
    typed_ptr.write_u16_at(3, 0xABCD); // byte offset 3
    let value = typed_ptr.read_u16_at(3);
    assert_eq!(value, 0xABCD);
}

The operations always take byte offsets; for simplicity.

API Overview

UnalignedRead Trait

Provides unaligned read operations for both *const T and *mut T:

  • read_u8_at, read_u16_at, read_u32_at, read_u64_at, read_u128_at, read_usize_at
  • read_i8_at, read_i16_at, read_i32_at, read_i64_at, read_i128_at, read_isize_at
  • read_f32_at, read_f64_at
  • read_bool_at

UnalignedWrite Trait

Provides unaligned write operations for *mut T:

  • write_u8_at, write_u16_at, write_u32_at, write_u64_at, write_u128_at, write_usize_at
  • write_i8_at, write_i16_at, write_i32_at, write_i64_at, write_i128_at, write_isize_at
  • write_f32_at, write_f64_at
  • write_bool_at

Safety

This library provides unsafe functions that require careful use:

  • Ensure pointers are valid for the requested read/write operation
  • Verify that the memory range [ptr + offset, ptr + offset + size_of::<T>()) is accessible
  • For writes, ensure the memory is mutable
  • The caller is responsible for preventing data races in multi-threaded contexts

Cargo Features

  • std (default): Enables standard library support
  • Default features can be disabled for no_std environments

Developer Manual

For step-by-step development guidance, see the Developer Manual.

Contributing

We welcome contributions! See the Contributing Guide for details.

License

Licensed under MIT.

Commit count: 0

cargo fmt