1 /* Strings with implicit length.
2 * Richard W.M. Jones <rjones@redhat.com>
4 * https://rwmj.wordpress.com/2016/01/08/half-baked-ideas-c-strings-with-implicit-length-field/
6 * Inspired by this OCaml implementation of strings:
7 * https://rwmj.wordpress.com/2009/08/05/ocaml-internals-part-2-strings-and-other-types/
9 * NB: It's just for playing with. Don't actually use this in
10 * production code!! In particular this uses malloc allocations in a
11 * way which is not valid, standard C, and may break or corrupt things
23 /* If your libc doesn't have glibc's malloc_usable_size, then
24 * you need to find the equivalent function and define it here.
26 #define ilenstr_malloc_size malloc_usable_size
28 /* Although ilenstrs have a separate length field, it's implicit,
29 * so they are convertable back to C strings (although C strings
30 * are NOT ilenstrs so don't try to cast them the other way).
32 typedef char *ilenstr;
34 /* Allocate a new ilenstr from an arbitrary string + length. The
35 * string may contain \0 characters within the string.
38 new_ilenstr_with_len (const char *str, size_t len)
44 ilstr = malloc (len+1);
45 if (!ilstr) return NULL;
46 memcpy (ilstr, str, len);
49 msize = ilenstr_malloc_size (ilstr);
50 assert (len <= msize);
52 /* Because we only have a single byte to use at the end of the
53 * malloc allocation, we have this limit. It could be bypassed with
54 * some horrible encoding scheme, but that would make getting the
55 * string length slower. Hopefully this never asserts in practice.
57 assert (msize-len <= 255);
59 p = (uint8_t *) &ilstr[msize-1];
65 /* Allocate an ilenstr from a C string. The C string cannot
66 * contain \0 characters within the string.
69 new_ilenstr (const char *cstr)
71 return new_ilenstr_with_len (cstr, strlen (cstr));
74 /* Get the implicit length of an ilenstr. */
76 ilstrlen (const ilenstr ilstr)
81 msize = ilenstr_malloc_size (ilstr);
82 p = (uint8_t *) (ilstr + msize - 1);
86 #endif /* ilenstr_h_ */