Appearance
aowlspt/ctext
Source: aowl/src/aowlspt/ctext.nim — 95 lines.
ctext.nim -- getting TEXT out of C and into a nimony string, once.
THE PROBLEM THIS EXISTS FOR
Nimony has no cstring -> string conversion. Nim 2's $cstring is not available, and there is no newString+copyMem idiom that survives the bounds rules here. So every consumer of a C string coming out of the ABI -- a region participant's name, a refusal reason, a capability id -- hand-rolled the SAME copy-into-a-caller-buffer C helper, privately. There were three such copies before this file; this is the shared one, so there is not a fourth.
THE SHAPE, and why it is this shape
C never returns a string. What crosses the boundary is:
- a
cstringthe C side owns and keeps alive, plus - a LENGTH obtained by a bounded scan on the C side.
The Nim side then allocates once and fills byte by byte. That is slower than a copyMem, and it is deliberate: a copyMem from a pointer whose length came from the same untrusted side is exactly the read-past-the-end this is meant to prevent, and these strings are tens of bytes read at human speed, not a hot loop.
EVERY READ IS BOUNDED. cTextLen scans at most MaxCText bytes and returns that cap if it finds no terminator, so an unterminated buffer costs a bounded read and yields a truncated string -- never a walk off the end of a page. A caller that needs to know truncation happened compares the result's length against MaxCText.
NULL IS NOT AN ERROR CODE HERE. A nil pointer yields "", because every caller so far wants "no text" and not an exception, and a "" that came from nil is indistinguishable from a "" that came from an empty buffer -- which is correct: both mean the same thing to a label.
Constants
MaxCText
nim
MaxCText* = 4096The hard ceiling on any single C string read through this module. It is a REFUSAL, not a preference: an unterminated or corrupt buffer must cost a bounded read. Region names are 32 bytes and reasons are 192, so this is three orders of magnitude of headroom over any real caller.
aowl/src/aowlspt/ctext.nim:37
Routines
cTextLen
nim
proc cTextLen*(s: cstring): intThe length of a C string, scanning at most MaxCText bytes. A result equal to MaxCText means the terminator was NOT found within the cap -- treat it as truncated, not as an exact length.
aowl/src/aowlspt/ctext.nim:66
cText
nim
proc cText*(s: cstring): stringA C string as a nimony string, bounded by MaxCText.
Returns "" for a nil or empty pointer; those two are the same answer to every caller this has, and inventing a distinction neither one carries would be a lie dressed as precision.
aowl/src/aowlspt/ctext.nim:72
cTextOr
nim
proc cTextOr*(s: cstring; dflt: string): stringcText, but with an explicit stand-in for "there was no text". Use this wherever an empty label on screen would read as a MEASUREMENT ("this participant has no name") rather than as an absence -- an empty string is the classic silently-wrong answer in this codebase.
aowl/src/aowlspt/ctext.nim:88

