String Handling#

Python accepts a str or integer token for scalar dual-mode attribute-name arguments, such as write, map, delete, and attribute-floor lookup. The list arguments Stage.read_attributes(attrs), Stage.query(attrs=...), and Stage.advance_write_floor(attributes=...) require integer tokens. Use PathDictionary.intern_token() for those lists, and reuse tokens when passing the same names repeatedly.

In C, ovx_string_t contains a pointer and a byte length. The text is UTF-8. An input string need not end with a null character; use its length when reading it. The view does not own its buffer.

Passing Strings or Tokens#

In C, arguments of type ovx_string_or_token_t accept a string or a token. A nonzero token is used directly; otherwise the name in string is resolved through the path dictionary. Reuse a token when passing the same name repeatedly.

Python accepts a str or an integer token for these arguments. The snippets below show an attribute passed as a string in Python and as a token in C. The Python snippet assumes an existing stage and query; the C snippet uses the previously resolved attr token.

# Attribute arguments accept an interned token (int) or a plain str:
# a token skips the per-call dictionary lookup, a str is interned for
# you at call time.
stage.write_attribute(
    query, "temperature", ordinal=2, tensors=np.array([4.0, 5.0, 6.0], np.float32),
    is_array=False,
).wait()
stage.advance_write_floor(ordinal=2).wait()
// Attributes pass as ovx_string_or_token_t. We already hold an interned
// token, so set it (token != 0) and leave the string empty to skip a lookup.
ovx_string_or_token_t attrArg{ attr, {} };

Use the stage’s dictionary to create tokens. See Path Dictionary for the Python and C examples and token lifetimes.

Reading Returned Strings in C#

  • Read length bytes. A null pointer with zero length represents no value; a null pointer with nonzero length is invalid.

  • Compare lengths first, then compare that many bytes with memcmp(). For zero-length strings, no byte comparison is needed. strncmp() stops at a null character and is not a general byte comparison.

  • In C++, use std::string_view to borrow a string or std::string to copy it.

  • A nonempty library-produced ovx_string_t has a trailing null character, as specified by its header. This does not extend the buffer’s lifetime.

In C, write the specified bytes without requiring a trailing null character. For a valid name view, this also avoids narrowing its length to int. Include <stdio.h> and check the returned byte count for output errors:

// An empty view may have a null pointer.
if (name.length != 0)
    fwrite(name.ptr, 1, name.length, stdout);

The C++ snippet below borrows the returned string using its pointer and length:

// ovx_string_t is a non-owning (ptr, length) view; wrap it in string_view
// for zero-copy use. Copy it if it must outlive the dictionary.
std::string_view name{ resolved.ptr, resolved.length };
std::printf("attribute token %llu = '%.*s'\n", (unsigned long long)attr, (int)name.size(), name.data());

Keep the owner alive while using a borrowed string. Dictionary strings last for the dictionary’s lifetime. Operation error messages have a shorter lifetime; see Error Handling and Diagnostics. Copy a string if you need it after its owner releases or replaces the buffer.