1 /* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 Without limiting anything contained in the foregoing, this file,
15 which is part of C Driver for MySQL (Connector/C), is also subject to the
16 Universal FOSS Exception, version 1.0, a copy of which can be found at
17 http://oss.oracle.com/licenses/universal-foss-exception.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License, version 2.0, for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
27
28 /*
29 Code for handling strings with can grow dynamicly.
30 Copyright Monty Program KB.
31 By monty.
32 */
33
34 #include "mysys_priv.h"
35 #include <m_string.h>
36
init_dynamic_string(DYNAMIC_STRING * str,const char * init_str,size_t init_alloc,size_t alloc_increment)37 my_bool init_dynamic_string(DYNAMIC_STRING *str, const char *init_str,
38 size_t init_alloc, size_t alloc_increment)
39 {
40 size_t length;
41 DBUG_ENTER("init_dynamic_string");
42
43 if (!alloc_increment)
44 alloc_increment=128;
45 length=1;
46 if (init_str && (length= strlen(init_str)+1) < init_alloc)
47 init_alloc=((length+alloc_increment-1)/alloc_increment)*alloc_increment;
48 if (!init_alloc)
49 init_alloc=alloc_increment;
50
51 if (!(str->str=(char*) my_malloc(init_alloc,MYF(MY_WME))))
52 DBUG_RETURN(TRUE);
53 str->length=length-1;
54 if (init_str)
55 memcpy(str->str,init_str,length);
56 str->max_length=init_alloc;
57 str->alloc_increment=alloc_increment;
58 DBUG_RETURN(FALSE);
59 }
60
61
dynstr_set(DYNAMIC_STRING * str,const char * init_str)62 my_bool dynstr_set(DYNAMIC_STRING *str, const char *init_str)
63 {
64 uint length=0;
65 DBUG_ENTER("dynstr_set");
66
67 if (init_str && (length= (uint) strlen(init_str)+1) > str->max_length)
68 {
69 str->max_length=((length+str->alloc_increment-1)/str->alloc_increment)*
70 str->alloc_increment;
71 if (!str->max_length)
72 str->max_length=str->alloc_increment;
73 if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
74 DBUG_RETURN(TRUE);
75 }
76 if (init_str)
77 {
78 str->length=length-1;
79 memcpy(str->str,init_str,length);
80 }
81 else
82 str->length=0;
83 DBUG_RETURN(FALSE);
84 }
85
86
dynstr_realloc(DYNAMIC_STRING * str,size_t additional_size)87 my_bool dynstr_realloc(DYNAMIC_STRING *str, size_t additional_size)
88 {
89 DBUG_ENTER("dynstr_realloc");
90
91 if (!additional_size) DBUG_RETURN(FALSE);
92 if (str->length + additional_size > str->max_length)
93 {
94 str->max_length=((str->length + additional_size+str->alloc_increment-1)/
95 str->alloc_increment)*str->alloc_increment;
96 if (!(str->str=(char*) my_realloc(str->str,str->max_length,MYF(MY_WME))))
97 DBUG_RETURN(TRUE);
98 }
99 DBUG_RETURN(FALSE);
100 }
101
102
dynstr_append(DYNAMIC_STRING * str,const char * append)103 my_bool dynstr_append(DYNAMIC_STRING *str, const char *append)
104 {
105 return dynstr_append_mem(str,append,(uint) strlen(append));
106 }
107
108
dynstr_append_mem(DYNAMIC_STRING * str,const char * append,size_t length)109 my_bool dynstr_append_mem(DYNAMIC_STRING *str, const char *append,
110 size_t length)
111 {
112 char *new_ptr;
113 if (str->length+length >= str->max_length)
114 {
115 size_t new_length=(str->length+length+str->alloc_increment)/
116 str->alloc_increment;
117 new_length*=str->alloc_increment;
118 if (!(new_ptr=(char*) my_realloc(str->str,new_length,MYF(MY_WME))))
119 return TRUE;
120 str->str=new_ptr;
121 str->max_length=new_length;
122 }
123 memcpy(str->str + str->length,append,length);
124 str->length+=length;
125 str->str[str->length]=0; /* Safety for C programs */
126 return FALSE;
127 }
128
129
dynstr_trunc(DYNAMIC_STRING * str,size_t n)130 my_bool dynstr_trunc(DYNAMIC_STRING *str, size_t n)
131 {
132 str->length-=n;
133 str->str[str->length]= '\0';
134 return FALSE;
135 }
136
137 /*
138 Concatenates any number of strings, escapes any OS quote in the result then
139 surround the whole affair in another set of quotes which is finally appended
140 to specified DYNAMIC_STRING. This function is especially useful when
141 building strings to be executed with the system() function.
142
143 @param str Dynamic String which will have addtional strings appended.
144 @param append String to be appended.
145 @param ... Optional. Additional string(s) to be appended.
146
147 @note The final argument in the list must be NullS even if no additional
148 options are passed.
149
150 @return True = Success.
151 */
152
dynstr_append_os_quoted(DYNAMIC_STRING * str,const char * append,...)153 my_bool dynstr_append_os_quoted(DYNAMIC_STRING *str, const char *append, ...)
154 {
155 #ifdef __WIN__
156 const char *quote_str= "\"";
157 const uint quote_len= 1;
158 #else
159 const char *quote_str= "\'";
160 const uint quote_len= 1;
161 #endif /* __WIN__ */
162 my_bool ret= TRUE;
163 va_list dirty_text;
164
165 ret&= dynstr_append_mem(str, quote_str, quote_len); /* Leading quote */
166 va_start(dirty_text, append);
167 while (append != NullS)
168 {
169 const char *cur_pos= append;
170 const char *next_pos= cur_pos;
171
172 /* Search for quote in each string and replace with escaped quote */
173 while(*(next_pos= strcend(cur_pos, quote_str[0])) != '\0')
174 {
175 ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
176 ret&= dynstr_append_mem(str ,"\\", 1);
177 ret&= dynstr_append_mem(str, quote_str, quote_len);
178 cur_pos= next_pos + 1;
179 }
180 ret&= dynstr_append_mem(str, cur_pos, (uint) (next_pos - cur_pos));
181 append= va_arg(dirty_text, char *);
182 }
183 va_end(dirty_text);
184 ret&= dynstr_append_mem(str, quote_str, quote_len); /* Trailing quote */
185
186 return ret;
187 }
188
189
dynstr_free(DYNAMIC_STRING * str)190 void dynstr_free(DYNAMIC_STRING *str)
191 {
192 my_free(str->str);
193 str->str= NULL;
194 }
195