A NMRefString tracks the length seprately, it thus may not be a NUL terminated
string (although, there is always a NUL character at the end of the buffer).
As such, the previous implementation did not work correctly in when comparing
for example NMRefString("a\0b") with "a". There was even a comment hinting
to that fact. Instead of making obscure comments, fix the implementation to
behave always correctly.
Imaging you track a list of NMRefString instances. You could
directly expose them as strv array, but then you need a way
from the string back to the NMRefString instance.
That's easy to do. Add NM_REF_STRING_UPCAST() for that.
Previously, NMRefString was the public part of the struct, while
there was an internal RefString struct with private fields.
That might make sense if we would need to preserve some stable ABI, but
we don't because this is all internal (unstable) API. It also might
make sense to hide fields, but in practice that is not necessary
because the leading underscore is indicator enough that these are
private fields that are not supposed to be touched (unless you really
know what you do). So, drop RefString and move all fields in the public
NMRefString. The advantage is that we can later inline certain trivial
functions, that we otherwise couldn't.
Also, drop the "str" pointer and only use the "str" array field. The
pointer existed so that during nm_ref_string_new_len() we could create
a lookup needle with external str pointer. That is now solved
differently by using "len == G_MAXSIZE" as indicator that this is
a special lookup instance. The advantage is that we save one pointer
field per NMRefString, that we reduce the redundancy of the data, and
that we don't need the additional indirection.
NMRefString has only const fields itself, and all operations (except
ref/unref) don't mutate the instance. As such, the type is already
immutable, and using "const" is redundant and unnecessary.
Drop "const" from all API of NMRefString.