put method

void put(
  1. String value, {
  2. Encoding? encoding,
  3. ZBytes? attachment,
  4. Timestamp? timestamp,
})

Publishes a string value through this publisher.

Optionally override the encoding for this specific put. An optional attachment can be included (consumed by this call). An optional timestamp can be attached to the message; borrowed, not consumed.

Implementation

void put(
  String value, {
  Encoding? encoding,
  ZBytes? attachment,
  Timestamp? timestamp,
}) {
  _ensureOpen();
  // ALLOCATE-LAST: the attachment handle is read before anything is
  // created. A disposed or already-consumed attachment throws StateError
  // here, and it used to throw with the internally-created payload ZBytes
  // (contents AND wrapper) and the encoding string already live and
  // unreleasable -- nothing else holds a reference to that payload.
  final attachmentPtr = attachment != null ? attachment.nativePtr : nullptr;
  final loaned = bindings.zd_publisher_loan(_ptr.cast());

  // Two INDEPENDENT length-carried channels (R-2), from the RAW pair (R-3a).
  final (mime, schema) = encoding != null
      ? encodingWireChannels(encoding)
      : (null, null);
  final encodingBuf = allocLengthCarriedUtf8(mime);
  final schemaBuf = allocLengthCarriedUtf8(schema);
  final tsPtr = timestamp != null ? _timestampToNative(timestamp) : nullptr;

  try {
    // Created inside the try so the finally covers it: nothing between here
    // and the FFI call can throw, so the payload is always either moved or
    // never built.
    final payload = ZBytes.fromString(value);
    final rc = bindings.zd_publisher_put(
      loaned,
      payload.nativePtr.cast(),
      encodingBuf.ptr,
      encodingBuf.len,
      schemaBuf.ptr,
      schemaBuf.len,
      attachmentPtr.cast(),
      tsPtr.cast(),
    );

    payload.markConsumed();
    if (attachment != null) attachment.markConsumed();

    if (rc != 0) {
      throw ZenohException('Publisher put failed', rc);
    }
  } finally {
    // allocLengthCarriedUtf8 uses calloc, so the release is calloc.free.
    if (encodingBuf.ptr != nullptr) calloc.free(encodingBuf.ptr);
    if (schemaBuf.ptr != nullptr) calloc.free(schemaBuf.ptr);
    if (tsPtr != nullptr) calloc.free(tsPtr);
  }
}