#[repr(C)]
pub struct _TidyAllocatorVtbl { pub alloc: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, nBytes: usize) -> *mut c_void>, pub realloc: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, block: *mut c_void, nBytes: usize) -> *mut c_void>, pub free: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, block: *mut c_void)>, pub panic: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, msg: ctmbstr)>, }
Expand description

//** @defgroup Memory Memory Allocation

Tidy can use a user-provided allocator for all memory allocations. If this allocator is not provided, then a default allocator is used which simply wraps standard C malloc()/free() calls. These wrappers call the panic() function upon any failure. The default panic function prints an out of memory message to stderr, and calls exit(2).

For applications in which it is unacceptable to abort in the case of memory allocation, then the panic function can be replaced with one which longjmps() out of the LibTidy code. For this to clean up completely, you should be careful not to use any Tidy methods that open files as these will not be closed before panic() is called.

Calling the xxxWithAllocator() family (tidyCreateWithAllocator, tidyBufInitWithAllocator, tidyBufAllocWithAllocator) allow setting custom allocators.

All parts of the document use the same allocator. Calls that require a user-provided buffer can optionally use a different allocator.

For reference in designing a plug-in allocator, most allocations made by LibTidy are less than 100 bytes, corresponding to attribute names and values, etc.

There is also an additional class of much larger allocations which are where most of the data from the lexer is stored. It is not currently possible to use a separate allocator for the lexer; this would be a useful extension.

In general, approximately 1/3rd of the memory used by LibTidy is freed during the parse, so if memory usage is an issue then an allocator that can reuse this memory is a good idea.

To create your own allocator, do something like the following: @code{.c} typedef struct _MyAllocator { TidyAllocator base; // …other custom allocator state… } MyAllocator;

void* MyAllocator_alloc(TidyAllocator *base, void *block, size_t nBytes) { MyAllocator self = (MyAllocator)base; // … } // etc.

static const TidyAllocatorVtbl MyAllocatorVtbl = { MyAllocator_alloc, MyAllocator_realloc, MyAllocator_free, MyAllocator_panic };

myAllocator allocator; TidyDoc doc;

allocator.base.vtbl = &MyAllocatorVtbl; //…initialise allocator specific state… doc = tidyCreateWithAllocator(&allocator); @endcode

Although this looks slightly long-winded, the advantage is that to create a custom allocator you simply need to set the vtbl pointer correctly. The vtbl itself can reside in static/global data, and hence does not need to be initialised each time an allocator is created, and furthermore the memory is shared amongst all created allocators.

@{

Fields§

§alloc: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, nBytes: usize) -> *mut c_void>§realloc: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, block: *mut c_void, nBytes: usize) -> *mut c_void>§free: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, block: *mut c_void)>§panic: Option<unsafe extern "C" fn(self_: *mut TidyAllocator, msg: ctmbstr)>

Trait Implementations§

source§

impl Clone for _TidyAllocatorVtbl

source§

fn clone(&self) -> _TidyAllocatorVtbl

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for _TidyAllocatorVtbl

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Copy for _TidyAllocatorVtbl

Auto Trait Implementations§

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> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

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

§

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>,

§

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.