summaryrefslogtreecommitdiff
path: root/src/dynstr.h
blob: f18e4f2772aaa7724c6e9937320002c466b5a426 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
 * @file dynstr.h
 * Dynamically allocated string.
 */

#ifndef DYNSTR_H
#define DYNSTR_H

/**
 * Dynamically allocated string.
 * If you modify the content of the struct your self (please don't) make sure
 * len is ALWAYS less than size.
 */
typedef struct dynstr_t
{
    /**
     * String data, size large and filled with len bytes of string.
     * Not null-terminated.
     */
    char* data;
    /**
     * Number of bytes in data
     */
    size_t len;
    /**
     * Size of data in bytes
     */
    size_t size;
} dynstr_t;

#include <string.h>

/**
 * Allocate a dynamically allocated string.
 * Returned string is empty but has allocate at least one byte of space.
 * Returns NULL in case of allocation error.
 * @return empty string
 */
MALLOC dynstr_t* dynstr_new(void);
/**
 * Allocate a dynamically allocated string and initialize with parameters.
 * Returned string has at least one more byte allocated than len.
 * Returns NULL in case of allocation error.
 * @param str string to copy len bytes from, may not be NULL
 * @param len number of bytes to copy from str
 * @return string with given data
 */
MALLOC NONULL dynstr_t* dynstr_new_strn(const char* str, size_t len);
/**
 * Allocate a dynamically allocated string and initialize with parameter.
 * Returned string has space for at least one more byte.
 * Returns NULL in case of allocation error.
 * @param str null-terminated string to copy from, may not be NULL
 * @return string with given data
 */
static inline MALLOC NONULL dynstr_t* dynstr_new_str(const char* str)
{
    assert(str);
    return dynstr_new_strn(str, strlen(str));
}
/**
 * Free a dynamic string.
 * @param str string to free, may be NULL
 */
void dynstr_free(dynstr_t* str);

/**
 * Return null-terminated static string and free dynamic string.
 * @param str string to free, may not be NULL
 * @return null-terminated content of str, never NULL
 */
NONULL char* dynstr_done(dynstr_t* str);

/**
 * Return null-terminated static string.
 * The returned string is only valid until the next call to a dynstr method
 * on the same string.
 * @param str string to free, may not be NULL
 * @return null-terminated content of str, never NULL
 */
NONULL const char* dynstr_peek(dynstr_t* str);

/**
 * Append len bytes of data from add to dynamic string.
 * @param str string to append to, may not be NULL
 * @param add string to append, may not be NULL
 * @param len number of bytes to append from add
 * @return false in case of allocation error
 */
NONULL bool dynstr_nappend(dynstr_t* str, const char* add, size_t len);

/**
 * Append string to dynamic string.
 * @param str string to append to, may not be NULL
 * @param add null-terminated string to append, may not be NULL
 * @return false in case of allocation error
 */
static inline NONULL bool dynstr_append(dynstr_t* str, const char* add)
{
    assert(add);
    return dynstr_nappend(str, add, strlen(add));
}

/**
 * Append character to dynamic string.
 * @param str string to append to, may not be NULL
 * @param c character to append
 * @return false in case of allocation error
 */
static inline NONULL bool dynstr_appendc(dynstr_t* str, char c)
{
    return dynstr_nappend(str, &c, 1);
}

/**
 * Make dynamic string shorter by cutting of a bit at the end.
 * @param str string to cut shorter, may not be NULL
 * @param newlen new length of string
 */
NONULL void dynstr_cut(dynstr_t* str, size_t newlen);

#endif /* DYNSTR_H */