diff options
author | Alexander Barkov <bar@mariadb.org> | 2016-10-10 14:36:09 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2016-10-10 14:36:09 +0400 |
commit | 5058ced5df7a4ee3ff011577829fb2e4a6f47843 (patch) | |
tree | 8f90cd07e71cef5dc09adfd825712f812f978f57 | |
parent | a6f032af5778018051d41fc8ba7e9c983b4b7fbf (diff) | |
download | mariadb-git-5058ced5df7a4ee3ff011577829fb2e4a6f47843.tar.gz |
MDEV-7769 MY_CHARSET_INFO refactoring# On branch 10.2
Part 3 (final): removing MY_CHARSET_HANDLER::well_formed_len().
34 files changed, 130 insertions, 342 deletions
diff --git a/include/m_ctype.h b/include/m_ctype.h index c50763ed570..152c7dd2e29 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -397,7 +397,6 @@ typedef struct */ typedef struct { - MY_STRCOPY_STATUS m_native_copy_status; const char *m_cannot_convert_error_pos; } MY_STRCONV_STATUS; @@ -410,9 +409,6 @@ struct my_charset_handler_st size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e); size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e, size_t pos); - size_t (*well_formed_len)(CHARSET_INFO *, - const char *b,const char *e, - size_t nchars, int *error); size_t (*lengthsp)(CHARSET_INFO *, const char *ptr, size_t length); size_t (*numcells)(CHARSET_INFO *, const char *b, const char *e); @@ -817,8 +813,6 @@ int my_wildcmp_bin(CHARSET_INFO *, size_t my_numchars_8bit(CHARSET_INFO *, const char *b, const char *e); size_t my_numcells_8bit(CHARSET_INFO *, const char *b, const char *e); size_t my_charpos_8bit(CHARSET_INFO *, const char *b, const char *e, size_t pos); -size_t my_well_formed_len_8bit(CHARSET_INFO *, const char *b, const char *e, - size_t pos, int *error); size_t my_well_formed_char_length_8bit(CHARSET_INFO *cs, const char *b, const char *e, size_t nchars, @@ -850,8 +844,6 @@ int my_wildcmp_mb(CHARSET_INFO *, size_t my_numchars_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_numcells_mb(CHARSET_INFO *, const char *b, const char *e); size_t my_charpos_mb(CHARSET_INFO *, const char *b, const char *e, size_t pos); -size_t my_well_formed_len_mb(CHARSET_INFO *, const char *b, const char *e, - size_t pos, int *error); uint my_instr_mb(CHARSET_INFO *, const char *b, size_t b_length, const char *s, size_t s_length, @@ -994,7 +986,9 @@ uint32 my_convert_using_func(char *to, uint32 to_length, CHARSET_INFO *to_cs, */ size_t my_convert_fix(CHARSET_INFO *dstcs, char *dst, size_t dst_length, CHARSET_INFO *srccs, const char *src, size_t src_length, - size_t nchars, MY_STRCONV_STATUS *status); + size_t nchars, + MY_STRCOPY_STATUS *copy_status, + MY_STRCONV_STATUS *conv_status); #define _MY_U 01 /* Upper case */ #define _MY_L 02 /* Lower case */ @@ -1089,6 +1083,22 @@ uint my_charlen_fix(CHARSET_INFO *cs, const char *str, const char *end) } +/* + A compatibility replacement pure C function for the former + cs->cset->well_formed_len(). + In C++ code please use Well_formed_prefix::length() instead. +*/ +static inline size_t +my_well_formed_length(CHARSET_INFO *cs, const char *b, const char *e, + size_t nchars, int *error) +{ + MY_STRCOPY_STATUS status; + (void) cs->cset->well_formed_char_length(cs, b, e, nchars, &status); + *error= status.m_well_formed_error_pos == NULL ? 0 : 1; + return status.m_source_end_pos - b; +} + + #define my_caseup_str(s, a) ((s)->cset->caseup_str((s), (a))) #define my_casedn_str(s, a) ((s)->cset->casedn_str((s), (a))) #define my_strntol(s, a, b, c, d, e) ((s)->cset->strntol((s),(a),(b),(c),(d),(e))) diff --git a/sql/field.cc b/sql/field.cc index ba0ebb253f4..e4ecb7422f2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7902,12 +7902,9 @@ int Field_blob::copy_value(Field_blob *from) from->get_ptr(&data); if (packlength < from->packlength) { - int well_formed_errors; set_if_smaller(length, Field_blob::max_data_length()); - length= field_charset->cset->well_formed_len(field_charset, - (const char *) data, - (const char *) data + length, - length, &well_formed_errors); + length= (uint32) Well_formed_prefix(field_charset, + (const char *) data, length).length(); rc= report_if_important_data((const char *) data + length, (const char *) data + from->get_length(), true); @@ -7943,9 +7940,8 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs) copy_length= table->in_use->variables.group_concat_max_len; if (new_length > copy_length) { - int well_formed_error; - new_length= cs->cset->well_formed_len(cs, from, from + copy_length, - new_length, &well_formed_error); + new_length= Well_formed_prefix(cs, + from, copy_length, new_length).length(); table->blob_storage->set_truncated_value(true); } if (!(tmp= table->blob_storage->store(from, new_length))) diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 263c5bb5017..85101fd5f0a 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -467,20 +467,19 @@ static void do_cut_string(Copy_field *copy) static void do_cut_string_complex(Copy_field *copy) { // Shorter string field - int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); const uchar *from_end= copy->from_ptr + copy->from_length; - uint copy_length= cs->cset->well_formed_len(cs, - (char*) copy->from_ptr, - (char*) from_end, - copy->to_length / cs->mbmaxlen, - &well_formed_error); + Well_formed_prefix prefix(cs, + (char*) copy->from_ptr, + (char*) from_end, + copy->to_length / cs->mbmaxlen); + uint copy_length= prefix.length(); if (copy->to_length < copy_length) copy_length= copy->to_length; memcpy(copy->to_ptr, copy->from_ptr, copy_length); /* Check if we lost any important characters */ - if (well_formed_error || + if (prefix.well_formed_error_pos() || cs->cset->scan(cs, (char*) copy->from_ptr + copy_length, (char*) from_end, MY_SEQ_SPACES) < (copy->from_length - copy_length)) @@ -534,22 +533,19 @@ static void do_varstring1(Copy_field *copy) static void do_varstring1_mb(Copy_field *copy) { - int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); uint from_length= (uint) *(uchar*) copy->from_ptr; const uchar *from_ptr= copy->from_ptr + 1; uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen; - uint length= cs->cset->well_formed_len(cs, (char*) from_ptr, - (char*) from_ptr + from_length, - to_char_length, &well_formed_error); - if (length < from_length) + Well_formed_prefix prefix(cs, (char*) from_ptr, from_length, to_char_length); + if (prefix.length() < from_length) { if (current_thd->count_cuted_fields) copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); } - *copy->to_ptr= (uchar) length; - memcpy(copy->to_ptr + 1, from_ptr, length); + *copy->to_ptr= (uchar) prefix.length(); + memcpy(copy->to_ptr + 1, from_ptr, prefix.length()); } @@ -572,22 +568,19 @@ static void do_varstring2(Copy_field *copy) static void do_varstring2_mb(Copy_field *copy) { - int well_formed_error; CHARSET_INFO *cs= copy->from_field->charset(); uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen; uint from_length= uint2korr(copy->from_ptr); const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH; - uint length= cs->cset->well_formed_len(cs, (char*) from_beg, - (char*) from_beg + from_length, - char_length, &well_formed_error); - if (length < from_length) + Well_formed_prefix prefix(cs, (char*) from_beg, from_length, char_length); + if (prefix.length() < from_length) { if (current_thd->count_cuted_fields) copy->to_field->set_warning(Sql_condition::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); } - int2store(copy->to_ptr, length); - memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length); + int2store(copy->to_ptr, prefix.length()); + memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, prefix.length()); } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 83378c2e994..51a6c2bd3eb 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3156,21 +3156,18 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), /* stop if length of result more than max_length */ if (result->length() > max_length) { - int well_formed_error; CHARSET_INFO *cs= item->collation.collation; const char *ptr= result->ptr(); - uint add_length; THD *thd= current_thd; /* It's ok to use item->result.length() as the fourth argument as this is never used to limit the length of the data. Cut is done with the third argument. */ - add_length= cs->cset->well_formed_len(cs, - ptr + old_length, - ptr + max_length, - result->length(), - &well_formed_error); + uint add_length= Well_formed_prefix(cs, + ptr + old_length, + ptr + max_length, + result->length()).length(); result->length(old_length + add_length); item->warning_for_row= TRUE; push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 41dc96717fe..5e0ae028d88 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2468,13 +2468,9 @@ String *Item_char_typecast::val_str(String *str) if (!charset_conversion) { // Try to reuse the original string (if well formed). - MY_STRCOPY_STATUS status; - cs->cset->well_formed_char_length(cs, res->ptr(), res->end(), - cast_length, &status); - if (!status.m_well_formed_error_pos) - { - res= reuse(res, status.m_source_end_pos - res->ptr()); - } + Well_formed_prefix prefix(cs, res->ptr(), res->end(), cast_length); + if (!prefix.well_formed_error_pos()) + res= reuse(res, prefix.length()); goto end; } // Character set conversion, or bad bytes were found. diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ab6a8032348..2ae252c2232 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -12030,14 +12030,9 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, mostly for backward compatibility (to truncate long usernames, as old 5.1 did) */ - { - CHARSET_INFO *cs= system_charset_info; - int err; - - user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len, - username_char_length, &err); - user[user_len]= '\0'; - } + user_len= Well_formed_prefix(system_charset_info, user, user_len, + username_char_length).length(); + user[user_len]= '\0'; Security_context *sctx= thd->security_ctx; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f4ac33d77fa..ddb5e2744cb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -9614,11 +9614,8 @@ bool check_string_char_length(LEX_STRING *str, uint err_msg, uint max_char_length, CHARSET_INFO *cs, bool no_error) { - int well_formed_error; - uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length, - max_char_length, &well_formed_error); - - if (!well_formed_error && str->length == res) + Well_formed_prefix prefix(cs, str->str, str->length, max_char_length); + if (!prefix.well_formed_error_pos() && str->length == prefix.length()) return FALSE; if (!no_error) diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 4bb9f835211..49442260704 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -1018,10 +1018,10 @@ String_copier::well_formed_copy(CHARSET_INFO *to_cs, { m_cannot_convert_error_pos= NULL; return to_cs->cset->copy_fix(to_cs, to, to_length, from, from_length, - nchars, &m_native_copy_status); + nchars, this); } return my_convert_fix(to_cs, to, to_length, from_cs, from, from_length, - nchars, this); + nchars, this, this); } diff --git a/sql/sql_string.h b/sql/sql_string.h index cc7cff09d77..e51d089709e 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -44,13 +44,48 @@ inline uint32 copy_and_convert(char *to, uint32 to_length, } -class String_copier: private MY_STRCONV_STATUS +class String_copy_status: protected MY_STRCOPY_STATUS { public: const char *source_end_pos() const - { return m_native_copy_status.m_source_end_pos; } + { return m_source_end_pos; } const char *well_formed_error_pos() const - { return m_native_copy_status.m_well_formed_error_pos; } + { return m_well_formed_error_pos; } +}; + + +class Well_formed_prefix_status: public String_copy_status +{ +public: + Well_formed_prefix_status(CHARSET_INFO *cs, + const char *str, const char *end, size_t nchars) + { cs->cset->well_formed_char_length(cs, str, end, nchars, this); } +}; + + +class Well_formed_prefix: public Well_formed_prefix_status +{ + const char *m_str; // The beginning of the string +public: + Well_formed_prefix(CHARSET_INFO *cs, const char *str, const char *end, + size_t nchars) + :Well_formed_prefix_status(cs, str, end, nchars), m_str(str) + { } + Well_formed_prefix(CHARSET_INFO *cs, const char *str, size_t length, + size_t nchars) + :Well_formed_prefix_status(cs, str, str + length, nchars), m_str(str) + { } + Well_formed_prefix(CHARSET_INFO *cs, const char *str, size_t length) + :Well_formed_prefix_status(cs, str, str + length, length), m_str(str) + { } + size_t length() const { return m_source_end_pos - m_str; } +}; + + +class String_copier: public String_copy_status, + protected MY_STRCONV_STATUS +{ +public: const char *cannot_convert_error_pos() const { return m_cannot_convert_error_pos; } const char *most_important_error_pos() const @@ -67,7 +102,7 @@ public: uint nchars) { return my_convert_fix(dstcs, dst, dst_length, - srccs, src, src_length, nchars, this); + srccs, src, src_length, nchars, this, this); } /* Copy a string. Fix bad bytes/characters to '?'. @@ -606,9 +641,7 @@ public: } uint well_formed_length() const { - int dummy_error; - return charset()->cset->well_formed_len(charset(), ptr(), ptr() + length(), - length(), &dummy_error); + return (uint) Well_formed_prefix(charset(), ptr(), length()).length(); } bool is_ascii() const { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6b2dbca75a9..b8810311b51 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -14371,10 +14371,7 @@ IDENT_sys: if (thd->charset_is_system_charset) { CHARSET_INFO *cs= system_charset_info; - int dummy_error; - uint wlen= cs->cset->well_formed_len(cs, $1.str, - $1.str+$1.length, - $1.length, &dummy_error); + uint wlen= Well_formed_prefix(cs, $1.str, $1.length).length(); if (wlen < $1.length) { ErrConvString err($1.str, $1.length, &my_charset_bin); diff --git a/storage/innobase/api/api0api.cc b/storage/innobase/api/api0api.cc index 1b99dcf1564..403d6e4a28d 100644 --- a/storage/innobase/api/api0api.cc +++ b/storage/innobase/api/api0api.cc @@ -2172,7 +2172,7 @@ ib_col_set_value( if (len > 0 && cs->mbmaxlen > 1) { true_len = (ulint) - cs->cset->well_formed_len( + my_well_formed_length( cs, (const char*)src, (const char*)src + len, diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 1e74154f26d..604beec6f78 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2404,7 +2404,7 @@ innobase_check_identifier_length( CHARSET_INFO *cs = system_charset_info; DBUG_ENTER("innobase_check_identifier_length"); - size_t len = cs->cset->well_formed_len( + size_t len = my_well_formed_length( cs, id, id + strlen(id), NAME_CHAR_LEN, &well_formed_error); @@ -7962,7 +7962,7 @@ wsrep_store_key_val_for_row( the true length of the key */ if (len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) cs->cset->well_formed_len(cs, + true_len = (ulint) my_well_formed_length(cs, (const char *) data, (const char *) data + len, (uint) (key_len / @@ -8048,7 +8048,7 @@ wsrep_store_key_val_for_row( the true length of the key */ if (blob_len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) cs->cset->well_formed_len(cs, + true_len = (ulint) my_well_formed_length(cs, (const char *) blob_data, (const char *) blob_data + blob_len, @@ -8137,7 +8137,7 @@ wsrep_store_key_val_for_row( if (key_len > 0 && cs->mbmaxlen > 1) { true_len = (ulint) - cs->cset->well_formed_len(cs, + my_well_formed_length(cs, (const char *)src_start, (const char *)src_start + key_len, diff --git a/storage/perfschema/table_events_statements.cc b/storage/perfschema/table_events_statements.cc index 0d0ea02974d..fdc63034be5 100644 --- a/storage/perfschema/table_events_statements.cc +++ b/storage/perfschema/table_events_statements.cc @@ -253,12 +253,9 @@ void table_events_statements_common::make_row_part_1(PFS_events_statements *stat { if (cs->mbmaxlen > 1) { - int well_formed_error; - valid_length= cs->cset->well_formed_len(cs, - statement->m_sqltext, - statement->m_sqltext + valid_length, - valid_length, - &well_formed_error); + valid_length= Well_formed_prefix(cs, + statement->m_sqltext, + valid_length).length(); } } diff --git a/storage/xtradb/api/api0api.cc b/storage/xtradb/api/api0api.cc index 739ea9f7572..a6dfad40150 100644 --- a/storage/xtradb/api/api0api.cc +++ b/storage/xtradb/api/api0api.cc @@ -2334,7 +2334,7 @@ ib_col_set_value( if (len > 0 && cs->mbmaxlen > 1) { true_len = (ulint) - cs->cset->well_formed_len( + my_well_formed_length( cs, (const char*)src, (const char*)src + len, diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index ca1eb76cbda..aa54a5aff5d 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -2424,7 +2424,7 @@ innobase_check_identifier_length( CHARSET_INFO *cs = system_charset_info; DBUG_ENTER("innobase_check_identifier_length"); - size_t len = cs->cset->well_formed_len( + size_t len = my_well_formed_length( cs, id, id + strlen(id), NAME_CHAR_LEN, &well_formed_error); @@ -7434,7 +7434,7 @@ wsrep_store_key_val_for_row( the true length of the key */ if (len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) cs->cset->well_formed_len(cs, + true_len = (ulint) my_well_formed_length(cs, (const char *) data, (const char *) data + len, (uint) (key_len / @@ -7521,7 +7521,7 @@ wsrep_store_key_val_for_row( the true length of the key */ if (blob_len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) cs->cset->well_formed_len(cs, + true_len = (ulint) my_well_formed_length(cs, (const char *) blob_data, (const char *) blob_data + blob_len, @@ -7610,7 +7610,7 @@ wsrep_store_key_val_for_row( if (key_len > 0 && cs->mbmaxlen > 1) { true_len = (ulint) - cs->cset->well_formed_len(cs, + my_well_formed_length(cs, (const char *)src_start, (const char *)src_start + key_len, @@ -7745,7 +7745,7 @@ ha_innobase::store_key_val_for_row( the true length of the key */ if (len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) cs->cset->well_formed_len(cs, + true_len = (ulint) my_well_formed_length(cs, (const char*) data, (const char*) data + len, (uint) (key_len / cs->mbmaxlen), @@ -7816,7 +7816,7 @@ ha_innobase::store_key_val_for_row( the true length of the key */ if (blob_len > 0 && cs->mbmaxlen > 1) { - true_len = (ulint) cs->cset->well_formed_len(cs, + true_len = (ulint) my_well_formed_length(cs, (const char*) blob_data, (const char*) blob_data + blob_len, @@ -7888,7 +7888,7 @@ ha_innobase::store_key_val_for_row( if (key_len > 0 && cs->mbmaxlen > 1) { true_len = (ulint) - cs->cset->well_formed_len(cs, + my_well_formed_length(cs, (const char*) src_start, (const char*) src_start + key_len, diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index dd66da224ba..22cb83a8806 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6775,7 +6775,6 @@ static MY_CHARSET_HANDLER my_charset_big5_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_big5, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_big5, /* mb_wc */ diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 5655edd6063..0bbbd282530 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -535,7 +535,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_8bit, my_charpos_8bit, - my_well_formed_len_8bit, my_lengthsp_binary, my_numcells_8bit, my_mb_wc_bin, diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 83f8d40c480..46226f92ba7 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -34731,7 +34731,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_cp932, my_lengthsp_8bit, my_numcells_cp932, my_mb_wc_cp932, /* mb_wc */ diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index e2a50da2ed4..1af182db9aa 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -10021,7 +10021,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_euckr, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_euc_kr, /* mb_wc */ diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index 47d03bd5d99..f70dc69bafa 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -67559,7 +67559,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_eucjpms, my_lengthsp_8bit, my_numcells_eucjpms, my_mb_wc_eucjpms, /* mb_wc */ diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index 832c6c7f038..42235a54e69 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -6426,7 +6426,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_gb2312, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_gb2312, /* mb_wc */ diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index d24b77950c2..ae454591d08 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -10708,7 +10708,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_gbk, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_gbk, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index 6f71c7a0c76..12871c2b7c7 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -398,7 +398,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_8bit, my_charpos_8bit, - my_well_formed_len_8bit, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_latin1, diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index d78e758010d..6438273bc4b 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -401,28 +401,6 @@ size_t my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)), } -size_t my_well_formed_len_mb(CHARSET_INFO *cs, const char *b, const char *e, - size_t pos, int *error) -{ - const char *b_start= b; - *error= 0; - while (pos) - { - my_wc_t wc; - int mb_len; - - if ((mb_len= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <= 0) - { - *error= b < e ? 1 : 0; - break; - } - b+= mb_len; - pos--; - } - return (size_t) (b - b_start); -} - - /* Append a badly formed piece of string. Bad bytes are fixed to '?'. diff --git a/strings/ctype-mb.ic b/strings/ctype-mb.ic index 2df9c9d5e49..4806331c737 100644 --- a/strings/ctype-mb.ic +++ b/strings/ctype-mb.ic @@ -30,7 +30,6 @@ #ifdef DEFINE_ASIAN_ROUTINES -#define DEFINE_WELL_FORMED_LEN #define DEFINE_WELL_FORMED_CHAR_LENGTH #define DEFINE_CHARLEN #define DEFINE_NATIVE_TO_MB_VARLEN @@ -96,73 +95,7 @@ MY_FUNCTION_NAME(charlen)(CHARSET_INFO *cs __attribute__((unused)), /* Wrong byte sequence */ return MY_CS_ILSEQ; } -#endif /* DEFINE_WELL_FORMED_LEN */ - - -#ifdef DEFINE_WELL_FORMED_LEN -/** - Returns well formed length of a character string with - variable character length for character sets with: - - mbminlen == 1 - - mbmaxlen == 2, 3, or 4 -*/ -static size_t -MY_FUNCTION_NAME(well_formed_len)(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, - size_t nchars, int *error) -{ - const char *b0= b; - - DBUG_ASSERT(cs->mbminlen == 1); - DBUG_ASSERT(cs->mbmaxlen <= 4); - - for (*error= 0 ; b < e && nchars-- ; ) - { - if ((uchar) b[0] < 128) - { - b++; /* Single byte ASCII character */ - continue; - } - - if (b + 2 <= e && IS_MB2_CHAR(b[0], b[1])) - { - b+= 2; /* Double byte character */ - continue; - } - -#ifdef IS_MB3_CHAR - if (b + 3 <= e && IS_MB3_CHAR(b[0], b[1], b[2])) - { - b+= 3; /* Three-byte character */ - continue; - } -#endif - -#ifdef IS_MB4_CHAR - if (b + 4 <= e && IS_MB4_CHAR(b[0], b[1], b[2], b[3])) - { - b+= 4; /* Four-byte character */ - continue; - } -#endif - -#ifdef IS_8BIT_CHAR - if (IS_8BIT_CHAR(b[0])) - { - b++; /* Single byte non-ASCII character, e.g. half width kana in sjis */ - continue; - } -#endif - - /* Wrong byte sequence */ - *error= 1; - break; - } - return b - b0; -} - -#endif /* DEFINE_WELL_FORMED_LEN */ - +#endif /* DEFINE_CHARLEN */ #ifdef DEFINE_WELL_FORMED_CHAR_LENGTH diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index b142aab18a6..99f26731851 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1143,16 +1143,6 @@ size_t my_charpos_8bit(CHARSET_INFO *cs __attribute__((unused)), } -size_t my_well_formed_len_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *start, const char *end, - size_t nchars, int *error) -{ - size_t nbytes= (size_t) (end-start); - *error= 0; - return MY_MIN(nbytes, nchars); -} - - size_t my_well_formed_char_length_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *start, const char *end, @@ -2064,7 +2054,6 @@ MY_CHARSET_HANDLER my_charset_8bit_handler= my_cset_init_8bit, my_numchars_8bit, my_charpos_8bit, - my_well_formed_len_8bit, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_8bit, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 94fd69c79c0..36aab369c4a 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -34110,7 +34110,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_sjis, my_lengthsp_8bit, my_numcells_sjis, my_mb_wc_sjis, /* mb_wc */ diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 72a33036085..4dbb66d89c5 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -880,7 +880,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_8bit, my_charpos_8bit, - my_well_formed_len_8bit, my_lengthsp_8bit, my_numcells_8bit, my_mb_wc_tis620, /* mb_wc */ diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 9d8353103f0..e154545e4f6 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1490,27 +1490,6 @@ my_charpos_utf16(CHARSET_INFO *cs, } -static size_t -my_well_formed_len_utf16(CHARSET_INFO *cs, - const char *b, const char *e, - size_t nchars, int *error) -{ - const char *b0= b; - uint charlen; - *error= 0; - - for ( ; nchars; b+= charlen, nchars--) - { - if (!(charlen= my_ismbchar(cs, b, e))) - { - *error= b < e ? 1 : 0; - break; - } - } - return (size_t) (b - b0); -} - - static int my_wildcmp_utf16_ci(CHARSET_INFO *cs, const char *str,const char *str_end, @@ -1629,7 +1608,6 @@ MY_CHARSET_HANDLER my_charset_utf16_handler= NULL, /* init */ my_numchars_utf16, my_charpos_utf16, - my_well_formed_len_utf16, my_lengthsp_mb2, my_numcells_mb, my_utf16_uni, /* mb_wc */ @@ -1963,7 +1941,6 @@ static MY_CHARSET_HANDLER my_charset_utf16le_handler= NULL, /* init */ my_numchars_utf16, my_charpos_utf16, - my_well_formed_len_utf16, my_lengthsp_utf16le, my_numcells_mb, my_utf16le_uni, /* mb_wc */ @@ -2636,34 +2613,6 @@ my_charpos_utf32(CHARSET_INFO *cs __attribute__((unused)), } -static size_t -my_well_formed_len_utf32(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, - size_t nchars, int *error) -{ - /* Ensure string length is divisible by 4 */ - const char *b0= b; - size_t length= e - b; - DBUG_ASSERT((length % 4) == 0); - *error= 0; - nchars*= 4; - if (length > nchars) - { - length= nchars; - e= b + nchars; - } - for (; b < e; b+= 4) - { - if (!IS_UTF32_MBHEAD4(b[0], b[1])) - { - *error= 1; - return b - b0; - } - } - return length; -} - - static void my_fill_utf32(CHARSET_INFO *cs, char *s, size_t slen, int fill) @@ -2809,7 +2758,6 @@ MY_CHARSET_HANDLER my_charset_utf32_handler= NULL, /* init */ my_numchars_utf32, my_charpos_utf32, - my_well_formed_len_utf32, my_lengthsp_utf32, my_numcells_mb, my_utf32_uni, @@ -3248,19 +3196,6 @@ size_t my_charpos_ucs2(CHARSET_INFO *cs __attribute__((unused)), } -static -size_t my_well_formed_len_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *b, const char *e, - size_t nchars, int *error) -{ - /* Ensure string length is dividable with 2 */ - size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1; - *error= 0; - nchars*= 2; - return MY_MIN(nbytes, nchars); -} - - static size_t my_well_formed_char_length_ucs2(CHARSET_INFO *cs __attribute__((unused)), const char *b, const char *e, @@ -3403,7 +3338,6 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler= NULL, /* init */ my_numchars_ucs2, my_charpos_ucs2, - my_well_formed_len_ucs2, my_lengthsp_mb2, my_numcells_mb, my_ucs2_uni, /* mb_wc */ diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 8c08e906284..4c553d15526 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -67303,7 +67303,6 @@ static MY_CHARSET_HANDLER my_charset_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_ujis, my_lengthsp_8bit, my_numcells_eucjp, my_mb_wc_euc_jp, /* mb_wc */ diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 39d3521baa4..ac262b81eb1 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -5421,27 +5421,6 @@ int my_charlen_utf8(CHARSET_INFO *cs __attribute__((unused)), return MY_CS_ILSEQ; } -static size_t -my_well_formed_len_utf8(CHARSET_INFO *cs, const char *b, const char *e, - size_t pos, int *error) -{ - const char *b_start= b; - *error= 0; - while (pos) - { - int mb_len; - - if ((mb_len= my_charlen_utf8(cs, (uchar*) b, (uchar*) e)) <= 0) - { - *error= b < e ? 1 : 0; - break; - } - b+= mb_len; - pos--; - } - return (size_t) (b - b_start); -} - #define MY_FUNCTION_NAME(x) my_ ## x ## _utf8 #define CHARLEN(cs,str,end) my_charlen_utf8(cs,str,end) @@ -5656,7 +5635,6 @@ MY_CHARSET_HANDLER my_charset_utf8_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_utf8, my_lengthsp_8bit, my_numcells_mb, my_utf8_uni, @@ -7276,7 +7254,6 @@ static MY_CHARSET_HANDLER my_charset_filename_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_mb, my_lengthsp_8bit, my_numcells_mb, my_mb_wc_filename, @@ -7885,29 +7862,6 @@ my_charlen_utf8mb4(CHARSET_INFO *cs __attribute__((unused)), } -static -size_t my_well_formed_len_utf8mb4(CHARSET_INFO *cs, - const char *b, const char *e, - size_t pos, int *error) -{ - const char *b_start= b; - *error= 0; - while (pos) - { - int mb_len; - - if ((mb_len= my_charlen_utf8mb4(cs, (uchar*) b, (uchar*) e)) <= 0) - { - *error= b < e ? 1 : 0; - break; - } - b+= mb_len; - pos--; - } - return (size_t) (b - b_start); -} - - #define MY_FUNCTION_NAME(x) my_ ## x ## _utf8mb4 #define CHARLEN(cs,str,end) my_charlen_utf8mb4(cs,str,end) #define DEFINE_WELL_FORMED_CHAR_LENGTH_USING_CHARLEN @@ -8033,7 +7987,6 @@ MY_CHARSET_HANDLER my_charset_utf8mb4_handler= NULL, /* init */ my_numchars_mb, my_charpos_mb, - my_well_formed_len_utf8mb4, my_lengthsp_8bit, my_numcells_mb, my_mb_wc_utf8mb4, diff --git a/strings/ctype.c b/strings/ctype.c index 7d9789e48e2..7348cbfa1f9 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -1138,7 +1138,9 @@ my_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs, size_t my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, CHARSET_INFO *from_cs, const char *from, size_t from_length, - size_t nchars, MY_STRCONV_STATUS *status) + size_t nchars, + MY_STRCOPY_STATUS *copy_status, + MY_STRCONV_STATUS *conv_status) { int cnvres; my_wc_t wc; @@ -1151,8 +1153,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, DBUG_ASSERT(to_cs != &my_charset_bin); DBUG_ASSERT(from_cs != &my_charset_bin); - status->m_native_copy_status.m_well_formed_error_pos= NULL; - status->m_cannot_convert_error_pos= NULL; + copy_status->m_well_formed_error_pos= NULL; + conv_status->m_cannot_convert_error_pos= NULL; for ( ; nchars; nchars--) { @@ -1161,8 +1163,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, from+= cnvres; else if (cnvres == MY_CS_ILSEQ) { - if (!status->m_native_copy_status.m_well_formed_error_pos) - status->m_native_copy_status.m_well_formed_error_pos= from; + if (!copy_status->m_well_formed_error_pos) + copy_status->m_well_formed_error_pos= from; from++; wc= '?'; } @@ -1172,8 +1174,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, A correct multibyte sequence detected But it doesn't have Unicode mapping. */ - if (!status->m_cannot_convert_error_pos) - status->m_cannot_convert_error_pos= from; + if (!conv_status->m_cannot_convert_error_pos) + conv_status->m_cannot_convert_error_pos= from; from+= (-cnvres); wc= '?'; } @@ -1182,8 +1184,8 @@ my_convert_fix(CHARSET_INFO *to_cs, char *to, size_t to_length, if ((uchar *) from >= from_end) break; // End of line // Incomplete byte sequence - if (!status->m_native_copy_status.m_well_formed_error_pos) - status->m_native_copy_status.m_well_formed_error_pos= from; + if (!copy_status->m_well_formed_error_pos) + copy_status->m_well_formed_error_pos= from; from++; wc= '?'; } @@ -1192,8 +1194,8 @@ outp: to+= cnvres; else if (cnvres == MY_CS_ILUNI && wc != '?') { - if (!status->m_cannot_convert_error_pos) - status->m_cannot_convert_error_pos= from_prev; + if (!conv_status->m_cannot_convert_error_pos) + conv_status->m_cannot_convert_error_pos= from_prev; wc= '?'; goto outp; } @@ -1203,6 +1205,6 @@ outp: break; } } - status->m_native_copy_status.m_source_end_pos= from; + copy_status->m_source_end_pos= from; return to - to_start; } diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 846803d9b24..ad270bd9b64 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -205,8 +205,7 @@ static char *process_str_arg(CHARSET_INFO *cs, char *to, const char *end, plen= strnlen(par, width); if (left_len <= plen) plen = left_len - 1; - plen= cs->cset->well_formed_len(cs, par, par + plen, - width, &well_formed_error); + plen= my_well_formed_length(cs, par, par + plen, width, &well_formed_error); if (print_type & ESCAPED_ARG) to= backtick_string(cs, to, end, par, plen, '`'); else diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c index 22b50fc1659..fadcb4c768d 100644 --- a/unittest/strings/strings-t.c +++ b/unittest/strings/strings-t.c @@ -31,12 +31,12 @@ test_like_range_for_charset(CHARSET_INFO *cs, const char *src, size_t src_len) cs->coll->like_range(cs, src, src_len, '\\', '_', '%', sizeof(min_str), min_str, max_str, &min_len, &max_len); diag("min_len=%d\tmax_len=%d\t%s", (int) min_len, (int) max_len, cs->name); - min_well_formed_len= cs->cset->well_formed_len(cs, - min_str, min_str + min_len, - 10000, &error); - max_well_formed_len= cs->cset->well_formed_len(cs, - max_str, max_str + max_len, - 10000, &error); + min_well_formed_len= my_well_formed_length(cs, + min_str, min_str + min_len, + 10000, &error); + max_well_formed_len= my_well_formed_length(cs, + max_str, max_str + max_len, + 10000, &error); if (min_len != min_well_formed_len) diag("Bad min_str: min_well_formed_len=%d min_str[%d]=0x%02X", (int) min_well_formed_len, (int) min_well_formed_len, |