Module jdk.incubator.foreign
Package jdk.incubator.foreign

# Interface CLinker.VaList

All Superinterfaces:
  `Addressable`, `AutoCloseable`

Enclosing interface:
  CLinker

public static interface CLinker.VaList extends Addressable, AutoCloseable
An interface that models a C `va_list`.

A va list is a stateful cursor used to iterate over a set of variadic arguments.

Per the C specification (see C standard 6.5.2.2 Function calls - item 6), arguments to variadic calls are erased by way of 'default argument promotions', which erases integral types by way of integer promotion (see C standard 6.3.1.1 - item 2), and which erases all `float` arguments to `double`.

As such, this interface only supports reading `int`, `double`, and any other type that fits into a `long`.

Unless otherwise specified, passing a `null` argument, or an array argument containing one or more `null` elements to a method in this class causes a `NullPointerException` to be thrown.

API Note:
  In the future, if the Java language permits, `CLinker.VaList` may become a `sealed` interface, which would prohibit subclassing except by explicitly permitted types.

## Nested Class Summary

Nested Classes
Modifier and Type
Interface
Description
`static interface`
`CLinker.VaList.Builder`
A builder interface used to construct a C `va_list`.

## Method Summary

Modifier and Type
Method
Description
`MemoryAddress`
`address()`
Returns the memory address of the C `va_list` associated with this instance.
`void`
`close()`
Releases the underlying C `va_list` modelled by this instance, and any native memory that is attached to this va list that holds its elements (see `make(Consumer)`).
`CLinker.VaList`
`copy()`
Copies this C `va_list` at its current position.
`CLinker.VaList`
`copy​(NativeScope scope)`
Copies this C `va_list` at its current position.
`static CLinker.VaList`
`empty()`
Returns an empty C `va_list` constant.
`boolean`
`isAlive()`
A predicate used to check if the memory associated with the C `va_list` modelled by this instance is still valid to use.
`static CLinker.VaList`
`make​(Consumer<CLinker.VaList.Builder> actions)`
Constructs a new `VaList` using a builder (see `CLinker.VaList.Builder`).
`static CLinker.VaList`
`make​(Consumer<CLinker.VaList.Builder> actions, NativeScope scope)`
Constructs a new `VaList` using a builder (see `CLinker.VaList.Builder`).
`static CLinker.VaList`
`ofAddressRestricted​(MemoryAddress address)`
Constructs a new `VaList` instance out of a memory address pointing to an existing C `va_list`.
`void`
`skip​(MemoryLayout... layouts)`
Skips a number of elements with the given memory layouts, and advances this va list's position.
`MemoryAddress`
`vargAsAddress​(MemoryLayout layout)`
Reads the next value as a `MemoryAddress` and advances this va list's position.
`double`
`vargAsDouble​(MemoryLayout layout)`
Reads the next value as a `double` and advances this va list's position.
`int`
`vargAsInt​(MemoryLayout layout)`
Reads the next value as an `int` and advances this va list's position.
`long`
`vargAsLong​(MemoryLayout layout)`
Reads the next value as a `long` and advances this va list's position.
`MemorySegment`
`vargAsSegment​(MemoryLayout layout)`
Reads the next value as a `MemorySegment`, and advances this va list's position.
`MemorySegment`
`vargAsSegment​(MemoryLayout layout, NativeScope scope)`
Reads the next value as a `MemorySegment`, and advances this va list's position.

## Method Details

### vargAsInt

int vargAsInt​(MemoryLayout layout)
Reads the next value as an `int` and advances this va list's position.

Parameters:
  `layout` - the layout of the value
Returns:
  the value read as an `int`
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).
  `IllegalArgumentException` - if the given memory layout is not compatible with `int`

### vargAsLong

long vargAsLong​(MemoryLayout layout)
Reads the next value as a `long` and advances this va list's position.

Parameters:
  `layout` - the layout of the value
Returns:
  the value read as an `long`
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).
  `IllegalArgumentException` - if the given memory layout is not compatible with `long`

### vargAsDouble

double vargAsDouble​(MemoryLayout layout)
Reads the next value as a `double` and advances this va list's position.

Parameters:
  `layout` - the layout of the value
Returns:
  the value read as an `double`
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).
  `IllegalArgumentException` - if the given memory layout is not compatible with `double`

### vargAsAddress

MemoryAddress vargAsAddress​(MemoryLayout layout)
Reads the next value as a `MemoryAddress` and advances this va list's position.

Parameters:
  `layout` - the layout of the value
Returns:
  the value read as an `MemoryAddress`
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).
  `IllegalArgumentException` - if the given memory layout is not compatible with `MemoryAddress`

### vargAsSegment

MemorySegment vargAsSegment​(MemoryLayout layout)
Reads the next value as a `MemorySegment`, and advances this va list's position.

The memory segment returned by this method will be allocated using `MemorySegment.allocateNative(long, long)`, and will have to be closed separately.

Parameters:
  `layout` - the layout of the value
Returns:
  the value read as an `MemorySegment`
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).
  `IllegalArgumentException` - if the given memory layout is not compatible with `MemorySegment`

### vargAsSegment

MemorySegment vargAsSegment​(MemoryLayout layout, NativeScope scope)
Reads the next value as a `MemorySegment`, and advances this va list's position.

The memory segment returned by this method will be allocated using the given `NativeScope`.

Parameters:
  `layout` - the layout of the value
  `scope` - the scope to allocate the segment in
Returns:
  the value read as an `MemorySegment`
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).
  `IllegalArgumentException` - if the given memory layout is not compatible with `MemorySegment`

### skip

void skip​(MemoryLayout... layouts)
Skips a number of elements with the given memory layouts, and advances this va list's position.

Parameters:
  `layouts` - the layout of the value
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).

### isAlive

boolean isAlive()
A predicate used to check if the memory associated with the C `va_list` modelled by this instance is still valid to use.

Returns:
  true, if the memory associated with the C `va_list` modelled by this instance is still valid
See Also:
  `close()`

### close

void close()
Releases the underlying C `va_list` modelled by this instance, and any native memory that is attached to this va list that holds its elements (see `make(Consumer)`).

After calling this method, `isAlive()` will return `false` and further attempts to read values from this va list will result in an exception.

Specified by:
  `close` in interface `AutoCloseable`
See Also:
  `isAlive()`

### copy

CLinker.VaList copy()
Copies this C `va_list` at its current position. Copying is useful to traverse the va list's elements starting from the current position, without affecting the state of the original va list, essentially allowing the elements to be traversed multiple times.

If this method needs to allocate native memory for the copy, it will use `MemorySegment.allocateNative(long, long)` to do so. `close()` will have to be called on the returned va list instance to release the allocated memory.

This method only copies the va list cursor itself and not the memory that may be attached to the va list which holds its elements. That means that if this va list was created with the `make(Consumer)` method, closing this va list will also release the native memory that holds its elements, making the copy unusable.

Returns:
  a copy of this C `va_list`.
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).

### copy

CLinker.VaList copy​(NativeScope scope)
Copies this C `va_list` at its current position. Copying is useful to traverse the va list's elements starting from the current position, without affecting the state of the original va list, essentially allowing the elements to be traversed multiple times.

If this method needs to allocate native memory for the copy, it will use the given `NativeScope` to do so.

This method only copies the va list cursor itself and not the memory that may be attached to the va list which holds its elements. That means that if this va list was created with the `make(Consumer)` method, closing this va list will also release the native memory that holds its elements, making the copy unusable.

Parameters:
  `scope` - the scope to allocate the copy in
Returns:
  a copy of this C `va_list`.
Throws:
  `IllegalStateException` - if the C `va_list` associated with this instance is no longer valid (see `close()`).

### address

MemoryAddress address()
Returns the memory address of the C `va_list` associated with this instance.

Specified by:
  `address` in interface `Addressable`
Returns:
  the memory address of the C `va_list` associated with this instance.

### ofAddressRestricted

static CLinker.VaList ofAddressRestricted​(MemoryAddress address)
Constructs a new `VaList` instance out of a memory address pointing to an existing C `va_list`.

This method is restricted. Restricted method are unsafe, and, if used incorrectly, their use might crash the JVM or, worse, silently result in memory corruption. Thus, clients should refrain from depending on restricted methods, and use safe and supported functionalities, where possible.

Parameters:
  `address` - a memory address pointing to an existing C `va_list`.
Returns:
  a new `VaList` instance backed by the C `va_list` at `address`.

### make

static CLinker.VaList make​(Consumer<CLinker.VaList.Builder> actions)
Constructs a new `VaList` using a builder (see `CLinker.VaList.Builder`).

If this method needs to allocate native memory for the va list, it will use `MemorySegment.allocateNative(long, long)` to do so.

This method will allocate native memory to hold the elements in the va list. This memory will be 'attached' to the returned va list instance, and will be released when `close()` is called.

Note that when there are no elements added to the created va list, this method will return the same as `empty()`.

Parameters:
  `actions` - a consumer for a builder (see `CLinker.VaList.Builder`) which can be used to specify the elements of the underlying C `va_list`.
Returns:
  a new `VaList` instance backed by a fresh C `va_list`.

### make

static CLinker.VaList make​(Consumer<CLinker.VaList.Builder> actions, NativeScope scope)
Constructs a new `VaList` using a builder (see `CLinker.VaList.Builder`).

If this method needs to allocate native memory for the va list, it will use the given `NativeScope` to do so.

This method will allocate native memory to hold the elements in the va list. This memory will be managed by the given `NativeScope`, and will be released when the scope is closed.

Note that when there are no elements added to the created va list, this method will return the same as `empty()`.

Parameters:
  `actions` - a consumer for a builder (see `CLinker.VaList.Builder`) which can be used to specify the elements of the underlying C `va_list`.
  `scope` - the scope to be used for the valist allocation.
Returns:
  a new `VaList` instance backed by a fresh C `va_list`.

### empty

static CLinker.VaList empty()
Returns an empty C `va_list` constant.

The returned `VaList` can not be closed.

Returns:
  a `VaList` modelling an empty C `va_list`.