Struct scroll_buffer::DynamicBuffer[][src]

pub struct DynamicBuffer { /* fields omitted */ }
Expand description

A buffer designed for Pwrite that dynamically expands to hold all types written into it. Uses a standard Vec under the hood.

Use Cases

  • You don’t know exactly how much you’re writing ahead of time.
  • Your types change size depending on context parameters or specific values.

Allocations

By default, this buffer expands every time one byte is written. The with_increment constructor can be used to change how much the buffer expands to reduce overall number of allocations.

Pwrite and TryIntoCtx

Types must implement TryIntoCtx with a second generic parameter of DynamicBuffer to be used.

use scroll::{ctx::TryIntoCtx, Error, LE, Pwrite};
use scroll_buffer::DynamicBuffer;

struct EvenOdd(u32);

impl TryIntoCtx<(), DynamicBuffer> for EvenOdd {
    type Error = Error;

    fn try_into_ctx(self, buf: &mut DynamicBuffer, _: ()) -> Result<usize, Self::Error> {
        let offset = &mut 0;

        if self.0 % 2 == 0 {
            buf.gwrite_with(self.0, offset, LE)?;
        } else {
            buf.gwrite_with(self.0 as u64, offset, LE)?;
        }

        Ok(*offset)
    }
}

let mut buf = DynamicBuffer::new();

let offset = buf.pwrite(EvenOdd(2), 0).unwrap();
assert_eq!(buf.get(), [2, 0, 0, 0]);
buf.pwrite(EvenOdd(3), offset).unwrap();
assert_eq!(buf.get()[offset..], [3, 0, 0, 0, 0, 0, 0, 0]);

Why can’t I use types that already implement the default TryIntoCtx?

The default type parameters for TryIntoCtx expose a mutable raw slice to write into. This is great for pre-allocated buffers and types that have a static written size; however, we cannot create a custom slice type that performs dynamic expansions under the hood.

As a result, we need to expose a separate writing type that can track offsets and calculate when to allocate.

However, if your TryIntoCtx impls don’t use any special slice APIs and just use Pwrite and/or basic indexing, it’s extremely easy to migrate! Just add the DynamicBuffer generic type.

Implementations

Constructs an empty DynamicBuffer with the default allocation increment of one byte.

Constructs an empty DynamicBuffer with a custom allocation increment.

Gets a slice of all written bytes. Does not include extra bytes allocated by a large increment.

use scroll::{LE, Pwrite};
use scroll_buffer::DynamicBuffer;

let mut buf = DynamicBuffer::new();

assert_eq!(buf.get(), []);
buf.pwrite_with(2u32, 0, LE).unwrap();
assert_eq!(buf.get(), [2, 0, 0, 0]);

Resets the buffer’s contents. Maintains already allocated capacity.

use scroll::{LE, Pwrite};
use scroll_buffer::DynamicBuffer;

let mut buf = DynamicBuffer::new();

buf.pwrite_with(2u16, 0, LE).unwrap();
assert_eq!(buf.get(), [2, 0]);

buf.clear();
assert_eq!(buf.get(), []);

// does not reallocate!
buf.pwrite_with(0xffu8, 0, LE).unwrap();
assert_eq!(buf.get(), [0xff]);

Trait Implementations

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

Performs the mutable indexing (container[index]) operation. Read more

Write N at offset I with context Ctx Read more

Write n into self at offset, with a default Ctx. Updates the offset.

Write n into self at offset, with the ctx. Updates the offset.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.