Differences From
Artifact [b3e2b4c4d7]:
1 1 # kstr
2 2
3 3 **kstr** is the libk string library. it uses the **short** naming convention with the glyph `s`. **kstr** implies `#include <k/mem.h>`.
4 4
5 -## types
5 +# types
6 6
7 -### struct kstr
7 +## struct kstr
8 8 `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.
9 9 * `sz size` - length of string, excluding any null terminator
10 10 * `kmptr ptr` - pointer to string in memory
11 11
12 -### struct ksraw
12 +## struct ksraw
13 13 `struct ksraw` is like `kstr` except it uses raw `char` pointers instead of a `kmptr`.
14 14 * `sz size` - length of string, excluding any null terminator
15 15 * `char* ptr` - pointer to string in memory
16 16
17 -### struct ksbuf
18 -`struct ksbuf` is a structure used to hold buffers.
19 - * `sz size` - maximum size of buffer, including any null terminator
20 - * `char* buf` - region of memory to store buffer in
21 - * `ksalloc strat` - allocation strategy
22 - * `kmkind rule` - kind of allocator to use. only needs to be set if `where` is NULL. see [kmem](../kmem/kmem.md).
23 - * `kmcell* where` - where to allocate the object, in case of pool or tree allocation.
17 +## struct ksbuf
18 +`struct ksbuf` is a structure used for buffered IO.
19 + * `sz run` - maximum size of buffer, including any null terminator
20 + * `kiochan channel` - the channel that output will be written to when flushed
21 + * `char* cur` - a pointer that tracks the length of the buffer
22 + * `char buf []` - region of memory to store buffer in
24 23
25 -### struct kschain
24 +## struct kschain
26 25 `struct kschain` is a structure used for string accumulators that works by aggregating pointers to strings, instead of copying the strings themselves.
27 26 * `kschain_kind kind` - kind of chain
28 27 * `kmkind rule` - kind of allocation to use if `kind` ≠ `kschain_kind_linked`
29 28 * `pstr* ptrs` - pointer to pointer list
30 29 * `sz ptrc` - number of pointers
31 30 * `sz size` - total amount of space in `ptrs`
32 31
33 -#### enum kschain_kind
32 +### enum kschain_kind
34 33 * `kschain_kind_block` - occupies a single block of memory
35 34 * `kschain_kind_linked` - uses a linked list, allocated and deallocated as necessary
36 35
37 -### enum ksalloc
38 -`enum ksalloc` is an enumerator that tells libk what strategy to use when filling a `ksbuf` or `kschain` struct.
36 +## enum ksalloc
37 +`enum ksalloc` is an enumerator that tells libk what strategy to use when filling a `kschain` struct.
39 38 * `ksalloc_static` - do not allocate memory, fill an already-allocated, statically-sized array.
40 39 * `ksalloc_alloc` - allocate a string in memory using the specified kind of allocator.
41 40 * `ksalloc_dynamic` - fill an already-allocated array if possible, allocate a string in memory if the string length exceeds available space.
42 41
43 -## functions
42 +# functions
44 43
45 -### kssz
44 +## kssz
46 45 `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.
47 46
48 -### kstr
47 +## kstr
49 48 `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`.
50 49
51 -### kstoraw
50 +## kstoraw
52 51 `ksraw ksref(kstr)` is a simple convenience function that returns the `ksraw` form of a `kstr`.
53 52
54 -### kscomp
53 +## kscp
54 +`kscond kscp(ksraw src, ksmut dest, sz* len)` copies the string pointed to by `src` into `dest`. its behavior varies depending on the value of `src.size` — if the size is already known, attempts to copy a longer string on top of a shorter one will immediately fail with no changes made to either string. if the size is set to zero, `kscp()` will copy as many bytes as it can before it hits either a NUL terminator in the source string or reaches the end of the destination string. if `dest.src` is zero, kscp simply copies until it hits the first NUL, or reaches `src.ptr[src.size - 1]`. for safety reasons, kscp always terminates `dest` with a NUL when it has enough space to, even if neither string ended with a NUL. if a partial copy occurs, `kscp` will return a `kscond` of `kscond_partial`.
55 +
56 +## ksbufmk
57 +`ksbuf* ksbufmk(void* where, kiochan channel, sz run)` initializes a new buffer at the specified address. `run` should be equivalent to the full length of the memory region minus `sizeof(struct ksbuf)` - in other words, the size of the string the `ksbuf` can hold. memory should be allocated by the user, either by creating an array on the stack or with `kmem` allocation functions. `ksbufmk()` returns a pointer to the new structure. the return value will always point to the same point in memory as `where`, but will be of the appropriate type to pass to buffer functions.
58 +
59 +## ksbufput
60 +`kcond ksbufput(ksbuf* b, ksraw str)` copies a string into a buffer with `kscp`. flushing it as necessary.
61 +
62 +# ksbufflush
63 +`kcond ksbufflush(ksbuf* b)` flushes a buffer to its assigned channel, emptying it and readying it for another write cycle. a buffer should almost always be flushed before it goes out of scope or is deallocated.
64 +
65 +## kscomp
55 66 `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`.
56 67
57 68 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.
58 69
59 70 char mem[512];
60 71 kmptr text = <...>;
61 72 char* src = <...>;
................................................................................
65 76 ksref(text),
66 77 Kstr("</a>")
67 78 };
68 79 char* html = kscomp(Kmsz(chain), chain, &buf);
69 80
70 81 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.
71 82
72 -### macros
83 +## macros
73 84 if `KFclean` is not set when <k/str.h> is included, the following macros are defined.
74 85
75 86 * `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.