1 /* Copyright (c) 2017, 2019, 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 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 #include <fcntl.h>
24 #include <mysql/components/component_implementation.h>
25 #include <mysql/components/service_implementation.h>
26 #include <mysql/components/services/mysql_string.h>
27 #include <stdio.h>
28 
29 #include "m_string.h"  // strlen
30 #include "my_inttypes.h"
31 #include "my_sys.h"  // my_write, my_malloc
32 #include "sql_string.h"
33 #include "test_string_service_long.h"  // same header
34 
35 FILE *outfile;
36 
37 // Value must be a multiple of 16 (or TEST_TEXT_LIT_LENGTH)
38 #define MAX_BUFFER_LENGTH 128
39 int log_text_len = 0;
40 char log_text[MAX_BUFFER_LENGTH + 16];
41 
42 //  strcpy (log_text, lit_log_text);
43 
44 #define WRITE_LOG(format, lit_log_text)                   \
45   log_text_len = sprintf(log_text, format, lit_log_text); \
46   fwrite((uchar *)log_text, sizeof(char), log_text_len, outfile)
47 
48 /**
49   This file contains a test (example) component, which tests the service
50   "string".
51 */
52 
test_charset(const char * charset,const char * text,int buff_len)53 bool test_charset(const char *charset, const char *text, int buff_len) {
54   WRITE_LOG("%s\n",
55             "-------------------------------------------------------------");
56   WRITE_LOG("Charset: %s\n", charset);
57   WRITE_LOG("%s\n", text);
58   my_h_string out_string = nullptr;
59   char low_test_text[MAX_BUFFER_LENGTH];
60   char upper_test_text[MAX_BUFFER_LENGTH];
61   if (mysql_service_mysql_string_factory->create(&out_string)) {
62     WRITE_LOG("%s\n", "Create string failed.");
63   } else {
64     mysql_service_mysql_string_factory->destroy(out_string);
65     WRITE_LOG("%s\n", "Destroy string object.");
66     // Valid convert from buffer
67     if (mysql_service_mysql_string_converter->convert_from_buffer(
68             &out_string,
69             text,  // its a input buffer
70             buff_len, charset)) {
71       WRITE_LOG("%s\n", "Convert from buffer failed.");
72     } else {
73       uint out_length = 0;
74       WRITE_LOG("%s\n", "Convert from buffer passed.");
75       // valid get number of chars
76       if (mysql_service_mysql_string_character_access->get_char_length(
77               out_string, &out_length)) {
78         WRITE_LOG("%s\n", "Get number of chars failed.");
79       } else {
80         WRITE_LOG("Number of chars: %d\n", out_length);
81       }
82       out_length = 0;
83       // valid get number of bytes
84       if (mysql_service_mysql_string_byte_access->get_byte_length(
85               out_string, &out_length)) {
86         WRITE_LOG("%s\n", "Get number of bytes failed.");
87       } else {
88         WRITE_LOG("Number of bytes: %d\n", out_length);
89       }
90       // Convert to low string
91       my_h_string low_string = nullptr;
92       if (mysql_service_mysql_string_factory->create(&low_string)) {
93         WRITE_LOG("%s\n", "Create lower string object failed.");
94       } else {
95         if (mysql_service_mysql_string_case->tolower(&low_string, out_string)) {
96           WRITE_LOG("%s\n", "Tolower failed.");
97         } else {
98           WRITE_LOG("%s\n", "Tolower passed:");
99           // Convert low string to buffer
100           if (mysql_service_mysql_string_converter->convert_to_buffer(
101                   low_string, low_test_text, MAX_BUFFER_LENGTH, charset)) {
102             WRITE_LOG("%s\n", "Convert to buffer failed.");
103           } else {
104             WRITE_LOG("%s\n", low_test_text);
105           }
106         }
107       }
108       mysql_service_mysql_string_factory->destroy(low_string);
109       // Convert to upper string
110       my_h_string upper_string = nullptr;
111       if (mysql_service_mysql_string_factory->create(&upper_string)) {
112         WRITE_LOG("%s\n", "Create upper string object failed.");
113       } else {
114         if (mysql_service_mysql_string_case->toupper(&upper_string,
115                                                      out_string)) {
116           WRITE_LOG("%s\n", "Toupper failed.");
117         } else {
118           WRITE_LOG("%s\n", "Toupper passed:");
119           if (mysql_service_mysql_string_converter->convert_to_buffer(
120                   upper_string, upper_test_text, MAX_BUFFER_LENGTH, charset)) {
121             WRITE_LOG("%s\n", "Convert to buffer failed.");
122           } else {
123             WRITE_LOG("%s\n", upper_test_text);
124           }
125         }
126       }
127       mysql_service_mysql_string_factory->destroy(upper_string);
128       // Get char with index 1
129       ulong out_char;
130       if (mysql_service_mysql_string_character_access->get_char(out_string, 1,
131                                                                 &out_char)) {
132         WRITE_LOG("%s\n", "Get char with index 1 failed.");
133       } else {
134         WRITE_LOG("%s\n", "Get char with index 1 passed.");
135       }
136       // Get char with index > strlen : Must fail
137       if (mysql_service_mysql_string_character_access->get_char(
138               out_string, strlen(text) + 1, &out_char)) {
139         WRITE_LOG("%s\n", "Get char with index > strlen passed.");
140       }
141       // Get byte with index strlen
142       uint out_byte;
143       if (mysql_service_mysql_string_byte_access->get_byte(
144               out_string, strlen(text) - 1, &out_byte)) {
145         WRITE_LOG("%s\n", "Get byte with index strlen failed.");
146       } else {
147         WRITE_LOG("%s\n", "Get byte with index strlen passed.");
148       }
149     }
150   }
151   mysql_service_mysql_string_factory->destroy(out_string);
152   WRITE_LOG("%s\n", "Destroy string object.");
153   return false;
154 }
155 
156 /**
157   Initialization entry method for test component.
158   It executes the tests of the service.
159 */
test_string_service_init()160 mysql_service_status_t test_string_service_init() {
161   const char *chs_latin1 = "latin1";
162   const char *chs_utf8 = "utf8";
163   const char *chs_gb18030 = "gb18030";
164   //  const char* charset="utf8mb4";
165 
166 #define TEST_TEXT_LIT_LENGTH 48
167   const char *test_text_eng =
168       "Greetings from  beautiful Austria at March, 9th!";  // 48 chars
169   const char *test_text_ger =
170       "Grüße  aus  dem  schönen  Österreich am 9. März!";  // 48 chars
171   const char *test_text_chinese = "遥想公瑾当年,小乔初嫁了,雄姿英发";
172   bool retcode = false;
173   const char *filename = "test_string_service_charset.log";
174   unlink(filename);
175   outfile = fopen(filename, "w+");
176 
177   WRITE_LOG("%s\n", "test_string_service_long init:");
178 
179   retcode = test_charset(chs_latin1, test_text_eng, TEST_TEXT_LIT_LENGTH);
180   retcode = test_charset(chs_latin1, test_text_ger, TEST_TEXT_LIT_LENGTH);
181   retcode = test_charset(chs_utf8, test_text_eng, TEST_TEXT_LIT_LENGTH);
182   retcode = test_charset(chs_utf8, test_text_ger, TEST_TEXT_LIT_LENGTH);
183   retcode = test_charset(chs_utf8, test_text_chinese, TEST_TEXT_LIT_LENGTH);
184   retcode = test_charset(chs_gb18030, test_text_chinese, TEST_TEXT_LIT_LENGTH);
185 
186   WRITE_LOG("%s\n", "End of init");
187   fclose(outfile);
188 
189   return retcode;
190 }
191 
192 /**
193   De-initialization method for Component.
194 */
test_string_service_deinit()195 mysql_service_status_t test_string_service_deinit() { return false; }
196 
197 /* An empty list as no service is provided. */
198 BEGIN_COMPONENT_PROVIDES(test_string_service_charset)
199 END_COMPONENT_PROVIDES();
200 
201 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_factory);
202 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_converter);
203 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_character_access);
204 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_byte_access);
205 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_case);
206 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_iterator);
207 REQUIRES_SERVICE_PLACEHOLDER(mysql_string_ctype);
208 
209 /* A list of required services. */
210 BEGIN_COMPONENT_REQUIRES(test_string_service_charset)
211 REQUIRES_SERVICE(mysql_string_factory),
212     REQUIRES_SERVICE(mysql_string_converter),
213     REQUIRES_SERVICE(mysql_string_character_access),
214     REQUIRES_SERVICE(mysql_string_byte_access),
215     REQUIRES_SERVICE(mysql_string_case),
216     REQUIRES_SERVICE(mysql_string_iterator),
217     REQUIRES_SERVICE(mysql_string_ctype), END_COMPONENT_REQUIRES();
218 
219 /* A list of metadata to describe the Component. */
220 BEGIN_COMPONENT_METADATA(test_string_service_charset)
221 METADATA("mysql.author", "Oracle Corporation"),
222     METADATA("mysql.license", "GPL"),
223     METADATA("test_string_charset_service", "1"), END_COMPONENT_METADATA();
224 
225 /* Declaration of the Component. */
226 DECLARE_COMPONENT(test_string_service_charset,
227                   "mysql:test_string_service_charset")
228 test_string_service_init, test_string_service_deinit END_DECLARE_COMPONENT();
229 
230 /* Defines list of Components contained in this library. Note that for now
231   we assume that library will have exactly one Component. */
232 DECLARE_LIBRARY_COMPONENTS &COMPONENT_REF(test_string_service_charset)
233     END_DECLARE_LIBRARY_COMPONENTS
234