encodeBlob method

WalrusFfiEncodedBlob encodeBlob(
  1. int nShards,
  2. Uint8List data
)

Full encode: compute metadata AND all primary + secondary slivers.

Used for direct-mode blob storage where slivers must be distributed to storage nodes by the client.

Returns a WalrusFfiEncodedBlob containing metadata and all slivers.

Implementation

WalrusFfiEncodedBlob encodeBlob(int nShards, Uint8List data) {
  // First get encoding params to know buffer sizes.
  final params = encodingParams(nShards, data.length);
  final priSliverSize = params.primarySliverSize;
  final secSliverSize = params.secondarySliverSize;
  final totalPriBytes = nShards * priSliverSize;
  final totalSecBytes = nShards * secSliverSize;

  // Allocate input + output buffers.
  final dataPtr = calloc<Uint8>(data.isEmpty ? 1 : data.length);
  final outPriSlivers = calloc<Uint8>(totalPriBytes == 0 ? 1 : totalPriBytes);
  final outSecSlivers = calloc<Uint8>(totalSecBytes == 0 ? 1 : totalSecBytes);
  final outBlobId = calloc<Uint8>(32);
  final outRootHash = calloc<Uint8>(32);
  final outUnencodedLength = calloc<Uint64>(1);
  final outEncodingType = calloc<Uint8>(1);

  try {
    if (data.isNotEmpty) {
      dataPtr.asTypedList(data.length).setAll(0, data);
    }

    final ret = _encodeBlob(
      nShards,
      data.isEmpty ? nullptr : dataPtr,
      data.length,
      outPriSlivers,
      outSecSlivers,
      outBlobId,
      outRootHash,
      outUnencodedLength,
      outEncodingType,
    );

    if (ret != 0) {
      throw WalrusFfiException('walrus_encode_blob failed with code $ret');
    }

    // Extract primary slivers.
    final primarySlivers = <Uint8List>[];
    for (var i = 0; i < nShards; i++) {
      final offset = i * priSliverSize;
      primarySlivers.add(
        Uint8List.fromList(
          outPriSlivers
              .asTypedList(totalPriBytes)
              .sublist(offset, offset + priSliverSize),
        ),
      );
    }

    // Extract secondary slivers.
    final secondarySlivers = <Uint8List>[];
    for (var i = 0; i < nShards; i++) {
      final offset = i * secSliverSize;
      secondarySlivers.add(
        Uint8List.fromList(
          outSecSlivers
              .asTypedList(totalSecBytes)
              .sublist(offset, offset + secSliverSize),
        ),
      );
    }

    return WalrusFfiEncodedBlob(
      metadata: WalrusBlobMetadata(
        blobId: Uint8List.fromList(outBlobId.asTypedList(32)),
        rootHash: Uint8List.fromList(outRootHash.asTypedList(32)),
        unencodedLength: outUnencodedLength.value,
        encodingType: outEncodingType.value,
      ),
      primarySlivers: primarySlivers,
      secondarySlivers: secondarySlivers,
      symbolSize: params.symbolSize,
    );
  } finally {
    calloc.free(dataPtr);
    calloc.free(outPriSlivers);
    calloc.free(outSecSlivers);
    calloc.free(outBlobId);
    calloc.free(outRootHash);
    calloc.free(outUnencodedLength);
    calloc.free(outEncodingType);
  }
}