1 | /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB |
2 | 2016 MariaDB Corporation AB |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public |
15 | License along with this library; if not, write to the Free |
16 | Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
17 | MA 02111-1301, USA */ |
18 | |
19 | /* |
20 | Code for handling strings which can grow dynamically. |
21 | Copyright Monty Program KB. |
22 | By monty. |
23 | */ |
24 | |
25 | #include <ma_global.h> |
26 | #include <ma_sys.h> |
27 | #include <ma_string.h> |
28 | |
29 | my_bool ma_init_dynamic_string(DYNAMIC_STRING *str, const char *init_str, |
30 | size_t init_alloc, size_t alloc_increment) |
31 | { |
32 | uint length; |
33 | |
34 | if (!alloc_increment) |
35 | alloc_increment=128; |
36 | length=1; |
37 | if (init_str && (length= (uint) strlen(init_str)+1) < init_alloc) |
38 | init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment; |
39 | if (!init_alloc) |
40 | init_alloc=alloc_increment; |
41 | |
42 | if (!(str->str=(char*) malloc(init_alloc))) |
43 | return(TRUE); |
44 | str->length=length-1; |
45 | if (init_str) |
46 | memcpy(str->str,init_str,length); |
47 | str->max_length=init_alloc; |
48 | str->alloc_increment=alloc_increment; |
49 | return(FALSE); |
50 | } |
51 | |
52 | my_bool ma_dynstr_set(DYNAMIC_STRING *str, const char *init_str) |
53 | { |
54 | uint length; |
55 | |
56 | if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length) |
57 | { |
58 | str->max_length=((length+str->alloc_increment-1)/str->alloc_increment)* |
59 | str->alloc_increment; |
60 | if (!str->max_length) |
61 | str->max_length=str->alloc_increment; |
62 | if (!(str->str=(char*) realloc(str->str,str->max_length))) |
63 | return(TRUE); |
64 | } |
65 | if (init_str) |
66 | { |
67 | str->length=length-1; |
68 | memcpy(str->str,init_str,length); |
69 | } |
70 | else |
71 | str->length=0; |
72 | return(FALSE); |
73 | } |
74 | |
75 | |
76 | my_bool ma_dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size) |
77 | { |
78 | if (!additional_size) return(FALSE); |
79 | if (str->length + additional_size > str->max_length) |
80 | { |
81 | str->max_length=((str->length + additional_size+str->alloc_increment-1)/ |
82 | str->alloc_increment)*str->alloc_increment; |
83 | if (!(str->str=(char*) realloc(str->str,str->max_length))) |
84 | return(TRUE); |
85 | } |
86 | return(FALSE); |
87 | } |
88 | |
89 | |
90 | my_bool ma_dynstr_append(DYNAMIC_STRING *str, const char *append) |
91 | { |
92 | return ma_dynstr_append_mem(str,append,strlen(append)); |
93 | } |
94 | |
95 | my_bool ma_dynstr_append_quoted(DYNAMIC_STRING *str, |
96 | const char *append, size_t len, |
97 | char quote) |
98 | { |
99 | size_t additional= str->alloc_increment; |
100 | size_t lim= additional; |
101 | uint i; |
102 | |
103 | if (ma_dynstr_realloc(str, len + additional + 2)) |
104 | return TRUE; |
105 | str->str[str->length++]= quote; |
106 | for (i= 0; i < len; i++) |
107 | { |
108 | register char c= append[i]; |
109 | if (c == quote || c == '\\') |
110 | { |
111 | if (!lim) |
112 | { |
113 | if (ma_dynstr_realloc(str, additional)) |
114 | return TRUE; |
115 | lim= additional; |
116 | } |
117 | lim--; |
118 | str->str[str->length++]= '\\'; |
119 | } |
120 | str->str[str->length++]= c; |
121 | } |
122 | str->str[str->length++]= quote; |
123 | return FALSE; |
124 | } |
125 | |
126 | my_bool ma_dynstr_append_mem(DYNAMIC_STRING *str, const char *append, |
127 | size_t length) |
128 | { |
129 | char *new_ptr; |
130 | if (str->length+length >= str->max_length) |
131 | { |
132 | size_t new_length=(str->length+length+str->alloc_increment)/ |
133 | str->alloc_increment; |
134 | new_length*=str->alloc_increment; |
135 | if (!(new_ptr=(char*) realloc(str->str,new_length))) |
136 | return TRUE; |
137 | str->str=new_ptr; |
138 | str->max_length=new_length; |
139 | } |
140 | memcpy(str->str + str->length,append,length); |
141 | str->length+=length; |
142 | str->str[str->length]=0; /* Safety for C programs */ |
143 | return FALSE; |
144 | } |
145 | |
146 | |
147 | void ma_dynstr_free(DYNAMIC_STRING *str) |
148 | { |
149 | if (str->str) |
150 | { |
151 | free(str->str); |
152 | str->str=0; |
153 | } |
154 | } |
155 | |
156 | char *ma_strmake(register char *dst, register const char *src, size_t length) |
157 | { |
158 | while (length--) |
159 | if (! (*dst++ = *src++)) |
160 | return dst-1; |
161 | *dst=0; |
162 | return dst; |
163 | } |
164 | |