callWithBuffer function

Uint8List? callWithBuffer(
  1. BufferCallback fn, {
  2. int? maxSize,
  3. int? initialSize,
  4. bool preferTransient = false,
  5. bool? allowZeroCopy,
})

Calls a buffer callback function with dynamically sized buffers.

Starts with initialSize or initialBufferSize and doubles the buffer size if the callback returns -2 (buffer too small), up to maxSize or maxBufferSize.

When maxSize is null, maxBufferSize is used. When initialSize is null, initialBufferSize is used. Returns the data as Uint8List on success, null on failure.

Payloads at or above zeroCopyResultThresholdBytes use a transient native allocation and return a view with a `NativeFinalizer` when isZeroCopyResultBufferAvailable; otherwise they copy into the Dart heap.

Implementation

Uint8List? callWithBuffer(
  BufferCallback fn, {
  int? maxSize,
  int? initialSize,
  bool preferTransient = false,
  bool? allowZeroCopy,
}) {
  final limit = maxSize ?? maxBufferSize;
  final size = initialSize ?? initialBufferSize;
  final zeroCopy = allowZeroCopy ?? isZeroCopyResultBufferAvailable;
  // Prefer transient only when the caller opts in or the seed size already
  // suggests a large payload. Do not gate on [limit] (often 16 MiB) — that
  // forced malloc/free for every sync query and skipped the scratch pool.
  if (zeroCopy && (preferTransient || size >= zeroCopyResultThresholdBytes)) {
    return _callWithTransientBuffer(
      fn,
      limit: limit,
      initialSize: size,
      allowZeroCopy: true,
    );
  }
  final scratch = _sharedScratchPool.tryAcquire();
  if (scratch == null) {
    return _callWithTransientBuffer(
      fn,
      limit: limit,
      initialSize: size,
      allowZeroCopy: zeroCopy,
    );
  }
  try {
    return scratch.call(
      fn,
      limit: limit,
      initialSize: size,
      allowZeroCopy: zeroCopy,
    );
  } finally {
    scratch.release();
  }
}