Mercurial > dovecot > core-2.2
annotate src/lib/str.c @ 23007:36e01285b5b8
lib: buffer - Improve header comment for buffer_insert() and buffer_delete().
author | Stephan Bosch <stephan.bosch@dovecot.fi> |
---|---|
date | Mon, 18 Mar 2019 00:52:37 +0100 |
parents | cb108f786fb4 |
children |
rev | line source |
---|---|
22713
cb108f786fb4
Updated copyright notices to include the year 2018.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents:
21390
diff
changeset
|
1 /* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */ |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
3 #include "lib.h" |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
4 #include "buffer.h" |
5681
09415e6a0892
Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents:
4451
diff
changeset
|
5 #include "printf-format-fix.h" |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
6 #include "str.h" |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
7 |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
8 #include <stdio.h> |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
9 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
10 string_t *str_new(pool_t pool, size_t initial_size) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
11 { |
17204
49c7cc58fb1b
liblib: Fixed crash using str_c() in different stack frame with str_new(0) allocated string.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
12 /* never allocate a 0 byte size buffer. this is especially important |
49c7cc58fb1b
liblib: Fixed crash using str_c() in different stack frame with str_new(0) allocated string.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
13 when str_c() is called on an empty string from a different stack |
49c7cc58fb1b
liblib: Fixed crash using str_c() in different stack frame with str_new(0) allocated string.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
14 frame (see the comment in buffer.c about this). */ |
49c7cc58fb1b
liblib: Fixed crash using str_c() in different stack frame with str_new(0) allocated string.
Timo Sirainen <tss@iki.fi>
parents:
17130
diff
changeset
|
15 return buffer_create_dynamic(pool, I_MAX(initial_size, 1)); |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 |
8007 | 18 string_t *str_new_const(pool_t pool, const char *str, size_t len) |
19 { | |
20 string_t *ret; | |
21 | |
22 i_assert(str[len] == '\0'); | |
9623
3da42dafa798
buffer_create_[const_]data() API change: Take buffer_t as parameter instead of allocating it.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
23 |
3da42dafa798
buffer_create_[const_]data() API change: Take buffer_t as parameter instead of allocating it.
Timo Sirainen <tss@iki.fi>
parents:
8590
diff
changeset
|
24 ret = p_new(pool, buffer_t, 1); |
15034
7efef678bca8
Renamed buffer_create_*data() to buffer_create_from_*data() for consistency.
Timo Sirainen <tss@iki.fi>
parents:
15032
diff
changeset
|
25 buffer_create_from_const_data(ret, str, len + 1); |
8007 | 26 str_truncate(ret, len); |
27 return ret; | |
28 } | |
29 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
30 string_t *t_str_new(size_t initial_size) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 { |
1782
2f3d906d99d8
data_stack_pool split into two: unsafe_data_stack_pool which works like
Timo Sirainen <tss@iki.fi>
parents:
1763
diff
changeset
|
32 return str_new(pool_datastack_create(), initial_size); |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
34 |
8263 | 35 string_t *t_str_new_const(const char *str, size_t len) |
36 { | |
37 return str_new_const(pool_datastack_create(), str, len); | |
38 } | |
39 | |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
2839
diff
changeset
|
40 void str_free(string_t **str) |
995 | 41 { |
6414
a6a49d5efc59
Changed buffer_free() and buffer_free_without_data() APIs to take ** pointer
Timo Sirainen <tss@iki.fi>
parents:
5866
diff
changeset
|
42 buffer_free(str); |
995 | 43 } |
44 | |
2708
f1e9f3ec8135
Buffer API change: we no longer support limited sized buffers where
Timo Sirainen <tss@iki.fi>
parents:
2152
diff
changeset
|
45 static void str_add_nul(string_t *str) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
46 { |
8007 | 47 const unsigned char *data = str_data(str); |
48 size_t len = str_len(str); | |
49 size_t alloc = buffer_get_size(str); | |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
50 |
8007 | 51 if (len == alloc || data[len] != '\0') { |
52 buffer_write(str, len, "", 1); | |
53 /* remove the \0 - we don't want to keep it */ | |
54 buffer_set_used_size(str, len); | |
55 } | |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
56 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
57 |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
2839
diff
changeset
|
58 char *str_free_without_data(string_t **str) |
2839 | 59 { |
3879
928229f8b3e6
deinit, unref, destroy, close, free, etc. functions now take a pointer to
Timo Sirainen <tss@iki.fi>
parents:
2839
diff
changeset
|
60 str_add_nul(*str); |
6414
a6a49d5efc59
Changed buffer_free() and buffer_free_without_data() APIs to take ** pointer
Timo Sirainen <tss@iki.fi>
parents:
5866
diff
changeset
|
61 return buffer_free_without_data(str); |
2839 | 62 } |
63 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
64 const char *str_c(string_t *str) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
65 { |
2708
f1e9f3ec8135
Buffer API change: we no longer support limited sized buffers where
Timo Sirainen <tss@iki.fi>
parents:
2152
diff
changeset
|
66 str_add_nul(str); |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
67 return buffer_get_data(str, NULL); |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
68 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 |
4451
1a35d53c18fc
Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
70 char *str_c_modifiable(string_t *str) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
71 { |
2708
f1e9f3ec8135
Buffer API change: we no longer support limited sized buffers where
Timo Sirainen <tss@iki.fi>
parents:
2152
diff
changeset
|
72 str_add_nul(str); |
4451
1a35d53c18fc
Array API redesigned to work using unions. It now provides type safety
Timo Sirainen <tss@iki.fi>
parents:
3879
diff
changeset
|
73 return buffer_get_modifiable_data(str, NULL); |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
75 |
6967 | 76 bool str_equals(const string_t *str1, const string_t *str2) |
77 { | |
78 if (str1->used != str2->used) | |
79 return FALSE; | |
80 | |
81 return memcmp(str1->data, str2->data, str1->used) == 0; | |
82 } | |
83 | |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
84 void str_append_n(string_t *str, const void *cstr, size_t max_len) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
85 { |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
86 size_t len; |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
87 |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
88 len = 0; |
898
0d5be52d7131
Use unsigned char* when accessing non-NUL terminating strings. Compiler
Timo Sirainen <tss@iki.fi>
parents:
859
diff
changeset
|
89 while (len < max_len && ((const char *)cstr)[len] != '\0') |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
90 len++; |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
91 |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
92 buffer_append(str, cstr, len); |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
93 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
94 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
95 void str_printfa(string_t *str, const char *fmt, ...) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
96 { |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
97 va_list args; |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
98 |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
99 va_start(args, fmt); |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
100 str_vprintfa(str, fmt, args); |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
101 va_end(args); |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
102 } |
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
103 |
903
fd8888f6f037
Naming style changes, finally got tired of most of the typedefs. Also the
Timo Sirainen <tss@iki.fi>
parents:
898
diff
changeset
|
104 void str_vprintfa(string_t *str, const char *fmt, va_list args) |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
105 { |
10214
c84c4f705e69
Minor memory allocation tweaks.
Timo Sirainen <tss@iki.fi>
parents:
9623
diff
changeset
|
106 #define SNPRINTF_INITIAL_EXTRA_SIZE 128 |
5866
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
107 va_list args2; |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
108 char *tmp; |
21322
5ab8dc1a4a6f
global: Change string position/length from unsigned int to size_t
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
21019
diff
changeset
|
109 size_t init_size; |
5866
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
110 size_t pos = str->used; |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
111 int ret, ret2; |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
112 |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
113 VA_COPY(args2, args); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
114 |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
115 /* the format string is modified only if %m exists in it. it happens |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
116 only in error conditions, so don't try to t_push() here since it'll |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
117 just slow down the normal code path. */ |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
118 fmt = printf_format_fix_get_len(fmt, &init_size); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
119 init_size += SNPRINTF_INITIAL_EXTRA_SIZE; |
837
ec6dd72cb8e3
Use vsnprintf() always when possible, even if we went through the
Timo Sirainen <tss@iki.fi>
parents:
834
diff
changeset
|
120 |
5866
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
121 /* @UNSAFE */ |
20104
252215077391
global: Use buffer_get_writable_size() where possible
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
122 if (pos+init_size > buffer_get_writable_size(str) && |
252215077391
global: Use buffer_get_writable_size() where possible
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
123 pos < buffer_get_writable_size(str)) { |
14966
fff00bb85ae4
str_*printfa(): Avoid growing underlying buffer if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
124 /* avoid growing buffer larger if possible. this is also |
fff00bb85ae4
str_*printfa(): Avoid growing underlying buffer if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
125 required if buffer isn't dynamically growing. */ |
20104
252215077391
global: Use buffer_get_writable_size() where possible
Timo Sirainen <timo.sirainen@dovecot.fi>
parents:
19552
diff
changeset
|
126 init_size = buffer_get_writable_size(str)-pos; |
14966
fff00bb85ae4
str_*printfa(): Avoid growing underlying buffer if possible.
Timo Sirainen <tss@iki.fi>
parents:
14133
diff
changeset
|
127 } |
5866
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
128 tmp = buffer_get_space_unsafe(str, pos, init_size); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
129 ret = vsnprintf(tmp, init_size, fmt, args); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
130 i_assert(ret >= 0); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
131 |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
132 if ((unsigned int)ret >= init_size) { |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
133 /* didn't fit with the first guess. now we know the size, |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
134 so try again. */ |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
135 tmp = buffer_get_space_unsafe(str, pos, ret + 1); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
136 ret2 = vsnprintf(tmp, ret + 1, fmt, args2); |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
137 i_assert(ret2 == ret); |
5681
09415e6a0892
Require C99 compatible vsnprintf(). Removed printf_string_upper_bound() and
Timo Sirainen <tss@iki.fi>
parents:
4451
diff
changeset
|
138 } |
17396
03870eea2857
lib: pair VA_COPY with va_end
Phil Carmody <phil@dovecot.fi>
parents:
17318
diff
changeset
|
139 va_end(args2); |
5866
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
140 |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
141 /* drop the unused data, including terminating NUL */ |
092b9d3b7f97
Implement str_vprintfa() by making vsnprintf() write directly to the string.
Timo Sirainen <tss@iki.fi>
parents:
5681
diff
changeset
|
142 buffer_set_used_size(str, pos + ret); |
833
41ec8cadd238
Replaced TempString with a String which can use any memory pool and uses
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
143 } |