libk  kstr.md at [5c1200e1a8]

File mod/kstr/kstr.md artifact b3e2b4c4d7 part of check-in 5c1200e1a8


# kstr

**kstr** is the libk string library. it uses the **short** naming convention with the glyph `s`. **kstr** implies `#include <k/mem.h>`.

## types

### struct kstr
`struct kstr` is a structure for holding pascal strings (length-prefixed strings). it is the basic libk string type. **note:** if `ptr.ref` ≠ NULL and `sz` = 0, the string's length is unknown and should be calculated by any function that operates on a kstr, storing the result in the object if possible.
 * `sz size` - length of string, excluding any null terminator
 * `kmptr ptr` - pointer to string in memory

### struct ksraw
`struct ksraw` is like `kstr` except it uses raw `char` pointers instead of a `kmptr`.
 * `sz size` - length of string, excluding any null terminator
 * `char* ptr` - pointer to string in memory

### struct ksbuf
`struct ksbuf` is a structure used to hold buffers.
 * `sz size` - maximum size of buffer, including any null terminator
 * `char* buf` - region of memory to store buffer in
 * `ksalloc strat` - allocation strategy
 * `kmkind rule` - kind of allocator to use. only needs to be set if `where` is NULL. see [kmem](../kmem/kmem.md).
 * `kmcell* where` - where to allocate the object, in case of pool or tree allocation.

### struct kschain
`struct kschain` is a structure used for string accumulators that works by aggregating pointers to strings, instead of copying the strings themselves.
 * `kschain_kind kind` - kind of chain
 * `kmkind rule` - kind of allocation to use if `kind` ≠ `kschain_kind_linked`
 * `pstr* ptrs` - pointer to pointer list
 * `sz ptrc` - number of pointers
 * `sz size` - total amount of space in `ptrs`

#### enum kschain_kind
 * `kschain_kind_block` - occupies a single block of memory
 * `kschain_kind_linked` - uses a linked list, allocated and deallocated as necessary

### enum ksalloc
`enum ksalloc` is an enumerator that tells libk what strategy to use when filling a `ksbuf` or `kschain` struct.
 * `ksalloc_static` - do not allocate memory, fill an already-allocated, statically-sized array.
 * `ksalloc_alloc` - allocate a string in memory using the specified kind of allocator.
 * `ksalloc_dynamic` - fill an already-allocated array if possible, allocate a string in memory if the string length exceeds available space.

## functions

### kssz
`size_t kssz(char* str, size_t max)` returns the number of characters in a C string, **including** the final null. will count at most `max` characters if `max` > 0.

### kstr
`kstr kstr(char* str, size_t max)` takes a C string and returns a P-string, calculating the length of `str` and storing it in the return value. `max` works as in `kssz`.

### kstoraw
`ksraw ksref(kstr)` is a simple convenience function that returns the `ksraw` form of a `kstr`.

### kscomp
`char* kscomp(size_t ct, ksraw struct[], kmbuf* buf)` is a **string composition** function. it serves as an efficient, generalized replacement for functions like `strcat` and `strdup`.

to use kscomp, create an array of `kstr` and fill it with the strings you wish to concatenate. for example, to programmatically generate an HTML link tag, you might use the following code.

	char mem[512];
	kmptr text = <...>;
	char* src = <...>;
	kmbuf buf = { sizeof mem, &mem, kmkind_none };
    kstr chain[] = {
		Kstr("<a href=\""), { 0, src }, Kstr("\">"),
			ksref(text),
		Kstr("</a>")
	};
	char* html = kscomp(Kmsz(chain), chain, &buf);

kscomp will only calculate the length of individual strings if they are not already known. when it needs to calculate the length of a string, it will store that length in the original array so repeated calls can be made without needing to repeatedly calculate the lengths. this is not always desirable, so the variant `kscompc` exists, which is exactly the same as `kscomp` in every respect except that `chain` is not altered in any way.

### macros
if `KFclean` is not set when <k/str.h> is included, the following macros are defined.

 * `Kstr(string)` - the compile-time equivalent to `kstr()`. `Kstr` takes a literal string and inserts the text `{ sizeof (string), string }` into the document, suitable for initializing a kstr.