pkbuffer 0.7.0

Buffer objects made for arbitrary casting and addressing!
Documentation
# Changelog

## 0.7.0
### Features
* Added alignment-verified reference methods to the `Buffer` trait:
  * `get_aligned_ref<T: Copy>(&self, offset: usize) -> Result<&T, Error>` - returns a reference after verifying alignment
  * `get_aligned_mut<T: Copy>(&mut self, offset: usize) -> Result<&mut T, Error>` - returns a mutable reference after verifying alignment
* Added `Error::AlignmentMismatch(usize, usize)` error variant for reporting alignment violations

### Benefits
- Alignment is verified at runtime with an O(1) check before creating references
- Provides a safe alternative to pointer casting for well-aligned data
- Enables direct in-place mutation via mutable references without copy-out-and-reload

### Example
```rust
let mut buffer = VecBuffer::from_data(&[0u8; 16]);
// write via aligned reference
let val: &mut u32 = buffer.get_aligned_mut(0).unwrap();
*val = 0xDEADBEEF;  // writes directly, persists immediately
// misaligned access returns an error
assert!(buffer.get_aligned_ref::<u32>(1).is_err());
```

## 0.6.0
### Breaking Changes
This version removes the `Castable` trait entirely, eliminating all unsafe pointer casting from the crate.

**Removed:**
- The `Castable` unsafe marker trait and all implementations
- The `pkbuffer_derive` crate and `#[derive(Castable)]` macro
- All methods requiring `Castable`: `get_ref`, `get_mut_ref`, `get_slice_ref`, `get_mut_slice_ref`
- All unsafe unaligned methods: `get_ref_unaligned`, `get_mut_ref_unaligned`, `get_slice_ref_unaligned`, `get_mut_slice_ref_unaligned`
- All force methods: `force_get_ref`, `force_get_mut_ref`, `force_get_slice_ref`, `force_get_mut_slice_ref`, `force_make_mut_ref`, `force_make_mut_slice_ref`
- Typed reference methods: `write_ref`, `write_slice_ref`, `make_mut_ref`, `make_mut_slice_ref`, `search_ref`, `search_slice_ref`, `contains_ref`, `contains_slice_ref`
- Helper functions: `ref_to_bytes`, `slice_ref_to_bytes`, `bytes_to_ref`, `bytes_to_mut_ref`, `ref_to_mut_bytes`, `slice_ref_to_mut_bytes`
- VecBuffer methods: `append_ref`, `append_slice_ref`
- Error variants: `BadAlignment`, `ZeroSizedType`

**Safe API (what to use instead):**
- `read_val<T: Copy>(offset)` returns a `T` by safe byte-copy
- `write_val<T: Copy>(offset, &data)` writes a `T` by safe byte-copy
- `append_val<T: Copy>(&data)` appends a `T` by safe byte-copy
- `append_slice_val<T: Copy>(&[T])` appends a slice by safe byte-copy
- `search(&[u8])` searches for raw bytes
- `contains(&[u8])` checks for raw byte presence

**Why:**
The `Castable` trait and its methods relied on unsafe pointer casting to return typed references, which is undefined behavior on misaligned addresses in Rust 1.94+ debug mode. The new safe byte-copy API works correctly regardless of alignment on all platforms and in both debug and release builds.

## 0.5.1
### Bugfixes
* re-introduced unaligned memory access behavior that was present in pre-Rust 1.94 versions
* `get_ref_unaligned`, `get_slice_ref_unaligned`, and `get_mut_ref_unaligned` now perform direct unaligned pointer dereferences which work correctly on x86 in release builds
* Note: Rust 1.94+ debug builds will panic on misaligned access - this is expected and only affects debug mode. Release builds work correctly.

### Known Issues
* Debug builds with Rust 1.94+ will panic on unaligned memory access. Use release builds for testing.

## 0.5.0
### Features
- added `try_` variants of operations that would otherwise panic on invalid inputs:
  - `try_swap`, `try_reverse`, `try_rotate_left`, `try_rotate_right`
  - `try_fill`, `try_fill_with`, `try_clone_from_data`, `try_copy_from_data`
  - `try_copy_within`, `try_swap_with_data`
  - `try_sort`, `try_sort_by`, `try_sort_by_key`, `try_repeat`

## 0.4.2
### Bugfixes
* fixes the general search function's runtime by using the memchr library's two-way search implementation, thanks to @Thell for reporting!

## 0.4.1
### Features
* added a dynamic search feature to buffers. Now you can search for a dynamic pattern of bytes, see the docs for more details!

## 0.4.0
### Bugfixes
* fixed the undefined behavior of `ref_to_bytes` and similar functions by taking inspiration from [bytemuck]https://crates.io/crate/bytemuck and actively preventing undefined behavior, thanks to @[repnop]https://github.com/repnop for reporting this! this changes the generic signatures to have the trait `Castable` (e.g., `T: Castable`) in multiple functions. see the docs for more details!
### Features
* objects acquired by `get_ref` and similar functions now require the `Castable` trait. this guarantees the safety of types acquired from byte buffers, see the docs for more details.
* with the addition of `Castable` comes alignment awareness. however, there are some cases (such as with PE files) where reading unaligned structures is necessary. as a result, `Buffer::get_ref_unaligned`, `Buffer::force_get_ref` and similar functions have been added to deal with unaligned objects.
* the `Castable` trait can be derived for any struct given it meets the requirements, see the docs for more details.

## 0.3.0
**This version makes major changes!** The `Buffer` struct is now a trait, and the struct has been converted to `PtrBuffer`. This simplifies the code and unifies the featureset without having to repeat code all over the place. Additionally, it gives the user the ability to define their own `Buffer` object.

### Bugfixes
* `IntoIter` was returning references when it should be returning values, this is fixed.
* `Error` now implements `Send` and `Sync`.
### Features
* `Buffer` is now a trait, which allows the featureset of both `VecBuffer` and the new `PtrBuffer` to be unified.
* `Error` now makes use of the `into()` function with regards to `std::io::Error`.

## 0.2.0
### Bugfixes
* ```Buffer``` object was not getting updated on clone in ```VecBuffer```. That's now fixed.
### Features
* ```Buffer::search``` and similar functions now return an iterator to all search results, including no search results.

## 0.1.0
### Features
* package released!
* created a buffer object that points to arbitrary memory locations via ```u8``` pointer
* created a vector-backed buffer object that points at the vector with extra vector features