pub trait BStackGuardedSlice<'a, A: BStackAllocator + 'a>where
Self: 'a,{
Show 40 methods
// Required methods
fn len(&self) -> u64;
unsafe fn raw_block(&self) -> BStackSlice<'a>;
// Provided methods
fn as_slice(&self) -> Result<BStackSlice<'a>, Error> { ... }
fn is_empty(&self) -> bool { ... }
fn decode<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>> { ... }
fn encode<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>> { ... }
fn on_read(&self, offset: u64, len: u64) -> Result<()> { ... }
fn on_write(&self, offset: u64, len: u64) -> Result<()> { ... }
fn pre_read(&self, _offset: u64, _len: u64) -> Result<()> { ... }
fn post_read<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>> { ... }
fn pre_write<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>> { ... }
fn post_write(&self, _offset: u64, _len: u64) -> Result<()> { ... }
fn start(&self) -> u64 { ... }
fn end(&self) -> u64 { ... }
fn range(&self) -> Range<u64> ⓘ { ... }
fn as_range(&self) -> BStackRange { ... }
fn stack(&self) -> &'a BStack ⓘ { ... }
fn read(&self) -> Result<Vec<u8>> { ... }
fn read_into(&self, buf: &mut [u8]) -> Result<()> { ... }
fn read_range(&self, start: u64, end: u64) -> Result<Vec<u8>> { ... }
fn read_range_into(&self, start: u64, buf: &mut [u8]) -> Result<()> { ... }
fn get(&self, index: u64) -> Result<Option<u8>> { ... }
fn contains(&self, needle: u8) -> Result<bool> { ... }
fn starts_with(&self, prefix: &[u8]) -> Result<bool> { ... }
fn ends_with(&self, suffix: &[u8]) -> Result<bool> { ... }
fn find(&self, needle: u8) -> Result<Option<u64>> { ... }
fn rfind(&self, needle: u8) -> Result<Option<u64>> { ... }
fn position(&self, predicate: impl Fn(u8) -> bool) -> Result<Option<u64>> { ... }
fn rposition(&self, predicate: impl Fn(u8) -> bool) -> Result<Option<u64>> { ... }
fn write(&self, data: impl AsRef<[u8]>) -> Result<()> { ... }
fn copy_from_slice(&self, src: &[u8]) -> Result<()> { ... }
fn write_range(&self, start: u64, data: impl AsRef<[u8]>) -> Result<()> { ... }
fn zero(&self) -> Result<()> { ... }
fn zero_range(&self, start: u64, n: u64) -> Result<()> { ... }
fn fill(&self, value: u8) -> Result<()> { ... }
fn fill_with(&self, f: impl FnMut() -> u8) -> Result<()> { ... }
fn process(&self, f: impl FnOnce(&mut [u8])) -> Result<()> { ... }
fn copy_within(&self, src: Range<u64>, dest: u64) -> Result<()> { ... }
fn to_owned_in<'b, B: BStackOwnedSliceAllocator>(
&self,
allocator: &'b B,
) -> Result<BStackOwnedSlice<'b, B>> { ... }
fn to_owned_uninit_in<'b, B>(
&self,
allocator: &'b B,
) -> Result<BStackOwnedSlice<'b, B>>
where B: BStackUninitAllocator + BStackOwnedSliceAllocator { ... }
}Expand description
A BStackSlice abstraction with lifecycle hooks for transparent I/O
interception.
A is the allocator type, given as a generic parameter so that a single
implementing struct can satisfy BStackGuardedSlice<'a, A> for any allocator
without being locked to one concrete choice.
§Required methods
Implement len and the unsafe
raw_block, which binds the trait to an
underlying BStackSlice; every other method has a working default.
as_slice defaults to returning
Unsupported — override it to expose an
apparent view when a meaningful one exists.
§Hooks
Override any combination of four hooks to intercept I/O:
| Hook | Role |
|---|---|
decode | Transform raw bytes read from disk into the apparent bytes. |
encode | Transform apparent bytes into the raw bytes written to disk. |
on_read | Observe or deny a read. Return Err to deny. |
on_write | Observe a completed write (audit, metadata). |
decode/encode default to identity (Cow::Borrowed, no allocation);
on_read/on_write default to no-ops. Both offsets are relative to
the start of the slice (0 is the first byte of this view).
decode/encode are whole-block transforms: read/write and the
derived range methods route the entire apparent block through them, which is
why a transforming guard (encryption, compression) can implement just
len, raw_block, decode, and encode.
§Deprecated hooks
The former hooks are deprecated since 0.4.4 and removed in 0.5.0:
post_read → decode, pre_write → encode, pre_read → on_read,
post_write → on_write. Note pre_read’s offset was absolute whereas
on_read’s is relative. The new hooks bridge to the old ones by default,
so an implementor overriding only the old hooks keeps working unchanged until
0.5.0.
§Borrow semantics
A guard sits at the same semantic position as BStackSlice: a borrowed I/O
view that owns no region and frees nothing on Drop. Because it binds only to
a BStackSlice it cannot hold a still-freeable region, and so inherits the
crate’s on-disk borrow soundness unchanged. See the module-level
documentation for the full argument.
§Lifetime
'a is the allocator lifetime, matching BStackSlice<'a>. All implementors
must satisfy Self: 'a and A: 'a. as_slice
and raw_block hand back BStackSlice<'a> at
that full lifetime — the borrowed-view convention shared with
BStackSlice::subslice, not the &self-scoped narrowing used by ownership
handles.
Required Methods§
Sourcefn len(&self) -> u64
fn len(&self) -> u64
The length of the data in this guarded view.
This should return the length of the apparent slice returned by as_slice,
not the underlying raw block length.
Sourceunsafe fn raw_block(&self) -> BStackSlice<'a>
unsafe fn raw_block(&self) -> BStackSlice<'a>
The raw I/O block for this guarded view.
A required method with no default: return the BStackSlice that
hooks and I/O actually operate on. It coincides with the apparent
as_slice view unless hooks operate on a
coarser granularity than the slice — for example, a block cipher that must
process aligned 16-byte blocks.
Can be used by custom subview implementations to issue reads against the full block rather than the narrowed sub-range.
§Safety
In general, calling this method is only safe when pre and post read/write
hooks are not active or are called during the call, otherwise the caller
may risk data corruption or undefined behavior. Prefer overriding as_slice
when possible.
Provided Methods§
Sourcefn as_slice(&self) -> Result<BStackSlice<'a>, Error>
fn as_slice(&self) -> Result<BStackSlice<'a>, Error>
The apparent slice for this guard view.
All I/O methods appears to operate within this slice, and all hooks
receive offsets relative to this slice. The implementation should only
return Some if the usage of this view is somehow safe and reflect
the actual underlying data. For example, exposing a cyphertext for
encrypted data does not help the caller to understand the actual plaintext
data, so for a guard that performs decryption, this method should return
None since there is no clear mapping between the apparent slice and the
underlying data.
The returned slice should have length equal to called len().
§Mutability and safety
The returned slice is read-only. Mutating the returned slice may cause data corruption or violate allocator invariants, unless the implementation explicitly allows it and documents the safety contract. If the implementation allows mutation, it must ensure that all hooks are properly fired on subsequent reads and writes, and that any necessary synchronization is performed to prevent data races or undefined behavior.
Sourcefn is_empty(&self) -> bool
fn is_empty(&self) -> bool
Returns true if this guarded view contains no data.
This is a convenience method that defaults to self.len() == 0.
Sourcefn decode<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
fn decode<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
Transform raw bytes read from the underlying store into the apparent bytes.
The inverse of encode. Called by
read with the whole raw block; return
Cow::Borrowed to pass through without allocation, or Cow::Owned for
decryption, decompression, or other transformations. The transformed
length should equal len.
Defaults to the deprecated post_read
(identity), for back-compat during the deprecation window.
Sourcefn encode<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
fn encode<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
Transform apparent bytes into the raw bytes written to the underlying store.
The inverse of decode. Called by
write with the whole apparent block; return
Cow::Borrowed to pass through, or Cow::Owned for encryption,
compression, or other transformations.
Defaults to the deprecated pre_write
(identity), for back-compat during the deprecation window.
Sourcefn on_read(&self, offset: u64, len: u64) -> Result<()>
fn on_read(&self, offset: u64, len: u64) -> Result<()>
Observe or deny a read of len raw bytes at offset.
offset is relative to the start of the slice; len is the number of
raw bytes about to be read (before decode).
Return Err to deny.
Defaults to bridging the deprecated
pre_read, whose offset was absolute: the
bridge adds the slice start, so an implementor overriding only pre_read
still receives the absolute offset it expects.
Sourcefn on_write(&self, offset: u64, len: u64) -> Result<()>
fn on_write(&self, offset: u64, len: u64) -> Result<()>
Observe a completed write of len logical bytes at offset.
offset is relative to the start of the slice; len is the number of
apparent bytes written (before encode). The
write has already succeeded; use for auditing or metadata.
Defaults to the deprecated post_write,
whose offset was already relative.
Sourcefn pre_read(&self, _offset: u64, _len: u64) -> Result<()>
👎Deprecated since 0.4.4: renamed to on_read; offset is now relative to the slice
fn pre_read(&self, _offset: u64, _len: u64) -> Result<()>
renamed to on_read; offset is now relative to the slice
Deprecated: renamed to on_read; its offset
is now relative to the slice, not absolute.
Sourcefn post_read<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
👎Deprecated since 0.4.4: renamed to decode
fn post_read<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
renamed to decode
Deprecated: renamed to decode.
Sourcefn pre_write<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
👎Deprecated since 0.4.4: renamed to encode
fn pre_write<'d>(&self, data: &'d [u8]) -> Result<Cow<'d, [u8]>>
renamed to encode
Deprecated: renamed to encode.
Sourcefn post_write(&self, _offset: u64, _len: u64) -> Result<()>
👎Deprecated since 0.4.4: renamed to on_write
fn post_write(&self, _offset: u64, _len: u64) -> Result<()>
renamed to on_write
Deprecated: renamed to on_write.
Sourcefn start(&self) -> u64
fn start(&self) -> u64
Absolute start offset of the raw block (raw_block().start()) within
the BStack payload.
This is a physical-storage coordinate. The apparent view is always
addressed as [0, len()); start locates where the raw (stored) bytes
actually live. For a pass-through guard (identity encode/decode) the two
coincide, but for a transforming
guard (encryption, compression) the raw span end - start is the encoded
size and differs from the apparent len. Parity
with BStackSlice::start.
Sourcefn end(&self) -> u64
fn end(&self) -> u64
Absolute exclusive end offset of the raw block
(start() + raw_block().len()).
A physical-storage coordinate; end - start is the encoded byte count,
which may exceed or fall short of the apparent
len for a transforming guard. Parity with
BStackSlice::end.
Sourcefn range(&self) -> Range<u64> ⓘ
fn range(&self) -> Range<u64> ⓘ
Half-open raw block byte range start()..end() within the
BStack payload.
The physical span the encoded bytes occupy, not the apparent [0, len())
view. Parity with BStackSlice::range.
Sourcefn as_range(&self) -> BStackRange
fn as_range(&self) -> BStackRange
The raw block location as a BStackRange — the physical
(offset, len) pair describing where the encoded bytes are stored.
Useful for recording or comparing storage locations; it is not the
apparent view, and its len is the encoded size rather than the decoded
len. Parity with BStackSlice::as_range.
Sourcefn stack(&self) -> &'a BStack ⓘ
fn stack(&self) -> &'a BStack ⓘ
The BStack backing this guard, borrowed for the full
allocator lifetime 'a.
Every guard I/O method ultimately reads from and writes to this store;
stack hands out the same reference for callers that need to issue their
own operations against it (for example, cross-region atomics that take a
&BStack). Parity with BStackSlice::stack.
Sourcefn read(&self) -> Result<Vec<u8>>
fn read(&self) -> Result<Vec<u8>>
Read the entire apparent slice — the decoded bytes — into a newly allocated
Vec<u8>.
Fires on_read(0, raw_len), reads the raw
block, then passes it through decode; the
decoded length may differ from the raw length. Allocates up to twice the raw
length — once for the raw read, and again for the decoded output whenever
decode returns Cow::Owned. A pass-through guard (identity decode)
returns Cow::Borrowed and so allocates only the raw read.
Sourcefn read_into(&self, buf: &mut [u8]) -> Result<()>
fn read_into(&self, buf: &mut [u8]) -> Result<()>
Read the entire apparent slice (the decoded bytes) into buf.
buf.len() must equal the decoded length, otherwise returns InvalidInput.
Unlike BStackSlice::read_into, this does not avoid allocation. It
reads the raw block into a temporary Vec and runs
decode (which may allocate again) before
copying the result into buf — the caller’s buffer is not read into
directly. Use it for the exact-length delivery and length check, not to save
an allocation; when you want the bytes owned anyway, prefer
read.
Sourcefn read_range(&self, start: u64, end: u64) -> Result<Vec<u8>>
fn read_range(&self, start: u64, end: u64) -> Result<Vec<u8>>
Read the apparent sub-range [start, end) into a newly allocated Vec<u8>.
There is no partial decode: this reads and decodes the whole block (via
read) and then copies out the requested
sub-range. Returns InvalidInput if start > end or end exceeds the
apparent len. Parity with
BStackSlice::read_range, but note the whole-block read and the extra
allocation.
Sourcefn read_range_into(&self, start: u64, buf: &mut [u8]) -> Result<()>
fn read_range_into(&self, start: u64, buf: &mut [u8]) -> Result<()>
Read the apparent sub-range [start, start + buf.len()) into buf.
Like read_range, this decodes the
whole block into a temporary Vec first and then copies the sub-range
into buf — so, unlike BStackSlice::read_range_into, it allocates and
reads more than the requested range. Returns InvalidInput if the range
exceeds the apparent len.
Sourcefn get(&self, index: u64) -> Result<Option<u8>>
fn get(&self, index: u64) -> Result<Option<u8>>
Read the byte at apparent index index, or None if out of range.
Like every scan/search convenience here
(contains,
find,
position, and the rest), this reads and
decodes the whole apparent block on each call. To run several queries,
call read once and scan the returned Vec
yourself. Parity with BStackSlice::get.
Sourcefn contains(&self, needle: u8) -> Result<bool>
fn contains(&self, needle: u8) -> Result<bool>
Whether the apparent bytes contain needle. Parity with
BStackSlice::contains.
Sourcefn starts_with(&self, prefix: &[u8]) -> Result<bool>
fn starts_with(&self, prefix: &[u8]) -> Result<bool>
Whether the apparent bytes start with prefix. Parity with
BStackSlice::starts_with.
Sourcefn ends_with(&self, suffix: &[u8]) -> Result<bool>
fn ends_with(&self, suffix: &[u8]) -> Result<bool>
Whether the apparent bytes end with suffix. Parity with
BStackSlice::ends_with.
Sourcefn find(&self, needle: u8) -> Result<Option<u64>>
fn find(&self, needle: u8) -> Result<Option<u64>>
Apparent index of the first byte equal to needle. Parity with
BStackSlice::find.
Sourcefn rfind(&self, needle: u8) -> Result<Option<u64>>
fn rfind(&self, needle: u8) -> Result<Option<u64>>
Apparent index of the last byte equal to needle. Parity with
BStackSlice::rfind.
Sourcefn position(&self, predicate: impl Fn(u8) -> bool) -> Result<Option<u64>>
fn position(&self, predicate: impl Fn(u8) -> bool) -> Result<Option<u64>>
Apparent index of the first byte satisfying predicate. Parity with
BStackSlice::position.
Sourcefn rposition(&self, predicate: impl Fn(u8) -> bool) -> Result<Option<u64>>
fn rposition(&self, predicate: impl Fn(u8) -> bool) -> Result<Option<u64>>
Apparent index of the last byte satisfying predicate. Parity with
BStackSlice::rposition.
Sourcefn copy_from_slice(&self, src: &[u8]) -> Result<()>
fn copy_from_slice(&self, src: &[u8]) -> Result<()>
Overwrite the whole apparent slice with src; src.len() must equal
len. Parity with
BStackSlice::copy_from_slice (returns InvalidInput on mismatch rather
than panicking). Requires feature set.
Sourcefn write_range(&self, start: u64, data: impl AsRef<[u8]>) -> Result<()>
fn write_range(&self, start: u64, data: impl AsRef<[u8]>) -> Result<()>
Overwrite the apparent sub-range at start with data, atomic
read-modify-write.
One crash-atomic BStack::process_gen: decodes
the whole block, splices data in at start, re-encodes, and writes — the
only correct way to patch a transformed (e.g. AEAD) block, all under one write
lock. The internal read does not fire
on_read; only
on_write(start, data.len()) fires. Parity
with BStackSlice::write_range. Requires features set and atomic.
Sourcefn zero(&self) -> Result<()>
fn zero(&self) -> Result<()>
Zero the whole apparent slice — writes encode(&[0; len]).
Zeroes the apparent (decoded) content, not the raw storage: for a
transforming guard the bytes on disk become the encoding of zeros (e.g. the
ciphertext of a zero block), not literal 0x00. To scrub the raw bytes,
operate on the underlying BStackSlice directly. Requires feature set.
Sourcefn zero_range(&self, start: u64, n: u64) -> Result<()>
fn zero_range(&self, start: u64, n: u64) -> Result<()>
Zero the apparent sub-range [start, start + n), atomic read-modify-write.
Parity with BStackSlice::zero_range. Requires features set and atomic.
Sourcefn fill(&self, value: u8) -> Result<()>
fn fill(&self, value: u8) -> Result<()>
Fill the whole apparent slice with value — writes encode(&[value; len]).
Sets the apparent content; like zero, the raw
bytes on disk are the encoding of the fill, not value repeated. Parity
with BStackSlice::fill. Requires feature set.
Sourcefn fill_with(&self, f: impl FnMut() -> u8) -> Result<()>
fn fill_with(&self, f: impl FnMut() -> u8) -> Result<()>
Fill the whole apparent slice by calling f once per apparent byte, then
writing encode of the result.
f generates the apparent (decoded) bytes; the raw storage is their
encoding. Parity with BStackSlice::fill_with. Requires feature set.
Sourcefn process(&self, f: impl FnOnce(&mut [u8])) -> Result<()>
fn process(&self, f: impl FnOnce(&mut [u8])) -> Result<()>
Transform the whole apparent block in place, atomic read-modify-write.
One crash-atomic BStack::process_gen: decodes
the block, hands it to f as a length-preserving mutable slice, re-encodes,
and writes — all under one write lock. The internal read does not fire
on_read; only
on_write(0, len) fires, after the write.
The general form of write_range/zero/fill. Requires features set and
atomic.
Sourcefn copy_within(&self, src: Range<u64>, dest: u64) -> Result<()>
fn copy_within(&self, src: Range<u64>, dest: u64) -> Result<()>
Copy the apparent sub-range src to dest within the slice, atomic
read-modify-write. Parity with BStackSlice::copy_within. Requires
features set and atomic.
Sourcefn to_owned_in<'b, B: BStackOwnedSliceAllocator>(
&self,
allocator: &'b B,
) -> Result<BStackOwnedSlice<'b, B>>
fn to_owned_in<'b, B: BStackOwnedSliceAllocator>( &self, allocator: &'b B, ) -> Result<BStackOwnedSlice<'b, B>>
Copy this view’s apparent bytes into a fresh allocation from allocator,
returning a plain BStackOwnedSlice.
The bytes are decoded on the way out, so the result holds
the apparent block, not the raw one, and is a plain region with no guard
attached. Unlike BStackSlice::to_owned_in, which copies on disk via one
atomic primitive, this necessarily routes through memory — decoding cannot
happen on disk — so it needs only the set feature.
§Errors
Any io::Error from the read, the allocation, or the copy. If the copy
fails after the allocation succeeds, the fresh region is freed on a
best-effort basis before returning the copy error; if that free itself
fails, the region is left allocated but unreferenced (reclaimable by the
allocator’s recovery).
Sourcefn to_owned_uninit_in<'b, B>(
&self,
allocator: &'b B,
) -> Result<BStackOwnedSlice<'b, B>>where
B: BStackUninitAllocator + BStackOwnedSliceAllocator,
fn to_owned_uninit_in<'b, B>(
&self,
allocator: &'b B,
) -> Result<BStackOwnedSlice<'b, B>>where
B: BStackUninitAllocator + BStackOwnedSliceAllocator,
Like to_owned_in, but skips the destination’s
zero-fill via alloc_uninit.
The fresh region is fully overwritten by the copy, so the zero-fill alloc
would perform is pure waste here.
§Errors
As to_owned_in.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".