KeyExpr.autocanonize constructor
- String expr
Creates a KeyExpr from expr, canonizing it first.
The additive door beside the strict default. Where KeyExpr(expr)
rejects a non-canon expression, this rewrites it into canon form and
constructs from the result — so KeyExpr.autocanonize('a/**/**/c') is
the key expression a/**/c, and its value reads back the canonized
form, not the input. See canonize for the four rewrite rules.
Canonize-then-validate, exactly as canon composes it: an expression that is still invalid after the rewrite throws ZenohException carrying canon's code — the same exception the strict constructor throws, for the same inputs.
The result is an ordinary KeyExpr in every respect: it delivers, answers intersects/includes/equals, clones and disposes identically to one built any other way, and nothing on it reports whether canonization actually happened — canon carries no such signal.
Canonization is construction-and-validation only, so non-ASCII input
is safe here — but the resulting handle is not safe to use: see the
non-ASCII warning in this class's documentation. expr is judged as
bytes, with the encode-boundary caveat described there.
The caller must dispose the result.
Implementation
factory KeyExpr.autocanonize(String expr) {
final encoded = utf8.encode(expr);
// Canon COPIES this before canonizing — the buffer is `const` on its side
// and is never written — so unlike `canonize` there is no in-place
// rewrite here. It must still be non-NULL at length 0.
final exprPtr = _copyToNative(encoded);
// Canon writes the canonized length back; nothing below reads it, because
// the owned key expression carries its own bytes. The cell exists because
// canon's signature takes one, and it is released either way.
final lenCell = calloc<Size>();
// Allocate-last: the slot is the final block taken, after everything that
// could have thrown, and it is freed on the rc-failure path.
final slot = calloc.allocate<Void>(bindings.zd_keyexpr_sizeof());
try {
lenCell.value = encoded.length;
final rc = bindings.zd_keyexpr_from_substr_autocanonize(
slot.cast(),
exprPtr.cast(),
lenCell,
);
if (rc != 0) {
calloc.free(slot);
throw ZenohException('Invalid key expression: "$expr"', rc);
}
return KeyExpr._owned(slot);
} finally {
malloc.free(exprPtr);
calloc.free(lenCell);
}
}