String Handling#

ovstage passes strings as ovx_string_t, a non-owning (ptr, length) view that is not required to be null-terminated. The caller owns the pointed-to bytes, length is a byte count (not a code-point count), and the text is UTF-8. Many entry points — attribute names, filter attributes, prim paths — accept the dual-mode ovx_string_or_token_t, which carries either a pre-resolved path-dictionary token or a raw string.

ovx_string_t#

typedef struct ovx_string_t {
    const char* ptr;     // borrowed bytes, not necessarily null-terminated
    size_t      length;  // byte count
} ovx_string_t;

Always use both fields together:

  • Print with %.*s, passing (int)length, ptr — never assume a terminator:

    printf("%.*s\n", (int)name.length, name.ptr);
    
  • Compare by checking length first, then memcmp / strncmp over exactly length bytes.

  • In C++, wrap a borrowed view as std::string_view{ s.ptr, s.length }; copy to a std::string if it must outlive the source buffer:

    // 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());
    

A string view returned from the path dictionary is valid only for the dictionary’s lifetime — copy it to outlive the dictionary.

ovx_string_or_token_t: String or Token#

typedef struct ovx_string_or_token_t {
    ovx_token_t  token;   // uint64; 0 == unresolved (use string)
    ovx_string_t string;  // resolved through the dictionary when token == 0
} ovx_string_or_token_t;

If token != 0 the token is used directly; if token == 0 the string is resolved through the path dictionary at call time. Pre-resolving a token avoids per-call hashing in hot loops:

// 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, {} };

In Python#

Python has no ovx_string_t. Methods accept a plain str (interned each call) or a pre-interned int token (cheaper for repeated use):

# Intern a string -> a stable integer token, and resolve it back.
attr = paths.intern_token("temperature")
print("attribute token", attr, "=", paths.token_to_string(attr))
# 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()

Where to Go Next#