1 /* Copyright (c) 2000, 2021, Oracle and/or its affiliates.
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    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 
24 /* Mallocs for used in threads */
25 
26 #include "thr_malloc.h"
27 #include "sql_class.h"
28 
29 #include <algorithm>
30 
31 using std::min;
32 using std::max;
33 
34 extern "C" void sql_alloc_error_handler(void);
35 
init_sql_alloc(PSI_memory_key key,MEM_ROOT * mem_root,size_t block_size,size_t pre_alloc)36 void init_sql_alloc(PSI_memory_key key,
37                     MEM_ROOT *mem_root, size_t block_size, size_t pre_alloc)
38 {
39   init_alloc_root(key, mem_root, block_size, pre_alloc);
40   mem_root->error_handler=sql_alloc_error_handler;
41 }
42 
sql_alloc(size_t Size)43 void *sql_alloc(size_t Size)
44 {
45   MEM_ROOT *root= *my_thread_get_THR_MALLOC();
46   return alloc_root(root,Size);
47 }
48 
49 
sql_calloc(size_t size)50 void *sql_calloc(size_t size)
51 {
52   void *ptr;
53   if ((ptr=sql_alloc(size)))
54     memset(ptr, 0, size);
55   return ptr;
56 }
57 
58 
sql_strdup(const char * str)59 char *sql_strdup(const char *str)
60 {
61   size_t len= strlen(str)+1;
62   char *pos;
63   if ((pos= (char*) sql_alloc(len)))
64     memcpy(pos,str,len);
65   return pos;
66 }
67 
68 
sql_strmake(const char * str,size_t len)69 char *sql_strmake(const char *str, size_t len)
70 {
71   char *pos;
72   if ((pos= (char*) sql_alloc(len+1)))
73   {
74     memcpy(pos,str,len);
75     pos[len]=0;
76   }
77   return pos;
78 }
79 
80 
sql_memdup(const void * ptr,size_t len)81 void* sql_memdup(const void *ptr, size_t len)
82 {
83   void *pos;
84   if ((pos= sql_alloc(len)))
85     memcpy(pos,ptr,len);
86   return pos;
87 }
88 
89 
sql_strmake_with_convert(const char * str,size_t arg_length,const CHARSET_INFO * from_cs,size_t max_res_length,const CHARSET_INFO * to_cs,size_t * result_length)90 char *sql_strmake_with_convert(const char *str, size_t arg_length,
91 			       const CHARSET_INFO *from_cs,
92 			       size_t max_res_length,
93 			       const CHARSET_INFO *to_cs, size_t *result_length)
94 {
95   char *pos;
96   size_t new_length= to_cs->mbmaxlen*arg_length;
97   max_res_length--;				// Reserve place for end null
98 
99   set_if_smaller(new_length, max_res_length);
100   if (!(pos= (char*) sql_alloc(new_length+1)))
101     return pos;					// Error
102 
103   if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
104   {
105     // Safety if to_cs->mbmaxlen > 0
106     new_length= min(arg_length, max_res_length);
107     memcpy(pos, str, new_length);
108   }
109   else
110   {
111     uint dummy_errors;
112     new_length= copy_and_convert(pos, new_length, to_cs, str,
113 				 arg_length, from_cs, &dummy_errors);
114   }
115   pos[new_length]= 0;
116   *result_length= new_length;
117   return pos;
118 }
119 
120