From 7b99b8a57b778d9b32915add7dca2772f27bf360 Mon Sep 17 00:00:00 2001 From: skidder Date: Mon, 3 Nov 2003 17:14:45 +0000 Subject: [PATCH] Basic INTL cleanup. - Rework (mostly undo) John's changes - Some function type safety - Make INTL OO layer very thin (this should slightly improve performance) --- src/common/classes/array.h | 1 + src/dsql/make.cpp | 3 +- src/dsql/movd.cpp | 2 +- src/gpre/movg.cpp | 8 +- src/include/fb_types.h | 3 +- src/jrd/blk.h | 3 - src/jrd/btr.h | 1 - src/jrd/constants.h | 3 + src/jrd/cvt.cpp | 168 ++-- src/jrd/cvt2.cpp | 57 +- src/jrd/cvt2_proto.h | 8 +- src/jrd/cvt_proto.h | 26 +- src/jrd/dyn.h | 1 - src/jrd/evl.cpp | 112 ++- src/jrd/evl_like.cpp | 15 +- src/jrd/evl_proto.h | 30 +- src/jrd/filters.cpp | 16 +- src/jrd/intl.cpp | 1757 ++++++++++------------------------ src/jrd/intl_builtin.cpp | 1824 ++++++++++++++---------------------- src/jrd/intl_classes.h | 537 +++++------ src/jrd/intl_proto.h | 33 +- src/jrd/intlobj.h | 33 +- src/jrd/mov.cpp | 35 +- src/jrd/opt.cpp | 3 +- src/jrd/par.cpp | 2 +- src/jrd/quad.cpp | 24 +- src/jrd/quad_proto.h | 10 +- src/remote/interface.cpp | 2 +- 28 files changed, 1714 insertions(+), 3003 deletions(-) diff --git a/src/common/classes/array.h b/src/common/classes/array.h index 1c0da17859..11d08dc1f7 100644 --- a/src/common/classes/array.h +++ b/src/common/classes/array.h @@ -139,6 +139,7 @@ template { public: SortedArray(MemoryPool* p, int s) : Array(p, s) {} + SortedArray(MemoryPool* p) : Array(p) {} bool find(const Key& item, int& pos) { int highBound = count, lowBound = 0; while (highBound > lowBound) { diff --git a/src/dsql/make.cpp b/src/dsql/make.cpp index 984174334b..42e829dd1f 100644 --- a/src/dsql/make.cpp +++ b/src/dsql/make.cpp @@ -195,8 +195,7 @@ dsql_nod* MAKE_constant(str* constant, dsql_constant_type numeric_flag) /* Now invoke the string_to_date/time/timestamp routines */ - CVT_move(&tmp, &node->nod_desc, - reinterpret_cast (ERRD_post)); + CVT_move(&tmp, &node->nod_desc, ERRD_post); break; } diff --git a/src/dsql/movd.cpp b/src/dsql/movd.cpp index c4bb9d83ae..c9fdb668f2 100644 --- a/src/dsql/movd.cpp +++ b/src/dsql/movd.cpp @@ -52,7 +52,7 @@ static void post_error(ISC_STATUS, ...); void MOVD_move(const dsc* from, dsc* to) { - CVT_move(from, to, (FPTR_VOID) post_error); + CVT_move(from, to, post_error); } diff --git a/src/gpre/movg.cpp b/src/gpre/movg.cpp index bda1c5fafc..015e3e916b 100644 --- a/src/gpre/movg.cpp +++ b/src/gpre/movg.cpp @@ -25,7 +25,7 @@ // //____________________________________________________________ // -// $Id: movg.cpp,v 1.4 2003-10-05 06:54:37 robocop Exp $ +// $Id: movg.cpp,v 1.5 2003-11-03 17:14:41 skidder Exp $ // #include "firebird.h" @@ -46,7 +46,7 @@ #include "../jrd/cvt_proto.h" #include "../jrd/thd_proto.h" -static void post_error(void); +static void post_error(ISC_STATUS, ...); //____________________________________________________________ @@ -57,7 +57,7 @@ static void post_error(void); void MOVG_move(const dsc* from, dsc* to) { - CVT_move(from, to, (FPTR_VOID) post_error); + CVT_move(from, to, post_error); } @@ -66,7 +66,7 @@ void MOVG_move(const dsc* from, dsc* to) // A conversion error occurred. Complain. // -static void post_error(void) +static void post_error(ISC_STATUS, ...) { CPR_error("conversion error: illegal string literal"); diff --git a/src/include/fb_types.h b/src/include/fb_types.h index a371d29242..b9629efd49 100644 --- a/src/include/fb_types.h +++ b/src/include/fb_types.h @@ -27,7 +27,7 @@ * Mark O'Donohue * * - * $Id: fb_types.h,v 1.28 2003-10-20 10:33:43 robocop Exp $ + * $Id: fb_types.h,v 1.29 2003-11-03 17:14:42 skidder Exp $ * * 2002.02.15 Sean Leyne - Code Cleanup, removed obsolete "OS/2" port * @@ -133,6 +133,7 @@ typedef void (*FPTR_VOID_PTR) (void*); typedef int (*FPTR_INT) (); typedef int (*FPTR_INT_VOID_PTR) (void*); typedef void (*FPTR_PRINT_CALLBACK) (void*, SSHORT, const char*); +typedef void (*FPTR_STATUS) (ISC_STATUS, ...); typedef ULONG RCRD_OFFSET; typedef USHORT FLD_LENGTH; typedef int (*lock_ast_t)(void*); diff --git a/src/jrd/blk.h b/src/jrd/blk.h index 49b53ffaa9..27dabb3092 100644 --- a/src/jrd/blk.h +++ b/src/jrd/blk.h @@ -79,9 +79,6 @@ BLKDEF(type_map, map, 0) BLKDEF(type_log, log, 0) BLKDEF(type_dls, dls, 1) BLKDEF(type_ail, logfiles, 1) /* wal file */ -BLKDEF(type_texttype_alloc_id, texttype, 0) /* Intl Text Impl Object */ -BLKDEF(type_charset_alloc_id, charset, 0) /* Intl Charset definition */ -BLKDEF(type_csconvert_alloc_id, csconvert, 0) /* Intl character set converter */ BLKDEF(type_prc, jrd_prc, 1) /* procedure block */ BLKDEF(type_prm, prm, 1) /* parameter block */ BLKDEF(type_sav, sav, 0) /* save points */ diff --git a/src/jrd/btr.h b/src/jrd/btr.h index feaa0bc87b..95eb5557b3 100644 --- a/src/jrd/btr.h +++ b/src/jrd/btr.h @@ -37,7 +37,6 @@ /* 64 turns out not to be enough indexes */ /* #define MAX_IDX 64 */ /* that should be plenty of indexes */ -#define MAX_KEY 256 /* 256 isn't big enough for a key either */ enum idx_null_state { idx_nulls_none, diff --git a/src/jrd/constants.h b/src/jrd/constants.h index 9b1ddad0d0..2e6dc2d5b7 100644 --- a/src/jrd/constants.h +++ b/src/jrd/constants.h @@ -96,5 +96,8 @@ enum frb_sysflag { #define MAX_INDEX_SEGMENTS 16 +// Maximum index key length +#define MAX_KEY 256 + #endif /* JRD_CONSTANTS_H */ diff --git a/src/jrd/cvt.cpp b/src/jrd/cvt.cpp index 0ffae21956..1d306d510c 100644 --- a/src/jrd/cvt.cpp +++ b/src/jrd/cvt.cpp @@ -175,13 +175,13 @@ static TEXT* cvt_failures_ptr = NULL; static TEXT* error_string(const char*, SSHORT); #endif -static void conversion_error(const dsc*, FPTR_VOID); -static void datetime_to_text(const dsc*, dsc*, FPTR_VOID); -static SSHORT decompose(const char*, USHORT, SSHORT, SLONG*, FPTR_VOID); -static void float_to_text(const dsc*, dsc*, FPTR_VOID); -static void integer_to_text(const dsc*, dsc*, FPTR_VOID); +static void conversion_error(const dsc*, FPTR_STATUS); +static void datetime_to_text(const dsc*, dsc*, FPTR_STATUS); +static SSHORT decompose(const char*, USHORT, SSHORT, SLONG*, FPTR_STATUS); +static void float_to_text(const dsc*, dsc*, FPTR_STATUS); +static void integer_to_text(const dsc*, dsc*, FPTR_STATUS); static void string_to_datetime(const dsc*, GDS_TIMESTAMP*, EXPECT_DATETIME, - FPTR_VOID); + FPTR_STATUS); static double power_of_ten(const int); #ifndef NATIVE_QUAD @@ -219,7 +219,7 @@ typedef void (*pfn_cvt_private_cludge) (int, int); typedef void (*pfn_cvt_private_cludge2) (int, int, ...); -double CVT_date_to_double(const dsc* desc, FPTR_VOID err) +double CVT_date_to_double(const dsc* desc, FPTR_STATUS err) { /************************************** * @@ -281,7 +281,7 @@ to FPU register being 80 bits long and double being 64 bits long */ } -void CVT_double_to_date(double real, SLONG fixed[2], FPTR_VOID err) +void CVT_double_to_date(double real, SLONG fixed[2], FPTR_STATUS err) { /************************************** * @@ -303,7 +303,7 @@ void CVT_double_to_date(double real, SLONG fixed[2], FPTR_VOID err) } -double CVT_get_double(const dsc* desc, FPTR_VOID err) +double CVT_get_double(const dsc* desc, FPTR_STATUS err) { /************************************** * @@ -430,8 +430,7 @@ double CVT_get_double(const dsc* desc, FPTR_VOID err) later in this routine. */ if (exp >= SHORT_LIMIT) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } else if (*p == '-' && !digit_seen && !sign) sign = -1; @@ -454,7 +453,7 @@ double CVT_get_double(const dsc* desc, FPTR_VOID err) the user know... */ if (ABSOLUT(scale) > DBL_MAX_10_EXP) - reinterpret_cast(err)(gds_arith_except, 0); + (*err)(gds_arith_except, 0); /* Repeated division is a good way to mung the least significant bits @@ -481,7 +480,7 @@ double CVT_get_double(const dsc* desc, FPTR_VOID err) break; default: - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err) (gds_badblk, 0); /* internal error */ break; } @@ -495,7 +494,7 @@ double CVT_get_double(const dsc* desc, FPTR_VOID err) the user know... */ if (ABSOLUT(scale) > DBL_MAX_10_EXP) - reinterpret_cast(err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); if (scale > 0) value *= power_of_ten(scale); @@ -506,7 +505,7 @@ double CVT_get_double(const dsc* desc, FPTR_VOID err) } -SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) +SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_STATUS err) { /************************************** * @@ -567,14 +566,12 @@ SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) else if (scale < 0) do { if ((val64 > INT64_LIMIT) || (val64 < -INT64_LIMIT)) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); val64 *= 10; } while (++scale); if ((val64 > LONG_MAX_int64) || (val64 < LONG_MIN_int64)) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); return (SLONG) val64; case dtype_quad: @@ -582,8 +579,7 @@ SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) high = ((SLONG *) p)[HIGH_WORD]; if ((value >= 0 && !high) || (value < 0 && high == -1)) break; - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_arith_except, - 0); + (*err) (gds_arith_except, 0); break; case dtype_real: @@ -620,14 +616,12 @@ SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) if (d < (double) LONG_MIN_real) { if (d > (double) LONG_MIN_real - 1.) return LONG_MIN; - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } if (d > (double) LONG_MAX_real) { if (d < (double) LONG_MAX_real + 1.) return LONG_MAX_int; - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } return (SLONG) d; @@ -649,7 +643,7 @@ SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) break; default: - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err)(gds_badblk, 0); /* internal error */ break; } @@ -682,8 +676,7 @@ SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) else if (scale < 0) do { if (value > LONG_LIMIT || value < -LONG_LIMIT) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); value *= 10; } while (++scale); @@ -693,7 +686,7 @@ SLONG CVT_get_long(const dsc* desc, SSHORT scale, FPTR_VOID err) UCHAR CVT_get_numeric(const UCHAR* string, const USHORT length, - SSHORT* scale, double* ptr, FPTR_VOID err) + SSHORT* scale, double* ptr, FPTR_STATUS err) { /************************************** * @@ -806,7 +799,7 @@ UCHAR CVT_get_numeric(const UCHAR* string, } -SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, FPTR_VOID err) +SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, FPTR_STATUS err) { /************************************** * @@ -891,8 +884,7 @@ SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, FPTR_VOID err) return QUAD_MIN_int; else if (d < (double) QUAD_MAX_real + 1.) return QUAD_MAX_int; - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err)(gds_arith_except, 0); } return QUAD_FROM_DOUBLE(d, err); @@ -914,7 +906,7 @@ SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, FPTR_VOID err) break; default: - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err)(gds_badblk, 0); /* internal error */ break; } @@ -924,7 +916,7 @@ SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, FPTR_VOID err) return value; #ifndef NATIVE_QUAD - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err)(gds_badblk, 0); /* internal error */ #else if (scale > 0) { if (desc->dsc_dtype == dtype_short || @@ -963,7 +955,7 @@ SQUAD CVT_get_quad(const dsc* desc, SSHORT scale, FPTR_VOID err) } -SINT64 CVT_get_int64(const dsc* desc, SSHORT scale, FPTR_VOID err) +SINT64 CVT_get_int64(const dsc* desc, SSHORT scale, FPTR_STATUS err) { /************************************** * @@ -1045,8 +1037,7 @@ SINT64 CVT_get_int64(const dsc* desc, SSHORT scale, FPTR_VOID err) double, and thus will have no effect on the sum. */ if (d < (double) QUAD_MIN_real || (double) QUAD_MAX_real < d) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); return (SINT64) d; @@ -1068,7 +1059,7 @@ SINT64 CVT_get_int64(const dsc* desc, SSHORT scale, FPTR_VOID err) break; default: - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err) (gds_badblk, 0); /* internal error */ break; } @@ -1102,8 +1093,7 @@ SINT64 CVT_get_int64(const dsc* desc, SSHORT scale, FPTR_VOID err) else if (scale < 0) do { if (value > INT64_LIMIT || value < -INT64_LIMIT) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); value *= 10; } while (++scale); @@ -1114,7 +1104,7 @@ SINT64 CVT_get_int64(const dsc* desc, SSHORT scale, FPTR_VOID err) USHORT CVT_get_string_ptr(const dsc* desc, USHORT* ttype, UCHAR** address, - vary* temp, USHORT length, FPTR_VOID err) + vary* temp, USHORT length, FPTR_STATUS err) { /************************************** * @@ -1182,7 +1172,7 @@ USHORT CVT_get_string_ptr(const dsc* desc, } -GDS_DATE CVT_get_sql_date(const dsc* desc, FPTR_VOID err) +GDS_DATE CVT_get_sql_date(const dsc* desc, FPTR_STATUS err) { /************************************** * @@ -1208,7 +1198,7 @@ GDS_DATE CVT_get_sql_date(const dsc* desc, FPTR_VOID err) } -GDS_TIME CVT_get_sql_time(const dsc* desc, FPTR_VOID err) +GDS_TIME CVT_get_sql_time(const dsc* desc, FPTR_STATUS err) { /************************************** * @@ -1234,7 +1224,7 @@ GDS_TIME CVT_get_sql_time(const dsc* desc, FPTR_VOID err) } -GDS_TIMESTAMP CVT_get_timestamp(const dsc* desc, FPTR_VOID err) +GDS_TIMESTAMP CVT_get_timestamp(const dsc* desc, FPTR_STATUS err) { /************************************** * @@ -1265,7 +1255,7 @@ USHORT CVT_make_string(const dsc* desc, const char** address, VARY* temp, USHORT length, - FPTR_VOID err) + FPTR_STATUS err) { /************************************** * @@ -1315,7 +1305,7 @@ USHORT CVT_make_string(const dsc* desc, } -void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) +void CVT_move(const dsc* from, dsc* to, FPTR_STATUS err) { /************************************** * @@ -1370,8 +1360,9 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) isc_decode_timestamp(&date, ×); if ((times.tm_year + 1900) < MIN_YEAR || (times.tm_year) + 1900 > MAX_YEAR) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (isc_date_range_exceeded, 0); + { + (*err) (isc_date_range_exceeded, 0); + } ((GDS_TIMESTAMP *) to->dsc_address)->timestamp_date = date.timestamp_date; ((GDS_TIMESTAMP *) to->dsc_address)->timestamp_time = date.timestamp_time; @@ -1457,8 +1448,9 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) isc_decode_timestamp(&date, ×); if ((times.tm_year + 1900) < MIN_YEAR || (times.tm_year) + 1900 > MAX_YEAR) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (isc_date_range_exceeded, 0); + { + (*err) (isc_date_range_exceeded, 0); + } *((GDS_DATE *) to->dsc_address) = date.timestamp_date; } @@ -1476,8 +1468,9 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) isc_decode_timestamp(&new_date, ×); if ((times.tm_year + 1900) < MIN_YEAR || (times.tm_year) + 1900 > MAX_YEAR) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (isc_date_range_exceeded, 0); + { + (*err) (isc_date_range_exceeded, 0); + } *((GDS_DATE *) to->dsc_address) = ((GDS_TIMESTAMP *) from->dsc_address)->timestamp_date; @@ -1567,13 +1560,13 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) #ifndef REQUESTER #ifndef SUPERCLIENT if ((INTL_TTYPE(from) == ttype_dynamic) && - (err == (FPTR_VOID) ERR_post)) + (err == ERR_post)) charset1 = INTL_charset(NULL, INTL_TTYPE(from), err); else charset1 = INTL_TTYPE(from); if ((INTL_TTYPE(to) == ttype_dynamic) && - (err == (FPTR_VOID) ERR_post)) + (err == ERR_post)) charset2 = INTL_charset(NULL, INTL_TTYPE(to), err); else charset2 = INTL_TTYPE(to); @@ -1587,15 +1580,14 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) (charset1 != ttype_binary) && (charset2 != ttype_binary) && (charset1 != ttype_dynamic) && (charset2 != ttype_dynamic)) { - if (err == (FPTR_VOID) ERR_post) { + if (err == ERR_post) { INTL_convert_string(to, from, err); return; } else #endif #endif - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); #ifndef REQUESTER #ifndef SUPERCLIENT } @@ -1663,8 +1655,7 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) do { if (*q++ != ASCII_SPACE) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } while (--l); } return; @@ -1707,11 +1698,7 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) } if (to->dsc_dtype != from->dsc_dtype) - reinterpret_cast < pfn_cvt_private_cludge2 > (err) (gds_wish_list, - gds_arg_gds, - gds_blobnotsup, - gds_arg_string, - "move", 0); + (*err) (gds_wish_list, gds_arg_gds, gds_blobnotsup, gds_arg_string, "move", 0); /* Note: DSC_EQUIV failed above as the blob sub_types were different, * or their character sets were different. In V4 we aren't trying @@ -1728,8 +1715,7 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) /* assert(l <= MAX_SSHORT); */ *(SSHORT *) p = (SSHORT) l; if (*(SSHORT *) p != l) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); return; case dtype_long: @@ -1754,8 +1740,7 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) double d_value; d_value = CVT_get_double(from, err); if (ABSOLUT(d_value) > FLOAT_MAX) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); *(float*) p = (float) d_value; } return; @@ -1773,17 +1758,13 @@ void CVT_move(const dsc* from, dsc* to, FPTR_VOID err) } if (from->dsc_dtype == dtype_array || from->dsc_dtype == dtype_blob) - reinterpret_cast(err) (gds_wish_list, - gds_arg_gds, - gds_blobnotsup, - gds_arg_string, - "move", 0); + (*err) (gds_wish_list, gds_arg_gds, gds_blobnotsup, gds_arg_string, "move", 0); - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err) (gds_badblk, 0); /* internal error */ } -static void conversion_error(const dsc* desc, FPTR_VOID err) +static void conversion_error(const dsc* desc, FPTR_STATUS err) { /************************************** * @@ -1815,12 +1796,11 @@ static void conversion_error(const dsc* desc, FPTR_VOID err) #endif } - reinterpret_cast(err)(gds_convert_error, - gds_arg_string, p, 0); + (*err)(gds_convert_error, gds_arg_string, p, 0); } -static void datetime_to_text(const dsc* from, dsc* to, FPTR_VOID err) +static void datetime_to_text(const dsc* from, dsc* to, FPTR_STATUS err) { /************************************** * @@ -1866,7 +1846,7 @@ static void datetime_to_text(const dsc* from, dsc* to, FPTR_VOID err) break; default: assert(FALSE); - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err) (gds_badblk, 0); /* internal error */ break; } @@ -1950,7 +1930,7 @@ static SSHORT decompose(const char* string, USHORT length, SSHORT dtype, SLONG* return_value, - FPTR_VOID err) + FPTR_STATUS err) { /************************************** * @@ -1967,7 +1947,7 @@ static SSHORT decompose(const char* string, supported by the platform as a native datatype. */ if (dtype == dtype_quad) - reinterpret_cast (err) (gds_badblk, 0); /* internal error */ + (*err) (gds_badblk, 0); /* internal error */ #endif dsc errd; @@ -2002,12 +1982,10 @@ static SSHORT decompose(const char* string, if (value >= limit_by_10) { /* possibility of an overflow */ if (value > limit_by_10) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); else if (((*p > '8') && (sign == -1)) || ((*p > '7') && (sign != -1))) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } value = value * 10 + *p - '0'; @@ -2053,8 +2031,7 @@ static SSHORT decompose(const char* string, applied to the value. */ if (exp >= SHORT_LIMIT) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } else if (*p == '-' && !digit_seen && !sign) sign = -1; @@ -2120,7 +2097,7 @@ static TEXT* error_string(const char* in_string, SSHORT length) #endif -static void float_to_text(const dsc* from, dsc* to, FPTR_VOID err) +static void float_to_text(const dsc* from, dsc* to, FPTR_STATUS err) { /************************************** * @@ -2190,8 +2167,7 @@ static void float_to_text(const dsc* from, dsc* to, FPTR_VOID err) /* If we cannot print at least two digits, one on each side of the ".", report an overflow exception. */ if (precision < 2) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); chars_printed = sprintf(temp, num_format, width, precision, d); @@ -2203,8 +2179,7 @@ static void float_to_text(const dsc* from, dsc* to, FPTR_VOID err) if (chars_printed > width) { precision -= (chars_printed - width); if (precision < 2) - reinterpret_cast < pfn_cvt_private_cludge > - (err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); chars_printed = sprintf(temp, num_format, width, precision, d); } } @@ -2237,7 +2212,7 @@ static void float_to_text(const dsc* from, dsc* to, FPTR_VOID err) } -static void integer_to_text(const dsc* from, dsc* to, FPTR_VOID err) +static void integer_to_text(const dsc* from, dsc* to, FPTR_STATUS err) { /************************************** * @@ -2255,7 +2230,7 @@ static void integer_to_text(const dsc* from, dsc* to, FPTR_VOID err) supported by the platform as a native datatype. */ if (from->dsc_dtype == dtype_quad) - reinterpret_cast < pfn_cvt_private_cludge > (err) (gds_badblk, 0); /* internal error */ + (*err) (gds_badblk, 0); /* internal error */ #endif SSHORT pad = 0, decimal = 0, neg = 0; @@ -2382,7 +2357,7 @@ static void integer_to_text(const dsc* from, dsc* to, FPTR_VOID err) static void string_to_datetime( const dsc* desc, GDS_TIMESTAMP* date, - EXPECT_DATETIME expect_type, FPTR_VOID err) + EXPECT_DATETIME expect_type, FPTR_STATUS err) { /************************************** * @@ -2718,8 +2693,7 @@ static void string_to_datetime( if ((times.tm_year + 1900) < MIN_YEAR || (times.tm_year) + 1900 > MAX_YEAR) { - reinterpret_cast - (err) (isc_date_range_exceeded, 0); + (*err) (isc_date_range_exceeded, 0); } if (times.tm_year != times2.tm_year || diff --git a/src/jrd/cvt2.cpp b/src/jrd/cvt2.cpp index c2eaccae30..27e40c282a 100644 --- a/src/jrd/cvt2.cpp +++ b/src/jrd/cvt2.cpp @@ -97,12 +97,7 @@ static const BYTE compare_priority[] = { dtype_null, /* dtype_null through dtype dtype_long + 1 }; /* int64 goes right after long */ -#pragma FB_COMPILER_MESSAGE("Fix this! Ugly function pointer cast!") -typedef void (*pfn_cvt_private_cludge) (int, int); -typedef void (*pfn_cvt_private_cludge2) (int, int, ...); - - -SSHORT CVT2_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) +SSHORT CVT2_compare(const dsc* arg1, const dsc* arg2, FPTR_STATUS err) { /************************************** * @@ -493,11 +488,11 @@ SSHORT CVT2_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) return CVT2_blob_compare(arg1, arg2, err); case dtype_array: - reinterpret_cast < void (*) (...) > (*err) (gds_wish_list, - gds_arg_gds, - gds_blobnotsup, - gds_arg_string, "compare", - 0); + (*err) (gds_wish_list, + gds_arg_gds, + gds_blobnotsup, + gds_arg_string, "compare", + 0); break; default: @@ -508,7 +503,7 @@ SSHORT CVT2_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) } -SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) +SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_STATUS err) { /************************************** * @@ -529,7 +524,7 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) SSHORT l1, l2; USHORT ttype1, ttype2; SSHORT ret_val = 0; - TextType *obj1 = 0, *obj2 = 0; + TextType obj1 = NULL, obj2 = NULL; DSC desc1, desc2; bool bin_cmp = false, both_are_text = false; @@ -538,8 +533,7 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) /* DEV_BLKCHK (node, type_nod); */ if (arg1->dsc_dtype != dtype_blob) - reinterpret_cast < pfn_cvt_private_cludge2 > - (err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); + (*err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); /* Is arg2 a blob? */ if (arg2->dsc_dtype == dtype_blob) @@ -588,8 +582,8 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) { obj1 = INTL_texttype_lookup(tdbb, ttype1, err, NULL); obj2 = INTL_texttype_lookup(tdbb, ttype2, err, NULL); - ttype1 = obj1->getType(); - ttype2 = obj2->getType(); + ttype1 = obj1.getType(); + ttype2 = obj2.getType(); } bin_cmp = (ttype1 == ttype2 || ttype1 == ttype_none || ttype1 == ttype_ascii || ttype2 == ttype_none || ttype2 == ttype_ascii); @@ -603,16 +597,15 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) characters per chunk from both blobs. */ if (!bin_cmp && (blob1->blb_length > BUFFER_LARGE || blob2->blb_length > BUFFER_LARGE)) { - if (!obj1) + if (obj1 == NULL) { obj1 = INTL_texttype_lookup(tdbb, ttype1, err, NULL); obj2 = INTL_texttype_lookup(tdbb, ttype2, err, NULL); } - assert(obj1); - assert(obj2); - if (obj1->getBytesPerChar() != 1 || obj2->getBytesPerChar() != 1) - reinterpret_cast < pfn_cvt_private_cludge2 > - (err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); + assert(obj1 != NULL); + assert(obj2 != NULL); + if (obj1.getBytesPerChar() != 1 || obj2.getBytesPerChar() != 1) + (*err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); } while (!(blob1->blb_flags & BLB_eof) && !(blob2->blb_flags & BLB_eof)) @@ -712,8 +705,7 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) } /* We do not accept arrays for now. Maybe ADS in the future. */ else if (arg2->dsc_dtype == dtype_array) - reinterpret_cast < pfn_cvt_private_cludge2 > - (err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); + (*err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); /* The second parameter should be a string. */ else { @@ -744,16 +736,16 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) if (arg1->dsc_sub_type == BLOB_text) { obj1 = INTL_texttype_lookup(tdbb, ttype1, err, NULL); - assert(obj1); - ttype1 = obj1->getType(); + assert(obj1 != NULL); + ttype1 = obj1.getType(); if (ttype1 == ttype_none || ttype1 == ttype_ascii) bin_cmp = true; } if (arg2->dsc_dtype <= dtype_varying) { obj2 = INTL_texttype_lookup(tdbb, ttype2, err, NULL); - assert(obj2); - ttype2 = obj2->getType(); + assert(obj2 != NULL); + ttype2 = obj2.getType(); if (ttype2 == ttype_none || ttype2 == ttype_ascii) bin_cmp = true; } @@ -763,8 +755,7 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) /* I will stop execution here until I can complete this function. */ if (!bin_cmp) - reinterpret_cast < pfn_cvt_private_cludge2 > - (err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); + (*err) (gds_wish_list, gds_arg_gds, gds_datnotsup, 0); if (arg2->dsc_length > BUFFER_LARGE) { @@ -789,7 +780,7 @@ SSHORT CVT2_blob_compare(const dsc* arg1, const dsc* arg2, FPTR_VOID err) } -void CVT2_get_name(const dsc* desc, TEXT* string, FPTR_VOID err) +void CVT2_get_name(const dsc* desc, TEXT* string, FPTR_STATUS err) { /************************************** * @@ -817,7 +808,7 @@ void CVT2_get_name(const dsc* desc, TEXT* string, FPTR_VOID err) USHORT CVT2_make_string2(const dsc* desc, USHORT to_interp, UCHAR** address, - VARY* temp, USHORT length, STR* ptr, FPTR_VOID err) + VARY* temp, USHORT length, STR* ptr, FPTR_STATUS err) { /************************************** * diff --git a/src/jrd/cvt2_proto.h b/src/jrd/cvt2_proto.h index 3150a9ea2d..e17cd25077 100644 --- a/src/jrd/cvt2_proto.h +++ b/src/jrd/cvt2_proto.h @@ -24,11 +24,11 @@ #ifndef JRD_CVT2_PROTO_H #define JRD_CVT2_PROTO_H -SSHORT CVT2_compare(const dsc*, const dsc*, FPTR_VOID); -SSHORT CVT2_blob_compare(const dsc*, const dsc*, FPTR_VOID); -void CVT2_get_name(const dsc*, TEXT*, FPTR_VOID); +SSHORT CVT2_compare(const dsc*, const dsc*, FPTR_STATUS); +SSHORT CVT2_blob_compare(const dsc*, const dsc*, FPTR_STATUS); +void CVT2_get_name(const dsc*, TEXT*, FPTR_STATUS); USHORT CVT2_make_string2(const dsc*, USHORT, UCHAR**, vary*, - USHORT, str**, FPTR_VOID); + USHORT, str**, FPTR_STATUS); #endif // JRD_CVT2_PROTO_H diff --git a/src/jrd/cvt_proto.h b/src/jrd/cvt_proto.h index cb967e453e..c0099a3beb 100644 --- a/src/jrd/cvt_proto.h +++ b/src/jrd/cvt_proto.h @@ -24,21 +24,21 @@ #ifndef JRD_CVT_PROTO_H #define JRD_CVT_PROTO_H -double CVT_date_to_double(const dsc*, FPTR_VOID); -void CVT_double_to_date(double, SLONG[2], FPTR_VOID); -double CVT_get_double(const dsc*, FPTR_VOID); -SLONG CVT_get_long(const dsc*, SSHORT, FPTR_VOID); -SINT64 CVT_get_int64(const dsc*, SSHORT, FPTR_VOID); -UCHAR CVT_get_numeric(const UCHAR*, const USHORT, SSHORT*, double*, FPTR_VOID); -SQUAD CVT_get_quad(const dsc*, SSHORT, FPTR_VOID); +double CVT_date_to_double(const dsc*, FPTR_STATUS); +void CVT_double_to_date(double, SLONG[2], FPTR_STATUS); +double CVT_get_double(const dsc*, FPTR_STATUS); +SLONG CVT_get_long(const dsc*, SSHORT, FPTR_STATUS); +SINT64 CVT_get_int64(const dsc*, SSHORT, FPTR_STATUS); +UCHAR CVT_get_numeric(const UCHAR*, const USHORT, SSHORT*, double*, FPTR_STATUS); +SQUAD CVT_get_quad(const dsc*, SSHORT, FPTR_STATUS); USHORT CVT_get_string_ptr(const dsc*, USHORT*, UCHAR**, - vary*, USHORT, FPTR_VOID); -GDS_DATE CVT_get_sql_date(const dsc*, FPTR_VOID); -GDS_TIME CVT_get_sql_time(const dsc*, FPTR_VOID); -GDS_TIMESTAMP CVT_get_timestamp(const dsc*, FPTR_VOID); + vary*, USHORT, FPTR_STATUS); +GDS_DATE CVT_get_sql_date(const dsc*, FPTR_STATUS); +GDS_TIME CVT_get_sql_time(const dsc*, FPTR_STATUS); +GDS_TIMESTAMP CVT_get_timestamp(const dsc*, FPTR_STATUS); USHORT CVT_make_string(const dsc*, USHORT, const char**, vary*, - USHORT, FPTR_VOID); -extern "C" void CVT_move(const dsc*, dsc*, FPTR_VOID); + USHORT, FPTR_STATUS); +extern "C" void CVT_move(const dsc*, dsc*, FPTR_STATUS); #endif // JRD_CVT_PROTO_H diff --git a/src/jrd/dyn.h b/src/jrd/dyn.h index 446a9aed4f..5e70267c11 100644 --- a/src/jrd/dyn.h +++ b/src/jrd/dyn.h @@ -30,7 +30,6 @@ /* all applicable grant/revoke privileges for a procedure */ #define DYN_MSG_FAC 8 #define STUFF_COUNT 4 -#define MAX_KEY 256 #define TEXT_BLOB_LENGTH 512 #define PRIMARY_KEY "PRIMARY KEY" diff --git a/src/jrd/evl.cpp b/src/jrd/evl.cpp index 834bb05ed5..c4ff55d533 100644 --- a/src/jrd/evl.cpp +++ b/src/jrd/evl.cpp @@ -19,7 +19,7 @@ * * All Rights Reserved. * Contributor(s): ______________________________________. - * $Id: evl.cpp,v 1.44 2003-11-02 11:54:49 dimitr Exp $ + * $Id: evl.cpp,v 1.45 2003-11-03 17:14:44 skidder Exp $ */ /* @@ -159,12 +159,12 @@ static DSC *record_version(TDBB, JRD_NOD, VLU); static BOOLEAN reject_duplicate(UCHAR *, UCHAR *, int); static DSC *scalar(TDBB, JRD_NOD, VLU); static SSHORT sleuth(TDBB, JRD_NOD, DSC *, DSC *); -static BOOLEAN nc_sleuth_check(class TextType*, USHORT, UCHAR *, UCHAR *, UCHAR *, +static BOOLEAN nc_sleuth_check(TextType, USHORT, UCHAR *, UCHAR *, UCHAR *, UCHAR *); -static BOOLEAN nc_sleuth_class(class TextType*, USHORT, UCHAR *, UCHAR *, UCHAR); -static BOOLEAN wc_sleuth_check(class TextType*, USHORT, UCS2_CHAR *, UCS2_CHAR *, +static BOOLEAN nc_sleuth_class(TextType, USHORT, UCHAR *, UCHAR *, UCHAR); +static BOOLEAN wc_sleuth_check(TextType, USHORT, UCS2_CHAR *, UCS2_CHAR *, UCS2_CHAR *, UCS2_CHAR *); -static BOOLEAN wc_sleuth_class(class TextType*, USHORT, UCS2_CHAR *, UCS2_CHAR *, +static BOOLEAN wc_sleuth_class(TextType, USHORT, UCS2_CHAR *, UCS2_CHAR *, UCS2_CHAR); static SSHORT string_boolean(TDBB, JRD_NOD, DSC *, DSC *); static SSHORT string_function(TDBB, JRD_NOD, SSHORT, UCHAR *, SSHORT, UCHAR *, USHORT); @@ -1878,7 +1878,7 @@ void EVL_make_value(TDBB tdbb, DSC * desc, VLU value) USHORT EVL_mb_contains(TDBB tdbb, - class TextType* obj, + TextType obj, UCHAR * p1, USHORT l1, UCHAR * p2, @@ -1904,8 +1904,8 @@ USHORT EVL_mb_contains(TDBB tdbb, SET_TDBB(tdbb); - len1 = obj->to_wc(NULL, 0, p1, l1, &err_code, &err_pos); - len2 = obj->to_wc(NULL, 0, p2, l2, &err_code, &err_pos); + len1 = obj.to_wc(NULL, 0, p1, l1, &err_code, &err_pos); + len2 = obj.to_wc(NULL, 0, p2, l2, &err_code, &err_pos); if (len1 > sizeof(buffer1)) { buf1 = FB_NEW_RPT(*tdbb->tdbb_default, len1) str(); @@ -1916,8 +1916,8 @@ USHORT EVL_mb_contains(TDBB tdbb, pp2 = (UCS2_CHAR *) buf2->str_data; } - len1 = obj->to_wc(pp1, len1, p1, l1, &err_code, &err_pos); - len2 = obj->to_wc(pp2, len2, p2, l2, &err_code, &err_pos); + len1 = obj.to_wc(pp1, len1, p1, l1, &err_code, &err_pos); + len2 = obj.to_wc(pp2, len2, p2, l2, &err_code, &err_pos); ret_val = EVL_wc_contains(tdbb, obj, pp1, len1, pp2, len2); @@ -1931,7 +1931,7 @@ USHORT EVL_mb_contains(TDBB tdbb, USHORT EVL_mb_like(TDBB tdbb, - class TextType* obj, + TextType obj, UCHAR * p1, SSHORT l1, UCHAR * p2, @@ -1964,8 +1964,8 @@ USHORT EVL_mb_like(TDBB tdbb, SET_TDBB(tdbb); - len1 = obj->to_wc(NULL, 0, p1, l1, &err_code, &err_pos); - len2 = obj->to_wc(NULL, 0, p2, l2, &err_code, &err_pos); + len1 = obj.to_wc(NULL, 0, p1, l1, &err_code, &err_pos); + len2 = obj.to_wc(NULL, 0, p2, l2, &err_code, &err_pos); if (len1 > sizeof(buffer1)) { buf1 = FB_NEW_RPT(*tdbb->tdbb_default, len1) str(); pp1 = (UCS2_CHAR *) buf1->str_data; @@ -1975,8 +1975,8 @@ USHORT EVL_mb_like(TDBB tdbb, pp2 = (UCS2_CHAR *) buf2->str_data; } - len1 = obj->to_wc(pp1, len1, p1, l1, &err_code, &err_pos); - len2 = obj->to_wc(pp2, len2, p2, l2, &err_code, &err_pos); + len1 = obj.to_wc(pp1, len1, p1, l1, &err_code, &err_pos); + len2 = obj.to_wc(pp2, len2, p2, l2, &err_code, &err_pos); // CHECK ME: Shouldn't errors to be handled? ret_val = EVL_wc_like(tdbb, obj, pp1, len1, pp2, len2, escape_char); @@ -1991,7 +1991,7 @@ USHORT EVL_mb_like(TDBB tdbb, USHORT EVL_mb_matches(TDBB tdbb, - class TextType* obj, + TextType obj, UCHAR * p1, SSHORT l1, UCHAR * p2, @@ -2021,8 +2021,8 @@ USHORT EVL_mb_matches(TDBB tdbb, SET_TDBB(tdbb); - len1 = obj->to_wc(NULL, 0, p1, l1, &err_code, &err_pos); - len2 = obj->to_wc(NULL, 0, p2, l2, &err_code, &err_pos); + len1 = obj.to_wc(NULL, 0, p1, l1, &err_code, &err_pos); + len2 = obj.to_wc(NULL, 0, p2, l2, &err_code, &err_pos); if (len1 > sizeof(buffer1)) { buf1 = FB_NEW_RPT(*tdbb->tdbb_default, len1) str(); pp1 = (UCS2_CHAR *) buf1->str_data; @@ -2032,8 +2032,8 @@ USHORT EVL_mb_matches(TDBB tdbb, pp2 = (UCS2_CHAR *) buf2->str_data; } - len1 = obj->to_wc(pp1, len1, p1, l1, &err_code, &err_pos); - len2 = obj->to_wc(pp2, len2, p2, l2, &err_code, &err_pos); + len1 = obj.to_wc(pp1, len1, p1, l1, &err_code, &err_pos); + len2 = obj.to_wc(pp2, len2, p2, l2, &err_code, &err_pos); ret_val = EVL_wc_matches(tdbb, obj, pp1, len1, pp2, len2); @@ -2047,7 +2047,7 @@ USHORT EVL_mb_matches(TDBB tdbb, USHORT EVL_mb_sleuth_check(TDBB tdbb, - class TextType* obj, + TextType obj, USHORT flags, UCHAR * search, USHORT search_bytes, @@ -2083,13 +2083,13 @@ USHORT EVL_mb_sleuth_check(TDBB tdbb, SET_TDBB(tdbb); - len1 = obj->to_wc(NULL, 0, search, search_bytes, &err_code, &err_pos); + len1 = obj.to_wc(NULL, 0, search, search_bytes, &err_code, &err_pos); if (len1 > sizeof(buffer1)) { buf1 = FB_NEW_RPT(*tdbb->tdbb_default, len1) str(); pp1 = (UCS2_CHAR *) buf1->str_data; } - len1 = obj->to_wc(pp1, len1, search, search_bytes, &err_code, &err_pos); + len1 = obj.to_wc(pp1, len1, search, search_bytes, &err_code, &err_pos); ret_val = EVL_wc_sleuth_check(tdbb, obj, 0, pp1, len1, @@ -2104,7 +2104,7 @@ USHORT EVL_mb_sleuth_check(TDBB tdbb, USHORT EVL_mb_sleuth_merge(TDBB tdbb, - class TextType* obj, + TextType obj, UCHAR * match, USHORT match_bytes, UCHAR * control, @@ -2137,8 +2137,8 @@ USHORT EVL_mb_sleuth_merge(TDBB tdbb, SET_TDBB(tdbb); - len1 = obj->to_wc(NULL, 0, match, match_bytes, &err_code, &err_pos); - len2 = obj->to_wc(NULL, 0, control, control_bytes, &err_code, &err_pos); + len1 = obj.to_wc(NULL, 0, match, match_bytes, &err_code, &err_pos); + len2 = obj.to_wc(NULL, 0, control, control_bytes, &err_code, &err_pos); if (len1 > sizeof(buffer1)) { buf1 = FB_NEW_RPT(*tdbb->tdbb_default, len1) str(); pp1 = (UCS2_CHAR *) buf1->str_data; @@ -2148,8 +2148,8 @@ USHORT EVL_mb_sleuth_merge(TDBB tdbb, pp2 = (UCS2_CHAR *) buf2->str_data; } - len1 = obj->to_wc(pp1, len1, match, match_bytes, &err_code, &err_pos); - len2 = obj->to_wc(pp2, len2, control, control_bytes, &err_code, &err_pos); + len1 = obj.to_wc(pp1, len1, match, match_bytes, &err_code, &err_pos); + len2 = obj.to_wc(pp2, len2, control, control_bytes, &err_code, &err_pos); ret_val = EVL_wc_sleuth_merge(tdbb, obj, pp1, len1, pp2, len2, reinterpret_cast < UCS2_CHAR * >(combined), @@ -2165,7 +2165,7 @@ USHORT EVL_mb_sleuth_merge(TDBB tdbb, USHORT EVL_nc_contains(TDBB tdbb_dummy, - class TextType* obj, + TextType obj, UCHAR * p1, USHORT l1, UCHAR * p2, @@ -2194,7 +2194,7 @@ USHORT EVL_nc_contains(TDBB tdbb_dummy, return TRUE; c1 = *q1++; c2 = *q2++; - } while (obj->to_upper(c1) == obj->to_upper(c2)); + } while (obj.to_upper(c1) == obj.to_upper(c2)); } return FALSE; @@ -2245,7 +2245,7 @@ USHORT EVL_nc_contains(TDBB tdbb_dummy, USHORT EVL_wc_contains(TDBB tdbb_dumm, - class TextType* obj, + TextType obj, UCS2_CHAR* p1, USHORT l1, /* byte count */ UCS2_CHAR* p2, @@ -2274,7 +2274,7 @@ USHORT EVL_wc_contains(TDBB tdbb_dumm, return TRUE; c1 = *q1++; c2 = *q2++; - } while (obj->to_upper(c1) == obj->to_upper(c2)); + } while (obj.to_upper(c1) == obj.to_upper(c2)); } return FALSE; @@ -2387,8 +2387,8 @@ static DSC *add(DSC * desc, JRD_NOD node, VLU value) result->dsc_length = sizeof(SQUAD); result->dsc_scale = node->nod_scale; value->vlu_misc.vlu_quad = (node->nod_type == nod_subtract) ? - QUAD_SUBTRACT(q2, q1, (FPTR_VOID) ERR_post) : - QUAD_ADD(q1, q2, (FPTR_VOID) ERR_post); + QUAD_SUBTRACT(q2, q1, ERR_post) : + QUAD_ADD(q1, q2, ERR_post); result->dsc_address = (UCHAR *) & value->vlu_misc.vlu_quad; return result; @@ -2472,8 +2472,8 @@ static DSC *add2(DSC * desc, JRD_NOD node, VLU value) result->dsc_length = sizeof(SQUAD); result->dsc_scale = node->nod_scale; value->vlu_misc.vlu_quad = (node->nod_type == nod_subtract2) ? - QUAD_SUBTRACT(q2, q1, (FPTR_VOID) ERR_post) : - QUAD_ADD(q1, q2, (FPTR_VOID) ERR_post); + QUAD_SUBTRACT(q2, q1, ERR_post) : + QUAD_ADD(q1, q2, ERR_post); result->dsc_address = (UCHAR *) & value->vlu_misc.vlu_quad; return result; @@ -3634,7 +3634,7 @@ static SINT64 get_day_fraction(DSC * d) result.dsc_address = reinterpret_cast < UCHAR * >(&result_days); /* Convert the input number to a double */ - CVT_move(d, &result, reinterpret_cast < void (*)() > (ERR_post)); + CVT_move(d, &result, ERR_post); /* There's likely some loss of precision here due to rounding of number */ @@ -3718,7 +3718,7 @@ static SINT64 get_timestamp_to_isc_ticks(DSC * d) result.dsc_length = sizeof(GDS_TIMESTAMP); result.dsc_address = reinterpret_cast < UCHAR * >(&result_timestamp); - CVT_move(d, &result, reinterpret_cast < void (*)() > (ERR_post)); + CVT_move(d, &result, ERR_post); return ((SINT64) result_timestamp.timestamp_date) * ISC_TICKS_PER_DAY + (SINT64) result_timestamp.timestamp_time; @@ -4037,7 +4037,7 @@ static DSC *multiply(DSC * desc, VLU value, JRD_NOD node) value->vlu_desc.dsc_length = sizeof(SQUAD); value->vlu_desc.dsc_scale = node->nod_scale; value->vlu_misc.vlu_quad = - QUAD_MULTIPLY(q1, q2, (FPTR_VOID) ERR_post); + QUAD_MULTIPLY(q1, q2, ERR_post); value->vlu_desc.dsc_address = (UCHAR *) & value->vlu_misc.vlu_quad; return &value->vlu_desc; @@ -4135,7 +4135,7 @@ static DSC *multiply2(DSC * desc, VLU value, JRD_NOD node) value->vlu_desc.dsc_length = sizeof(SQUAD); value->vlu_desc.dsc_scale = node->nod_scale; value->vlu_misc.vlu_quad = - QUAD_MULTIPLY(q1, q2, (FPTR_VOID) ERR_post); + QUAD_MULTIPLY(q1, q2, ERR_post); value->vlu_desc.dsc_address = (UCHAR *) & value->vlu_misc.vlu_quad; return &value->vlu_desc; @@ -4381,7 +4381,7 @@ static DSC *negate_dsc(TDBB tdbb, DSC * desc, VLU value) case dtype_quad: value->vlu_misc.vlu_quad = - QUAD_NEGATE(value->vlu_misc.vlu_quad, (FPTR_VOID) ERR_post); + QUAD_NEGATE(value->vlu_misc.vlu_quad, ERR_post); break; case dtype_int64: @@ -4573,8 +4573,8 @@ static SSHORT sleuth(TDBB tdbb, JRD_NOD node, DSC * desc1, DSC * desc2) else ttype = INTL_TTYPE(desc1); - TextType* obj = - INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL); + TextType obj = + INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL); /* Get operator definition string (control string) */ @@ -4589,7 +4589,7 @@ static SSHORT sleuth(TDBB tdbb, JRD_NOD node, DSC * desc1, DSC * desc2) reinterpret_cast(temp2), TEMP_SIZE(temp2), &match_str); /* Merge search and control strings */ - l2 = obj->sleuth_merge(tdbb, p2, l2, p1, l1, control, + l2 = obj.sleuth_merge(tdbb, p2, l2, p1, l1, control, BUFFER_SMALL); /* l2 is result's byte-count */ @@ -4604,7 +4604,7 @@ static SSHORT sleuth(TDBB tdbb, JRD_NOD node, DSC * desc1, DSC * desc2) MOV_make_string2(desc1, ttype, &p1, reinterpret_cast(temp1), TEMP_SIZE(temp1), &data_str); - ret_val = obj->sleuth_check(tdbb, 0, p1, l1, control, l2); + ret_val = obj.sleuth_check(tdbb, 0, p1, l1, control, l2); } else { /* Source string is a blob, things get interesting */ @@ -4617,7 +4617,7 @@ static SSHORT sleuth(TDBB tdbb, JRD_NOD node, DSC * desc1, DSC * desc2) while (!(blob->blb_flags & BLB_eof)) { l1 = BLB_get_segment(tdbb, blob, buffer, sizeof(buffer)); - if (obj->sleuth_check(tdbb, 0, buffer, l1, control, l2)) + if (obj.sleuth_check(tdbb, 0, buffer, l1, control, l2)) { ret_val = TRUE; break; @@ -4751,8 +4751,6 @@ static SSHORT string_function( * or STARTS WITH. * **************************************/ - class TextType* obj; - SET_TDBB(tdbb); DEV_BLKCHK(node, type_nod); @@ -4767,12 +4765,12 @@ static SSHORT string_function( return TRUE; } - obj = INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL); + TextType obj = INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL); /* Handle contains */ if (node->nod_type == nod_contains) { - return obj->contains(tdbb, p1, l1, p2, l2); + return obj.contains(tdbb, p1, l1, p2, l2); } /* Handle LIKE and MATCHES */ @@ -4794,17 +4792,17 @@ static SSHORT string_function( if (!l3) ERR_post(gds_like_escape_invalid, 0); /* Grab the first character from the string */ - consumed = obj->mbtowc(&escape, reinterpret_cast(const_cast(q1)), l3); + consumed = obj.mbtowc(&escape, reinterpret_cast(const_cast(q1)), l3); /* If characters left, or null byte character, return error */ if (consumed <= 0 || consumed != l3 || (escape == 0)) ERR_post(gds_like_escape_invalid, 0); } - return obj->like(tdbb, p1, l1, p2, l2, escape); + return obj.like(tdbb, p1, l1, p2, l2, escape); } - return obj->matches(tdbb, p1, l1, p2, l2); + return obj.matches(tdbb, p1, l1, p2, l2); } @@ -4825,7 +4823,7 @@ static DSC *substring( DSC desc; UCHAR temp[32]; USHORT ttype; - TextType *obj1 = 0; + TextType obj1 = NULL; /* CVC: I didn't bother to define a larger buffer because: - Native types when converted to string don't reach 31 bytes plus terminator. - String types do not need and do not use the buffer ("temp") to be pulled. @@ -4848,8 +4846,8 @@ static DSC *substring( if (dtype_blob == value->dsc_dtype && (BLOB_text != value->dsc_sub_type || (ttype = value->dsc_scale) == ttype_ascii || ttype == ttype_none || ttype == ttype_binary - || ((obj1 = INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL)) != 0 - && 1 == obj1->getBytesPerChar()))) + || ((obj1 = INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL)) != NULL + && 1 == obj1.getBytesPerChar()))) { /* Source string is a blob, things get interesting. */ @@ -4927,7 +4925,7 @@ static DSC *substring( I couldn't find an appropriate message for this failure among current registered messages, so I will return empty. Finally I decided to use arithmetic exception or numeric overflow. */ - TextType *text_obj = 0; + TextType text_obj = 0; UCHAR *p = (UCHAR*) desc.dsc_address; USHORT pcount = desc.dsc_length; BOOLEAN failure = FALSE; diff --git a/src/jrd/evl_like.cpp b/src/jrd/evl_like.cpp index fc5bff0576..017d32d21e 100644 --- a/src/jrd/evl_like.cpp +++ b/src/jrd/evl_like.cpp @@ -28,8 +28,7 @@ */ #define SLEUTH_insensitive 1 -#define COND_UPPER(obj,c) ((flags & SLEUTH_insensitive) ? \ - (obj)->to_upper(c) : (c)) +#define COND_UPPER(obj,c) ((flags & SLEUTH_insensitive) ? (obj).to_upper(c) : (c)) #define SQL_MATCH_ONE '_' #define SQL_MATCH_ANY '%' @@ -50,7 +49,7 @@ #define GDML_RPAREN ')' -USHORT LIKENAME(TDBB tdbb, class TextType* obj, LIKETYPE * p1, SSHORT l1_bytes, /* byte count */ +USHORT LIKENAME(TDBB tdbb, TextType obj, LIKETYPE * p1, SSHORT l1_bytes, /* byte count */ LIKETYPE * p2, SSHORT l2_bytes, /* byte count */ UCS2_CHAR escape_char) { @@ -131,7 +130,7 @@ USHORT LIKENAME(TDBB tdbb, class TextType* obj, LIKETYPE * p1, SSHORT l1_bytes, USHORT MATCHESNAME(TDBB tdbb, - class TextType* obj, + TextType obj, MATCHESTYPE * p1, SSHORT l1_bytes, MATCHESTYPE * p2, SSHORT l2_bytes) { @@ -194,7 +193,7 @@ USHORT MATCHESNAME(TDBB tdbb, USHORT SLEUTHNAME(TDBB tdbb_dummy, - class TextType* obj, + TextType obj, USHORT flags, SLEUTHTYPE * search, USHORT search_len, SLEUTHTYPE * match, USHORT match_len) @@ -226,7 +225,7 @@ USHORT SLEUTHNAME(TDBB tdbb_dummy, USHORT SLEUTH_MERGE_NAME(TDBB tdbb_dummy, - class TextType* obj, + TextType obj, SLEUTHTYPE * match, USHORT match_bytes, SLEUTHTYPE * control, @@ -345,7 +344,7 @@ USHORT SLEUTH_MERGE_NAME(TDBB tdbb_dummy, static BOOLEAN SLEUTH_AUX( - class TextType* obj, + TextType obj, USHORT flags, SLEUTHTYPE * search, SLEUTHTYPE * end_search, @@ -459,7 +458,7 @@ SLEUTHTYPE * match, SLEUTHTYPE * end_match) static BOOLEAN SLEUTH_CLASS_NAME( - class TextType* obj, + TextType obj, USHORT flags, SLEUTHTYPE * class_, SLEUTHTYPE * end_class, SLEUTHTYPE character) diff --git a/src/jrd/evl_proto.h b/src/jrd/evl_proto.h index a4cc5c18e9..6ab812f3eb 100644 --- a/src/jrd/evl_proto.h +++ b/src/jrd/evl_proto.h @@ -32,27 +32,27 @@ BOOLEAN EVL_boolean(TDBB tdbb, struct jrd_nod *); struct dsc* EVL_expr(TDBB tdbb, struct jrd_nod *); BOOLEAN EVL_field(struct jrd_rel *, struct rec *, USHORT, DSC *); USHORT EVL_group(TDBB tdbb, struct blk *, struct jrd_nod *, USHORT); -USHORT EVL_mb_contains(TDBB tdbb, TextType*, UCHAR *, USHORT, UCHAR *, USHORT); -USHORT EVL_mb_like(TDBB tdbb, TextType*, UCHAR *, SSHORT, UCHAR *, SSHORT, USHORT); -USHORT EVL_mb_matches(TDBB tdbb, TextType*, UCHAR *, SSHORT, UCHAR *, SSHORT); -USHORT EVL_mb_sleuth_check(TDBB tdbb, TextType*, USHORT, UCHAR *, USHORT, +USHORT EVL_mb_contains(TDBB tdbb, TextType, UCHAR *, USHORT, UCHAR *, USHORT); +USHORT EVL_mb_like(TDBB tdbb, TextType, UCHAR *, SSHORT, UCHAR *, SSHORT, USHORT); +USHORT EVL_mb_matches(TDBB tdbb, TextType, UCHAR *, SSHORT, UCHAR *, SSHORT); +USHORT EVL_mb_sleuth_check(TDBB tdbb, TextType, USHORT, UCHAR *, USHORT, UCHAR *,USHORT); -USHORT EVL_mb_sleuth_merge(TDBB tdbb, TextType*, UCHAR *, USHORT, UCHAR *, +USHORT EVL_mb_sleuth_merge(TDBB tdbb, TextType, UCHAR *, USHORT, UCHAR *, USHORT, UCHAR *, USHORT); void EVL_make_value(TDBB tdbb, struct dsc *, struct vlu *); -USHORT EVL_nc_contains(TDBB tdbb, TextType*, UCHAR *, USHORT, UCHAR *, USHORT); -USHORT EVL_nc_like(TDBB tdbb, TextType*, UCHAR *, SSHORT, UCHAR *, SSHORT, USHORT); -USHORT EVL_nc_matches(TDBB tdbb, TextType*, UCHAR *, SSHORT, UCHAR *, SSHORT); -USHORT EVL_nc_sleuth_check(TDBB tdbb, TextType*, USHORT, UCHAR *, USHORT, +USHORT EVL_nc_contains(TDBB tdbb, TextType, UCHAR *, USHORT, UCHAR *, USHORT); +USHORT EVL_nc_like(TDBB tdbb, TextType, UCHAR *, SSHORT, UCHAR *, SSHORT, USHORT); +USHORT EVL_nc_matches(TDBB tdbb, TextType, UCHAR *, SSHORT, UCHAR *, SSHORT); +USHORT EVL_nc_sleuth_check(TDBB tdbb, TextType, USHORT, UCHAR *, USHORT, UCHAR *, USHORT); -USHORT EVL_nc_sleuth_merge(TDBB tdbb, TextType*, UCHAR *, USHORT, UCHAR *, +USHORT EVL_nc_sleuth_merge(TDBB tdbb, TextType, UCHAR *, USHORT, UCHAR *, USHORT, UCHAR *, USHORT); -USHORT EVL_wc_contains(TDBB tdbb, TextType*, USHORT *, USHORT, USHORT *, USHORT); -USHORT EVL_wc_like(TDBB tdbb, TextType*, USHORT *, SSHORT, USHORT *, SSHORT, USHORT); -USHORT EVL_wc_matches(TDBB tdbb, TextType*, USHORT *, SSHORT, USHORT *, SSHORT); -USHORT EVL_wc_sleuth_check(TDBB tdbb, TextType*, USHORT, USHORT *, USHORT, +USHORT EVL_wc_contains(TDBB tdbb, TextType, USHORT *, USHORT, USHORT *, USHORT); +USHORT EVL_wc_like(TDBB tdbb, TextType, USHORT *, SSHORT, USHORT *, SSHORT, USHORT); +USHORT EVL_wc_matches(TDBB tdbb, TextType, USHORT *, SSHORT, USHORT *, SSHORT); +USHORT EVL_wc_sleuth_check(TDBB tdbb, TextType, USHORT, USHORT *, USHORT, USHORT *, USHORT); -USHORT EVL_wc_sleuth_merge(TDBB tdbb, TextType*, USHORT *, USHORT, USHORT *, +USHORT EVL_wc_sleuth_merge(TDBB tdbb, TextType, USHORT *, USHORT, USHORT *, USHORT, USHORT *, USHORT); #endif // JRD_EVL_PROTO_H diff --git a/src/jrd/filters.cpp b/src/jrd/filters.cpp index f8f4884fe4..9c8d418138 100644 --- a/src/jrd/filters.cpp +++ b/src/jrd/filters.cpp @@ -667,7 +667,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) USHORT result_length; typedef struct ctlaux { - CsConvert *ctlaux_obj1; /* Intl object that does tx for us */ + CsConvert ctlaux_obj1; /* Intl object that does tx for us */ BYTE *ctlaux_buffer1; /* Temporary buffer for transliteration */ CTL ctlaux_subfilter; /* For chaining transliterate filters */ ISC_STATUS ctlaux_source_blob_status; /* marks when source is EOF, etc */ @@ -713,7 +713,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) SET_TDBB(tdbb); aux->ctlaux_obj1 = INTL_convert_lookup(tdbb, dest_cs, source_cs); - if (!aux->ctlaux_obj1) { + if (aux->ctlaux_obj1 == NULL) { /* Do the convert the hard way, via Unicode. In this case, we become the filter from Unicode to the destination format. And we setup as our source @@ -729,7 +729,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) INTL_convert_lookup(tdbb, CS_UNICODE_UCS2, source_cs); } - if (!aux->ctlaux_obj1) { + if (aux->ctlaux_obj1 == NULL) { control->ctl_status[0] = gds_arg_gds; control->ctl_status[1] = gds_text_subtype; control->ctl_status[2] = gds_arg_number; @@ -769,7 +769,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) if (action == ACTION_open) { control->ctl_max_segment = - aux->ctlaux_obj1->convert(NULL, 0, NULL, + aux->ctlaux_obj1.convert(NULL, 0, NULL, source->ctl_max_segment, &err_code, &err_position); if (source->ctl_max_segment && control->ctl_max_segment) @@ -800,7 +800,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) * for an appropriate buffer size, allocate that, and re-allocate * later if we guess wrong. */ - tmp = aux->ctlaux_obj1->convert( NULL, 0, NULL, + tmp = aux->ctlaux_obj1.convert( NULL, 0, NULL, 128, &err_code, &err_position); aux->ctlaux_expansion_factor = (EXP_SCALE * tmp) / 128; @@ -851,7 +851,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) /* Now convert from the input buffer into the temporary buffer */ /* How much space do we need to convert? */ - result_length = aux->ctlaux_obj1->convert(NULL, 0, + result_length = aux->ctlaux_obj1.convert(NULL, 0, control->ctl_buffer, control->ctl_buffer_length, &err_code, &err_position); @@ -867,7 +867,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) /* convert the text */ - result_length = aux->ctlaux_obj1->convert(aux->ctlaux_buffer1, + result_length = aux->ctlaux_obj1.convert(aux->ctlaux_buffer1, aux->ctlaux_buffer1_len, control->ctl_buffer, control->ctl_buffer_length, &err_code, &err_position); @@ -959,7 +959,7 @@ ISC_STATUS filter_transliterate_text(USHORT action, CTL control) /* Now convert from the temporary buffer into the destination buffer */ - result_length = aux->ctlaux_obj1->convert(control->ctl_buffer, + result_length = aux->ctlaux_obj1.convert(control->ctl_buffer, control->ctl_buffer_length, aux->ctlaux_buffer1, length, &err_code, &err_position); diff --git a/src/jrd/intl.cpp b/src/jrd/intl.cpp index eae81cecbe..2dd48a9389 100644 --- a/src/jrd/intl.cpp +++ b/src/jrd/intl.cpp @@ -135,8 +135,6 @@ #else #define INTL_TRACE(args) #endif -/* 11 Sept 2002, Nickolay Samofatov. It is used only in asserts, - move it out DEV_BUILD section and let optimizer optimize it out */ #define IS_TEXT(x) (((x)->dsc_dtype == dtype_text) ||\ ((x)->dsc_dtype == dtype_varying)||\ ((x)->dsc_dtype == dtype_cstring)) @@ -147,42 +145,14 @@ typedef unsigned char FILECHAR; -// extern declarations for the allocator functions for builtin charsets -CharSetAllocFunc INTL_charset_alloc_func(short); -TextTypeAllocFunc INTL_texttype_alloc_func(short); -CsConvertAllocFunc INTL_csconvert_alloc_func(short, short); - static bool all_spaces(TDBB, CHARSET_ID, const BYTE*, USHORT, USHORT); -#ifdef NOT_USED_OR_REPLACED -#ifdef DEV_BUILD -static void dump_hex(UCHAR *, USHORT); -static void dump_latin(UCHAR *, USHORT); -#endif -#endif -//static void finish_texttype_init(TextType*, FPTR_VOID, ISC_STATUS *); -//static SSHORT internal_str_to_upper(TextType*, USHORT, UCHAR *, USHORT, -// UCHAR *); -//static USHORT internal_string_to_key(TextType*, USHORT, UCHAR *, USHORT, -// UCHAR *, USHORT); -//static USHORT mb_to_wc(CsConvert*, UCS2_CHAR *, USHORT, MBCHAR *, USHORT, SSHORT *, -// USHORT *); -#ifdef NOT_USED_OR_REPLACED -static USHORT nc_to_wc(CsConvert*, UCS2_CHAR *, USHORT, UCHAR *, USHORT, SSHORT *, - USHORT *); -#endif static void pad_spaces(TDBB, CHARSET_ID, BYTE *, USHORT); -//static USHORT wc_to_mb(CsConvert*, MBCHAR *, USHORT, UCS2_CHAR *, USHORT, SSHORT *, -// USHORT *); -//static USHORT wc_to_nc(CsConvert*, NCHAR *, USHORT, UCS2_CHAR *, USHORT, SSHORT *, -// USHORT *); -//static USHORT wc_to_wc(CsConvert*, UCS2_CHAR *, USHORT, UCS2_CHAR *, USHORT, SSHORT *, -// USHORT *); - -static CharSetContainer *internal_charset_container_lookup(TDBB, SSHORT, ISC_STATUS *); -static void* search_out_alloc_func(const char *, CHARSET_ID, CHARSET_ID); -static void* intl_back_compat_alloc_func_lookup(USHORT, CHARSET_ID, CHARSET_ID); -static void* intl_back_compat_obj_init_lookup(USHORT, SSHORT, SSHORT); - +static void* lookup_init_function(USHORT, SSHORT, SSHORT); +static void finish_texttype_init(TEXTTYPE); +static USHORT nc_to_wc(CSCONVERT, WCHAR *, USHORT, UCHAR *, USHORT, SSHORT *, + USHORT *); +static USHORT wc_to_wc(CSCONVERT, WCHAR *, USHORT, WCHAR *, USHORT, SSHORT *, + USHORT *); /* Name of module that implements text-type (n) */ @@ -210,70 +180,393 @@ static void* intl_back_compat_obj_init_lookup(USHORT, SSHORT, SSHORT); #define INTL_LOOKUP_ENTRY2 "LD2_lookup" #define INTL_USER_ENTRY "USER_TEXTTYPE_%03d" +// We need all the structure definitions from the old interface +#define INTL_ENGINE_INTERNAL +#include "../jrd/intlobj.h" + +// storage for the loadable modules +static PluginManager intlBCPlugins; +static bool bcLoaded = false; + +static const char *INTL_PLUGIN_DIR = "intl"; + +class CharsetIDGetter +{ +public: + static CHARSET_ID generate(void *sender, const CsConvert& Item) { + return Item.getToCS(); + } +}; // Classes and structures used internally to this file and intl implementation class CharSetContainer { public: - CharSetContainer(MemoryPool &p, CharSet *cs = 0) : - charset_converters(p), - charset_collations(p), - impossible_conversions(p), - cs(cs) - {} + CharSetContainer(MemoryPool *p, USHORT cs_id); - CharSet *getCharSet() { return cs; } + CharSet getCharSet() { return cs; } - void setCollation(TextType *cs, unsigned short id) - { - if (id >= charset_collations.size()) - charset_collations.resize(id + 10); - charset_collations[id] = cs; - } + TextType lookupCollation(TDBB tdbb, USHORT tt_id); - TextType *collation(unsigned short id) - { - if (id >= charset_collations.size()) - return NULL; - return charset_collations[id]; - } + CsConvert lookupConverter(TDBB tdbb, CHARSET_ID to_cs); - bool findConverter(CHARSET_ID id, CsConvert **cvt) - { - *cvt = NULL; - for(Firebird::vector::iterator itr1 = charset_converters.begin(); - itr1 != charset_converters.end(); ++itr1) - if ((*itr1)->getToCS() == id) - { - *cvt = *itr1; - return true; - } - - for(Firebird::vector::iterator itr2 = impossible_conversions.begin(); - itr2 != impossible_conversions.end(); ++itr2) - if (*itr2 == id) - return true; - return false; - } - - void addConverter(CsConvert *conv) - { - charset_converters.push_back(conv); - } - - void addNullConverter(CHARSET_ID nullId) - { - impossible_conversions.push_back(nullId); - } + static CharSetContainer* lookupCharset(TDBB tdbb, SSHORT ttype, ISC_STATUS *status); private: - Firebird::vector charset_converters; - Firebird::vector charset_collations; - Firebird::vector impossible_conversions; - CharSet *cs; + Firebird::SortedArray charset_converters; + Firebird::Array charset_collations; + Firebird::SortedArray impossible_conversions; + CharSet cs; }; -CHARSET_ID INTL_charset(TDBB tdbb, USHORT ttype, FPTR_VOID err) +CharSetContainer* CharSetContainer::lookupCharset(TDBB tdbb, SSHORT ttype, ISC_STATUS *status) +{ +/************************************** + * + * l o o k u p C h a r s e t + * + ************************************** + * + * Functional description + * + * Lookup a character set descriptor. + * + * First, search the appropriate vector that hangs + * off the dbb. If not found, then call the lower + * level lookup routine to allocate it, or return + * null if we don't know about the charset. + * + * Returns: + * *charset - if no errors; + * - if error & err non NULL + * NULL - if error & err NULL + * + **************************************/ + DBB dbb; + CharSetContainer *cs = NULL; + USHORT id; + + SET_TDBB(tdbb); + dbb = tdbb->tdbb_database; + + id = TTYPE_TO_CHARSET(ttype); + if (id == CS_dynamic) + id = tdbb->tdbb_attachment->att_charset; + + if (id >= dbb->dbb_charsets.size()) + dbb->dbb_charsets.resize(id + 10); + else + cs = dbb->dbb_charsets[id]; + + // allocate a new character set object if we couldn't find one. + if (!cs) { + cs = FB_NEW(*dbb->dbb_permanent) CharSetContainer(dbb->dbb_permanent, id); + if (cs->getCharSet() == NULL) { + delete cs; + return NULL; + } + dbb->dbb_charsets[id] = cs; + } + + assert(cs != NULL); + return cs; +} + +CharSetContainer::CharSetContainer(MemoryPool *p, USHORT cs_id) : + charset_converters(p), + charset_collations(p), + impossible_conversions(p), + cs(NULL) +{ + typedef USHORT (*CSInitFunc)(CHARSET, SSHORT, SSHORT); + CSInitFunc csInitFunc = + reinterpret_cast(lookup_init_function(type_charset, cs_id, 0)); + CHARSET cs = FB_NEW(*p) charset; + memset(cs, 0, sizeof(charset)); + + if (!csInitFunc || (*csInitFunc)(cs, cs_id, 0) != 0) + { + delete cs; + cs = NULL; + } + + this->cs = cs; +} + +CsConvert CharSetContainer::lookupConverter(TDBB tdbb, CHARSET_ID to_cs) +{ + int pos; + if (charset_converters.find(to_cs, pos)) + return charset_converters[pos]; + if (impossible_conversions.find(to_cs, pos)) + return NULL; + if (to_cs == CS_UNICODE_UCS2) { + return cs.getConvToUnicode(); + } + if (cs.getId() == CS_UNICODE_UCS2) { + CharSet to_charset = INTL_charset_lookup(tdbb, to_cs, NULL); + if (to_charset == NULL) + return NULL; + return to_charset.getConvFromUnicode(); + } + + typedef USHORT (*CVTInitFunc)(CSCONVERT, SSHORT, SSHORT); + CVTInitFunc cvtInitFunc = + reinterpret_cast(lookup_init_function(type_csconvert, to_cs, cs.getId())); + if (!cvtInitFunc) { + impossible_conversions.add(to_cs); + return NULL; + } + + CSCONVERT cvt = FB_NEW(*tdbb->tdbb_database->dbb_permanent) csconvert; + memset(cvt, 0, sizeof(csconvert)); + if ((*cvtInitFunc)(cvt, to_cs, cs.getId()) != 0) + { + impossible_conversions.add(to_cs); + delete cvt; + return NULL; + } + CsConvert converter = cvt; + assert(converter.getFromCS() == cs.getId()); + assert(converter.getToCS() == to_cs); + charset_converters.add(converter); + return cvt; +} + +TextType CharSetContainer::lookupCollation(TDBB tdbb, USHORT tt_id) +{ + USHORT id = TTYPE_TO_COLLATION(tt_id); + + if (id < charset_collations.getCount() && charset_collations[id] != NULL) + return charset_collations[id]; + typedef USHORT (*TTInitFunc)(TEXTTYPE, SSHORT, SSHORT); + TTInitFunc ttInitFunc = + reinterpret_cast(lookup_init_function(type_texttype, tt_id, 0)); + if (!ttInitFunc) + return NULL; + TEXTTYPE tt = FB_NEW(*tdbb->tdbb_database->dbb_permanent) texttype; + memset(tt, 0, sizeof(texttype)); + if ((*ttInitFunc)(tt, tt_id, 0) != 0) + { + delete tt; + return NULL; + } + finish_texttype_init(tt); + if (charset_collations.getCount() <= id) + charset_collations.grow(id+1); + charset_collations[id] = tt; + + return tt; +} + +static void finish_texttype_init(TEXTTYPE txtobj) +{ +/************************************** + * + * f i n i s h _ t e x t t y p e _ i n i t + * + ************************************** + * + * Functional description + * + * Finish initializing a text object with pointers to + * internal routines. + * This is also a handy place to check the licensing bits + * for the text object. + * + * Returns: + * The TEXTTYPE_init bit in texttype_flags is set if the + * object is sucessfully initialized. + * + **************************************/ + + if ((txtobj->texttype_fn_to_wc == NULL) && + (txtobj->texttype_bytes_per_char == 1)) { + /* Finish initialization of a narrow character object */ + + txtobj->texttype_fn_to_wc = (FPTR_SHORT) nc_to_wc; + txtobj->texttype_fn_contains = (FPTR_SHORT) EVL_nc_contains; + txtobj->texttype_fn_matches = (FPTR_SHORT) EVL_nc_matches; + txtobj->texttype_fn_like = (FPTR_SHORT) EVL_nc_like; + txtobj->texttype_fn_sleuth_merge = (FPTR_SHORT) EVL_nc_sleuth_merge; + txtobj->texttype_fn_sleuth_check = (FPTR_SHORT) EVL_nc_sleuth_check; + + if (!txtobj->texttype_fn_mbtowc) + txtobj->texttype_fn_mbtowc = (FPTR_short) INTL_builtin_nc_mbtowc; + } + else if ((txtobj->texttype_fn_to_wc == NULL) && + (txtobj->texttype_bytes_per_char == 2)) { + /* Finish initialization of a wide character object */ + + txtobj->texttype_fn_to_wc = (FPTR_SHORT) wc_to_wc; + txtobj->texttype_fn_contains = (FPTR_SHORT) EVL_wc_contains; + txtobj->texttype_fn_matches = (FPTR_SHORT) EVL_wc_matches; + txtobj->texttype_fn_like = (FPTR_SHORT) EVL_wc_like; + txtobj->texttype_fn_sleuth_merge = (FPTR_SHORT) EVL_wc_sleuth_merge; + txtobj->texttype_fn_sleuth_check = (FPTR_SHORT) EVL_wc_sleuth_check; + if (!txtobj->texttype_fn_mbtowc) + txtobj->texttype_fn_mbtowc = (FPTR_short) INTL_builtin_wc_mbtowc; + } + else if (txtobj->texttype_fn_to_wc != NULL) { + /* Finish initialization of a multibyte character object */ + + txtobj->texttype_fn_contains = (FPTR_SHORT) EVL_mb_contains; + txtobj->texttype_fn_matches = (FPTR_SHORT) EVL_mb_matches; + txtobj->texttype_fn_like = (FPTR_SHORT) EVL_mb_like; + txtobj->texttype_fn_sleuth_merge = (FPTR_SHORT) EVL_mb_sleuth_merge; + txtobj->texttype_fn_sleuth_check = (FPTR_SHORT) EVL_mb_sleuth_check; + if (!txtobj->texttype_fn_mbtowc) + txtobj->texttype_fn_mbtowc = (FPTR_short) INTL_builtin_mb_mbtowc; + } + else + assert(0); + + txtobj->texttype_flags |= TEXTTYPE_init; +} + +static void* lookup_init_function( + USHORT type, + SSHORT parm1, + SSHORT parm2) +{ +/************************************** + * + * lookup_init_function + * + ************************************** + * + * Functional description + * Find the allocator function for the requested international + * character set using the c/IB/FB 6.0 interface. + * Search algorithm is: + * Look in intllib + * Look in intllib2 + * Look for a normal UDF entry + * Abort with an error. + * + * Returns: + * FALSE - no errors + * TRUE - error occurred, and parameter was NULL; + * - error occurred, and parameter non-NULL; + * + * + ***************************************/ + USHORT (*function)(); + + if (!bcLoaded) + { + intlBCPlugins.addSearchPath(INTL_PLUGIN_DIR); + bcLoaded = true; + } + + PluginManager::Plugin intlMod1 = intlBCPlugins.findPlugin(INTL_MODULE1); + PluginManager::Plugin intlMod2 = intlBCPlugins.findPlugin(INTL_MODULE2); + + USHORT(*lookup_fn) (USHORT, FPTR_SHORT *, SSHORT, SSHORT); + + INTL_TRACE(("INTL: looking for obj %d ttype %d\n", objtype, parm1)); + + function = INTL_builtin_lookup(type, parm1, parm2); + if (function) return function; + +#ifdef INTL_BUILTIN + if (LD_lookup(type, &function, parm1, parm2) != 0) + function = NULL; + else + return function; +#else + /* Look for an InterBase supplied object to implement the text type */ + /* The flu.c uses searchpath which expects a file name not a path */ + INTL_TRACE(("INTL: trying %s %s\n", INTL_MODULE1, INTL_LOOKUP_ENTRY1)); + Firebird::string tempStr(INTL_LOOKUP_ENTRY1); + if ( intlMod1 && (lookup_fn = (USHORT(*)(USHORT, USHORT(**)(), short, short)) + (intlMod1.lookupSymbol(tempStr))) ) { + INTL_TRACE(("INTL: calling lookup %s %s\n", INTL_MODULE1, + INTL_LOOKUP_ENTRY1)); + if ((*lookup_fn) (type, &function, parm1, parm2) != 0) { + function = NULL; + } + else + { + return function; + } + } +#endif + +/* Still not found, check the set of supplimental international objects */ +#ifdef INTL_BUILTIN + if (LD2_lookup(type, &function, parm1, parm2) != 0) + function = NULL; + else + return function; +#else + /* Look for an InterBase supplied object to implement the text type */ + /* The flu.c uses searchpath which expects a file name not a path */ + INTL_TRACE(("INTL: trying %s %s\n", INTL_MODULE2, INTL_LOOKUP_ENTRY2)); + tempStr = INTL_LOOKUP_ENTRY2; + if ( intlMod2 && (lookup_fn = (USHORT(*)(USHORT, USHORT(**)(), short, short)) + (intlMod2.lookupSymbol(tempStr))) ) { + INTL_TRACE(("INTL: calling lookup %s %s\n", INTL_MODULE2, + INTL_LOOKUP_ENTRY2)); + if ((*lookup_fn) (type, &function, parm1, parm2) != 0) { + function = NULL; + } + else + { + return function; + } + } +#endif + +/* Still not found, check if there is a UDF in the database defined the right way */ + FUN function_block; + USHORT argcount; + char entry[48]; + + switch (type) { + case type_texttype: + sprintf(entry, INTL_USER_ENTRY, parm1); + argcount = 2; + break; + case type_charset: + sprintf(entry, "USER_CHARSET_%03d", parm1); + argcount = 2; + break; + case type_csconvert: + sprintf(entry, "USER_TRANSLATE_%03d_%03d", parm1, + parm2); + argcount = 3; + break; + default: + BUGCHECK(1); + break; + } + INTL_TRACE(("INTL: trying user fn %s\n", entry)); + if ( (function_block = FUN_lookup_function((TEXT*)entry, false)) ) { + INTL_TRACE(("INTL: found a user fn, validating\n")); + if ((function_block->fun_count == argcount) && + (function_block->fun_args == argcount) && + (function_block->fun_return_arg == 0) && + (function_block->fun_entrypoint != NULL) && + (function_block->fun_rpt[0].fun_mechanism == FUN_value) && + (function_block->fun_rpt[0].fun_desc.dsc_dtype == dtype_short) + && (function_block->fun_rpt[1].fun_desc.dsc_dtype == + dtype_short) + && (function_block->fun_rpt[argcount - 1]. + fun_desc.dsc_dtype == dtype_short) + && (function_block->fun_rpt[argcount].fun_mechanism == + FUN_reference) + && (function_block->fun_rpt[argcount].fun_desc.dsc_dtype == + dtype_text)) + { + return function_block->fun_entrypoint; + } + } + return NULL; +} + + +CHARSET_ID INTL_charset(TDBB tdbb, USHORT ttype, FPTR_STATUS err) { /************************************** * @@ -308,7 +601,7 @@ CHARSET_ID INTL_charset(TDBB tdbb, USHORT ttype, FPTR_VOID err) int INTL_compare(TDBB tdbb, const dsc* pText1, const dsc* pText2, - FPTR_VOID err) + FPTR_STATUS err) { /************************************** * @@ -374,9 +667,9 @@ int INTL_compare(TDBB tdbb, } } - TextType* obj = INTL_texttype_lookup(tdbb, compare_type, err, NULL); + TextType obj = INTL_texttype_lookup(tdbb, compare_type, err, NULL); - return obj->compare(length1, p1, length2, p2); + return obj.compare(length1, p1, length2, p2); } @@ -387,7 +680,7 @@ USHORT INTL_convert_bytes(TDBB tdbb, CHARSET_ID src_type, BYTE * src_ptr, USHORT src_len, - FPTR_VOID err) + FPTR_STATUS err) { /************************************** * @@ -411,8 +704,6 @@ USHORT INTL_convert_bytes(TDBB tdbb, UCHAR *start_dest_ptr; USHORT len; USHORT len2; - CsConvert* cs_obj; - CharSet* from_cs, *to_cs; SSHORT err_code = 0; USHORT err_position; BYTE *tmp_buffer; @@ -443,99 +734,78 @@ USHORT INTL_convert_bytes(TDBB tdbb, if (!len || all_spaces(tdbb, src_type, src_ptr, len, 0)) return (dest_ptr - start_dest_ptr); else - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); } else if (src_len == 0) return (0); else if (src_type == CS_BINARY) - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - gds_arg_gds, - gds_transliteration_failed, - 0); + (*err)(gds_arith_except, gds_arg_gds, gds_transliteration_failed, 0); else /* character sets are known to be different */ { /* Do we know an object from cs1 to cs2? */ - cs_obj = INTL_convert_lookup(tdbb, dest_type, src_type); + CsConvert cs_obj = INTL_convert_lookup(tdbb, dest_type, src_type); if (cs_obj != NULL) { - len = cs_obj->convert(dest_ptr, dest_len, src_ptr, + len = cs_obj.convert(dest_ptr, dest_len, src_ptr, src_len, &err_code, &err_position); if (!err_code || ((err_code == CS_TRUNCATION_ERROR) && all_spaces(tdbb, src_type, src_ptr, src_len, err_position))) return (len); else if (err_code == CS_TRUNCATION_ERROR) - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - 0); + (*err) (gds_arith_except, 0); else - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - gds_arg_gds, - gds_transliteration_failed, - 0); - + (*err) (gds_arith_except, gds_arg_gds, gds_transliteration_failed, 0); } /* Find a CS1 to UNICODE object */ - from_cs = INTL_charset_lookup(tdbb, src_type, NULL); + CharSet from_cs = INTL_charset_lookup(tdbb, src_type, NULL); if (from_cs == NULL) - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - gds_arg_gds, - gds_text_subtype, - gds_arg_number, - (SLONG) src_type, 0); + (*err)(gds_arith_except, gds_arg_gds, gds_text_subtype, gds_arg_number, + (ISC_STATUS) src_type, 0); /* ** allocate a temporary buffer that is large enough. */ - tmp_buffer = (BYTE *) FB_NEW(*getDefaultMemoryPool()) char[(SLONG) src_len * sizeof(UCS2_CHAR)]; + tmp_buffer = (BYTE *) FB_NEW(*tdbb->tdbb_default) char[(SLONG) src_len * sizeof(UCS2_CHAR)]; - cs_obj = from_cs->getConvToUnicode(); + cs_obj = from_cs.getConvToUnicode(); assert(cs_obj != NULL); - len = cs_obj->convert(tmp_buffer, src_len * 2, src_ptr, + len = cs_obj.convert(tmp_buffer, src_len * 2, src_ptr, src_len, &err_code, &err_position); if (err_code && !((err_code == CS_TRUNCATION_ERROR) && all_spaces(tdbb, src_type, src_ptr, src_len, err_position))) { delete [] tmp_buffer; if (err_code == CS_TRUNCATION_ERROR) - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - 0); + (*err) (gds_arith_except, 0); else - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - gds_arg_gds, - gds_transliteration_failed, - 0); + (*err) (gds_arith_except, gds_arg_gds, gds_transliteration_failed, 0); } /* Find a UNICODE to CS2 object */ - to_cs = INTL_charset_lookup(tdbb, dest_type, NULL); + CharSet to_cs = INTL_charset_lookup(tdbb, dest_type, NULL); if (to_cs == NULL) { delete [] tmp_buffer; - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - gds_arg_gds, - gds_text_subtype, - gds_arg_number, - (SLONG) dest_type, 0); + (*err) (gds_arith_except, gds_arg_gds, gds_text_subtype, gds_arg_number, + (ISC_STATUS) dest_type, 0); } - cs_obj = to_cs->getConvFromUnicode(); + cs_obj = to_cs.getConvFromUnicode(); assert(cs_obj != NULL); - len2 = cs_obj->convert(dest_ptr, dest_len, tmp_buffer, + len2 = cs_obj.convert(dest_ptr, dest_len, tmp_buffer, len, &err_code, &err_position); if (err_code && !((err_code == CS_TRUNCATION_ERROR) && - all_spaces(tdbb, CS_UNICODE_UCS2, tmp_buffer, len, err_position))) { + all_spaces(tdbb, CS_UNICODE_UCS2, tmp_buffer, len, err_position))) + { delete [] tmp_buffer; if (err_code == CS_TRUNCATION_ERROR) - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - 0); + (*err) (gds_arith_except, 0); else - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, - gds_arg_gds, - gds_transliteration_failed, - 0); + (*err) (gds_arith_except, gds_arg_gds, gds_transliteration_failed, 0); } delete [] tmp_buffer; @@ -545,7 +815,7 @@ USHORT INTL_convert_bytes(TDBB tdbb, } -CsConvert* INTL_convert_lookup(TDBB tdbb, +CsConvert INTL_convert_lookup(TDBB tdbb, CHARSET_ID to_cs, CHARSET_ID from_cs) { @@ -560,7 +830,6 @@ CsConvert* INTL_convert_lookup(TDBB tdbb, **************************************/ CharSetContainer *charset; - CsConvert* converter; DBB dbb; SET_TDBB(tdbb); @@ -578,58 +847,15 @@ CsConvert* INTL_convert_lookup(TDBB tdbb, assert(from_cs != CS_dynamic); assert(to_cs != CS_dynamic); - charset = internal_charset_container_lookup(tdbb, from_cs, NULL); + charset = CharSetContainer::lookupCharset(tdbb, from_cs, NULL); if (charset == NULL) - return (NULL); + return NULL; - if (charset->findConverter(to_cs, &converter)) - return converter; - - if (to_cs == CS_UNICODE_UCS2) { - converter = charset->getCharSet()->getConvToUnicode(); - } - else if (from_cs == CS_UNICODE_UCS2) { - CharSet* charset2; - charset2 = INTL_charset_lookup(tdbb, to_cs, NULL); - if (charset2 == NULL) - return (NULL); - converter = charset2->getConvFromUnicode(); - } - else { - CsConvertAllocFunc allocFunc; - - allocFunc = INTL_csconvert_alloc_func(from_cs, to_cs); - if (!allocFunc) - allocFunc = (CsConvertAllocFunc) - search_out_alloc_func("FB_CsConvert_lookup", from_cs, to_cs); - if (!allocFunc) - allocFunc = (CsConvertAllocFunc) -// intl_back_compat_alloc_func_lookup(type_csconvert, from_cs, to_cs); - intl_back_compat_alloc_func_lookup(type_csconvert, to_cs, from_cs); - if (!allocFunc) - { - charset->addNullConverter(to_cs); - return NULL; - } - - converter = (*allocFunc)(*dbb->dbb_permanent, from_cs, to_cs); - if (!converter) - { - charset->addNullConverter(to_cs); - return NULL; - } - } - - charset->addConverter(converter); - - assert(converter->getFromCS() == from_cs); - assert(converter->getToCS() == to_cs); - - return (converter); + return charset->lookupConverter(tdbb, to_cs); } -int INTL_convert_string(dsc* to, const dsc* from, FPTR_VOID err) +int INTL_convert_string(dsc* to, const dsc* from, FPTR_STATUS err) { /************************************** * @@ -748,13 +974,12 @@ int INTL_convert_string(dsc* to, const dsc* from, FPTR_VOID err) if (from_fill) /* Make sure remaining characters on From string are spaces */ if (!all_spaces(tdbb, from_cs, q, from_fill, 0)) - reinterpret_cast < void (*) (...) > (*err) (gds_arith_except, 0); + (*err) (gds_arith_except, 0); return 0; } -#ifdef DEV_BUILD int INTL_data(const dsc* pText) { /************************************** @@ -781,9 +1006,7 @@ int INTL_data(const dsc* pText) return FALSE; } -#endif -#ifdef DEV_BUILD int INTL_data_or_binary(const dsc* pText) { /************************************** @@ -798,14 +1021,6 @@ int INTL_data_or_binary(const dsc* pText) return (INTL_data(pText) || (pText->dsc_ttype == ttype_binary)); } -#else -// 11 Sent 2002, Nickolay Samofatov -// Used only in asserts, but let optimizer wipe it out -int INTL_data_or_binary(const dsc* pText) -{ - return TRUE; -} -#endif int INTL_defined_type(TDBB tdbb, ISC_STATUS * status, SSHORT t_type) @@ -828,13 +1043,11 @@ int INTL_defined_type(TDBB tdbb, ISC_STATUS * status, SSHORT t_type) * must return, and not call ERR directly. * **************************************/ - TextType* obj; - SET_TDBB(tdbb); if (status) status[0] = gds_arg_end; - obj = INTL_texttype_lookup(tdbb, t_type, NULL, status); + TextType obj = INTL_texttype_lookup(tdbb, t_type, NULL, status); if (obj == NULL) return FALSE; return TRUE; @@ -842,7 +1055,7 @@ int INTL_defined_type(TDBB tdbb, ISC_STATUS * status, SSHORT t_type) UCS2_CHAR INTL_getch(TDBB tdbb, - TextType* * obj, + TextType* obj, SSHORT t_type, UCHAR ** ptr, USHORT * count) { /************************************** @@ -864,10 +1077,10 @@ UCS2_CHAR INTL_getch(TDBB tdbb, assert(ptr); if (*obj == NULL) { - *obj = INTL_texttype_lookup(tdbb, t_type, (FPTR_VOID) ERR_post, NULL); - assert(*obj); + *obj = INTL_texttype_lookup(tdbb, t_type, ERR_post, NULL); + assert(*obj != NULL); } - used = (*obj)->mbtowc(&wc, *ptr, *count); + used = obj->mbtowc(&wc, *ptr, *count); if (used == -1) return 0; *ptr += used; @@ -887,19 +1100,6 @@ void INTL_init(TDBB tdbb) * Functional description * **************************************/ - /*DBB dbb; - VEC vector; - - SET_TDBB(tdbb); - dbb = tdbb->tdbb_database; - CHECK_DBB(dbb); - - if (!(vector = dbb->dbb_text_objects)) { - vector = dbb->dbb_text_objects = vec::newVector(*dbb->dbb_permanent, 25); - } - if (!(vector = dbb->dbb_charsets)) { - vector = dbb->dbb_charsets = vec::newVector(*dbb->dbb_permanent, 25); - }*/ } @@ -918,7 +1118,6 @@ USHORT INTL_key_length(TDBB tdbb, USHORT idxType, USHORT iLength) * **************************************/ USHORT key_length; - TextType* obj; SSHORT ttype; SET_TDBB(tdbb); @@ -931,8 +1130,8 @@ USHORT INTL_key_length(TDBB tdbb, USHORT idxType, USHORT iLength) if (ttype >= 0 && ttype <= ttype_last_internal) key_length = iLength; else { - obj = INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL); - key_length = obj->key_length(iLength); + TextType obj = INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL); + key_length = obj.key_length(iLength); } /* Validity checks on the computed key_length */ @@ -946,7 +1145,7 @@ USHORT INTL_key_length(TDBB tdbb, USHORT idxType, USHORT iLength) return (key_length); } -static CharSetContainer *internal_charset_container_lookup(TDBB tdbb, SSHORT parm1, ISC_STATUS * status) +CharSet INTL_charset_lookup(TDBB tdbb, SSHORT parm1, ISC_STATUS *status) { /************************************** * @@ -969,90 +1168,15 @@ static CharSetContainer *internal_charset_container_lookup(TDBB tdbb, SSHORT par * NULL - if error & err NULL * **************************************/ - DBB dbb; - CharSetContainer *cs = 0; - USHORT id; - - SET_TDBB(tdbb); - dbb = tdbb->tdbb_database; - - id = TTYPE_TO_CHARSET(parm1); - if (id == CS_dynamic) - id = tdbb->tdbb_attachment->att_charset; - - if (id >= dbb->dbb_charsets.size()) - dbb->dbb_charsets.resize(id + 10); - else - cs = dbb->dbb_charsets[id]; - - // allocate a new character set object if we couldn't find one. - if (!cs) - { - CharSet *newCs = NULL; - CharSetAllocFunc allocFunc; - - allocFunc = INTL_charset_alloc_func(id); - if (!allocFunc) - allocFunc = (CharSetAllocFunc)search_out_alloc_func("FB_CharSet_lookup",id,0); - if (!allocFunc) - allocFunc = (CharSetAllocFunc) - intl_back_compat_alloc_func_lookup(type_charset,id,0); - if (!allocFunc) - return NULL; - - newCs = (*allocFunc)(*dbb->dbb_permanent, id, 0); - if (!newCs) - return NULL; - - cs = FB_NEW(*dbb->dbb_permanent) CharSetContainer(*dbb->dbb_permanent, newCs); - if (!cs) - { - delete newCs; - return NULL; - } - - dbb->dbb_charsets[id] = cs; - } - - assert(cs != NULL); - return cs; -} - -CharSet* INTL_charset_lookup(TDBB tdbb, SSHORT parm1, ISC_STATUS * status) -{ -/************************************** - * - * I N T L _ c h a r s e t _ l o o k u p - * - ************************************** - * - * Functional description - * - * Lookup a character set descriptor. - * - * First, search the appropriate vector that hangs - * off the dbb. If not found, then call the lower - * level lookup routine to allocate it, or return - * null if we don't know about the charset. - * - * Returns: - * *charset - if no errors; - * - if error & err non NULL - * NULL - if error & err NULL - * - **************************************/ - CharSetContainer *cs; - - cs = internal_charset_container_lookup(tdbb, parm1, status); - if (!cs) - return NULL; + CharSetContainer *cs = CharSetContainer::lookupCharset(tdbb, parm1, status); + if (!cs) return NULL; return cs->getCharSet(); } -TextType* INTL_texttype_lookup(TDBB tdbb, +TextType INTL_texttype_lookup(TDBB tdbb, SSHORT parm1, - FPTR_VOID err, + FPTR_STATUS err, ISC_STATUS * status) { /************************************** @@ -1077,9 +1201,7 @@ TextType* INTL_texttype_lookup(TDBB tdbb, * **************************************/ DBB dbb; - TextType *cs_object; CharSetContainer *csc; - USHORT id; SET_TDBB(tdbb); dbb = tdbb->tdbb_database; @@ -1087,36 +1209,10 @@ TextType* INTL_texttype_lookup(TDBB tdbb, if (parm1 == ttype_dynamic) parm1 = MAP_CHARSET_TO_TTYPE(tdbb->tdbb_attachment->att_charset); - csc = internal_charset_container_lookup(tdbb, parm1, status); + csc = CharSetContainer::lookupCharset(tdbb, parm1, status); if (!csc) return NULL; - id = TTYPE_TO_COLLATION(parm1); - - cs_object = csc->collation(id); - - // allocate a new TextType object if needed - if (!cs_object) - { - TextTypeAllocFunc allocFunc; - - allocFunc = INTL_texttype_alloc_func(parm1); - if (!allocFunc) - allocFunc = (TextTypeAllocFunc)search_out_alloc_func("FB_texttype_lookup",parm1,0); - if (!allocFunc) - allocFunc = (TextTypeAllocFunc) - intl_back_compat_alloc_func_lookup(type_texttype,parm1,0); - if (!allocFunc) - return NULL; - - cs_object = (*allocFunc)(*dbb->dbb_permanent,parm1,0); - if (!cs_object) - return NULL; - - csc->setCollation(cs_object, id); - } - - assert(cs_object != NULL); - return (cs_object); + return csc->lookupCollation(tdbb, parm1); } void INTL_pad_spaces(TDBB tdbb, DSC * type, UCHAR * string, USHORT length) @@ -1167,7 +1263,6 @@ USHORT INTL_string_to_key(TDBB tdbb, USHORT outlen; UCHAR buffer[MAX_KEY]; UCHAR pad_char; - TextType* obj; SSHORT ttype; SET_TDBB(tdbb); @@ -1206,7 +1301,7 @@ USHORT INTL_string_to_key(TDBB tdbb, USHORT len = CVT_make_string(pString, ttype, &src, reinterpret_cast(buffer), sizeof(buffer), - (FPTR_VOID) ERR_post); + ERR_post); char* dest = reinterpret_cast(pByte->dsc_address); switch (ttype) { @@ -1225,8 +1320,8 @@ USHORT INTL_string_to_key(TDBB tdbb, outlen = (dest - (const char*)pByte->dsc_address); break; default: - obj = INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL); - outlen = obj->string_to_key(len, + TextType obj = INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL); + outlen = obj.string_to_key(len, reinterpret_cast(const_cast(src)), pByte->dsc_length, reinterpret_cast(dest), @@ -1254,7 +1349,6 @@ int INTL_str_to_upper(TDBB tdbb, DSC * pString) UCHAR *src, *dest; UCHAR buffer[MAX_KEY]; USHORT ttype; - TextType* obj; SET_TDBB(tdbb); @@ -1264,7 +1358,7 @@ int INTL_str_to_upper(TDBB tdbb, DSC * pString) len = CVT_get_string_ptr(pString, &ttype, &src, reinterpret_cast < vary * >(buffer), - sizeof(buffer), (FPTR_VOID) ERR_post); + sizeof(buffer), ERR_post); switch (ttype) { case ttype_binary: /* cannot uppercase binary strings */ @@ -1281,8 +1375,8 @@ int INTL_str_to_upper(TDBB tdbb, DSC * pString) break; default: - obj = INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL); - obj->str_to_upper(len, src, len, src); + TextType obj = INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL); + obj.str_to_upper(len, src, len, src); break; } /* @@ -1305,8 +1399,6 @@ UCHAR INTL_upper(TDBB tdbb, USHORT ttype, UCHAR ch) * Given an input character, convert it to uppercase * **************************************/ - TextType* obj; - SET_TDBB(tdbb); @@ -1321,8 +1413,8 @@ UCHAR INTL_upper(TDBB tdbb, USHORT ttype, UCHAR ch) return (UPPER7(ch)); default: - obj = INTL_texttype_lookup(tdbb, ttype, (FPTR_VOID) ERR_post, NULL); - return obj->to_upper(ch); + TextType obj = INTL_texttype_lookup(tdbb, ttype, ERR_post, NULL); + return obj.to_upper(ch); } } @@ -1350,7 +1442,7 @@ static bool all_spaces( assert(ptr != NULL); - CharSet* obj = INTL_charset_lookup(tdbb, charset, NULL); + CharSet obj = INTL_charset_lookup(tdbb, charset, NULL); assert(obj != NULL); @@ -1362,11 +1454,11 @@ static bool all_spaces( // Single-octet character sets are optimized here - if (obj->getSpaceLength() == 1) { + if (obj.getSpaceLength() == 1) { const BYTE* p = &ptr[offset]; const BYTE* const end = &ptr[len]; while (p < end) { - if (*p++ != *obj->getSpace()) + if (*p++ != *obj.getSpace()) return false; } return true; @@ -1374,10 +1466,10 @@ static bool all_spaces( else { const BYTE* p = &ptr[offset]; const BYTE* const end = &ptr[len]; - const unsigned char* space = obj->getSpace(); - const unsigned char* const end_space = &space[obj->getSpaceLength()]; + const unsigned char* space = obj.getSpace(); + const unsigned char* const end_space = &space[obj.getSpaceLength()]; while (p < end) { - space = obj->getSpace(); + space = obj.getSpace(); while (p < end && space < end_space) { if (*p++ != *space++) return false; @@ -1387,23 +1479,7 @@ static bool all_spaces( } } -#ifdef NOT_USED_OR_REPLACED -static USHORT internal_keylength(TextType* obj, USHORT iLength) -{ -/************************************** - * - * i n t e r n a l _ k e y l e n g t h - * - ************************************** - * - * Functional description - * - **************************************/ - - return (iLength); -} - -static USHORT nc_to_wc(CsConvert* obj, UCS2_CHAR * pWide, USHORT nWide, /* byte count */ +static USHORT nc_to_wc(CSCONVERT obj, UCS2_CHAR * pWide, USHORT nWide, /* byte count */ UCHAR * pNarrow, USHORT nNarrow, /* byte count */ SSHORT * err_code, USHORT * err_position) { @@ -1443,305 +1519,24 @@ static USHORT nc_to_wc(CsConvert* obj, UCS2_CHAR * pWide, USHORT nWide, /* byte return ((pWide - pStart) * sizeof(*pWide)); } -#endif -static void pad_spaces(TDBB tdbb, CHARSET_ID charset, BYTE * ptr, USHORT len) -{ /* byte count */ +static USHORT wc_to_wc(CSCONVERT obj, WCHAR * pDest, USHORT nDest, /* byte count */ + WCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) +{ /************************************** * - * p a d _ s p a c e s + * w c _ t o _ w c * ************************************** * * Functional description - * Pad a buffer with the character set defined space character. - * - **************************************/ - CharSet* obj; - BYTE *end; - const unsigned char *space, *end_space; - - SET_TDBB(tdbb); - - assert(ptr != NULL); - - obj = INTL_charset_lookup(tdbb, charset, NULL); + * + *************************************/ + WCHAR *pStart; + WCHAR *pStart_src; assert(obj != NULL); - -/* Single-octet character sets are optimized here */ - if (obj->getSpaceLength() == 1) { - end = &ptr[len]; - while (ptr < end) - *ptr++ = *obj->getSpace(); - } - else { - end = &ptr[len]; - space = obj->getSpace(); - end_space = &space[obj->getSpaceLength()]; - while (ptr < end) { - space = obj->getSpace(); - while (ptr < end && space < end_space) { - *ptr++ = *space++; - } - /* This assert is checking that we didn't have a buffer-end - * in the middle of a space character - */ - assert(!(ptr == end) || (space == end_space)); - } - } -} - -#ifdef NOT_USED_OR_REPLACED -#ifdef DEV_BUILD - -/* - * Utility routines designed to be called from the debugger to - * print buffers, pointers, etc. which may contain text that - * the debugger doesn't consider visible. - */ -static void dump_hex(UCHAR * p, USHORT len) -{ -/************************************** - * - * d u m p _ h e x - * - ************************************** - * - * Functional description - * - *************************************/ - - while (len--) - ib_printf("%02X ", *p++); - ib_printf("\n"); -} - - -static void dump_latin(UCHAR * p, USHORT len) -{ -/************************************** - * - * d u m p _ l a t i n - * - ************************************** - * - * Functional description - * - *************************************/ - - while (len--) - if (isprintable(*p)) - ib_printf("%c", *p++); - else - ib_printf("\0x%02X", *p++); - ib_printf("\n"); -} -#endif -#endif - -unsigned short TextTypeNC::to_wc(UCS2_CHAR *pWideUC, - unsigned short nWide, - unsigned char *pNarrow, - unsigned short nNarrow, - short *err_code, - unsigned short *err_position) -/************************************** - * - * TextTypeNC::to_wc - * - ************************************** - * - * Functional description - * - **************************************/ -{ - UCS2_CHAR *pStart, *pWide = pWideUC; - UCHAR *pNarrowStart; - - assert((pNarrow != NULL) || (pWide == NULL)); - assert(err_code != NULL); - assert(err_position != NULL); - - *err_code = 0; - if (pWide == NULL) - return (sizeof(UCS2_CHAR) * nNarrow); /* all cases */ - pStart = pWide; - pNarrowStart = pNarrow; - while (nWide-- > 1 && nNarrow) { - /* YYY - Byte order issues here */ - *pWide++ = (UCS2_CHAR) * pNarrow++; - nWide--; - nNarrow--; - } - if (!*err_code && nNarrow) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = (pNarrow - pNarrowStart) * sizeof(*pNarrow); - - return ((pWide - pStart) * sizeof(*pWide)); -} - -unsigned short TextTypeNC::contains(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) -{ - return EVL_nc_contains(a,this,b,c,d,e); -} - -unsigned short TextTypeNC::like(TDBB a, unsigned char *b, - short c, - unsigned char *d, - short e, - short f) -{ - return EVL_nc_like(a,this,b,c,d,e,f); -} - -unsigned short TextTypeNC::matches(TDBB a, unsigned char *b, short c, - unsigned char *d, short e) -{ - return EVL_nc_matches(a,this,b,c,d,e); -} - -unsigned short TextTypeNC::sleuth_check(TDBB a, unsigned short b, - unsigned char *c, - unsigned short d, - unsigned char *e, - unsigned short f) -{ - return EVL_nc_sleuth_check(a,this,b,c,d,e,f); -} - -unsigned short TextTypeNC::sleuth_merge(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e, - unsigned char *f, - unsigned short g) -{ - return EVL_nc_sleuth_merge(a,this,b,c,d,e,f,g); -} - -unsigned short TextTypeNC::mbtowc(UCS2_CHAR *wc, unsigned char *ptr, unsigned short count) -/************************************** - * - * i n t e r n a l _ n c _ m b t o w c - * - ************************************** - * - * Functional description - * Get the next character from the multibyte - * input stream. - * Narrow character version. - * Returns: - * Count of bytes consumed from the input stream. - * - **************************************/ -{ - assert(ptr); - - if (count >= 1) { - if (wc) - *wc = *ptr; - return 1; - } - if (wc) - *wc = 0; - return (unsigned short)-1; /* No more characters */ -} - -unsigned short TextTypeMB::contains(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) -{ - return EVL_mb_contains(a,this,b,c,d,e); -} - -unsigned short TextTypeMB::like(TDBB a, unsigned char *b, - short c, - unsigned char *d, - short e, - short f) -{ - return EVL_mb_like(a,this,b,c,d,e,f); -} - -unsigned short TextTypeMB::matches(TDBB a, unsigned char *b, short c, - unsigned char *d, short e) -{ - return EVL_mb_matches(a,this,b,c,d,e); -} - -unsigned short TextTypeMB::sleuth_check(TDBB a, unsigned short b, - unsigned char *c, - unsigned short d, - unsigned char *e, - unsigned short f) -{ - return EVL_mb_sleuth_check(a,this,b,c,d,e,f); -} - -unsigned short TextTypeMB::sleuth_merge(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e, - unsigned char *f, - unsigned short g) -{ - return EVL_mb_sleuth_merge(a,this,b,c,d,e,f,g); -} - -unsigned short TextTypeMB::mbtowc(UCS2_CHAR *wc, unsigned char *ptr, unsigned short count) -{ -/************************************** - * - * TextTypeMB::mbtowc - * - ************************************** - * - * Functional description - * Get the next character from the multibyte - * input stream. - * Multibyte version character version. - * Returns: - * Count of bytes consumed from the input stream. - * - **************************************/ - - assert(ptr); - - if (count >= 2) { - if (wc) - *wc = *(UCS2_CHAR *) ptr; - return 2; - } - if (wc) - *wc = 0; - return (unsigned short)-1; /* No more characters */ -} - -unsigned short TextTypeWC::to_wc(UCS2_CHAR *pDestUC, - unsigned short nDest, - unsigned char *pSrcUC, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * TextTypeWC::to_wc - * - ************************************** - * - * Functional description - * - *************************************/ - UCS2_CHAR *pStart, *pDest = pDestUC; - UCS2_CHAR *pStart_src, *pSrc = (UCS2_CHAR*)pSrcUC; - assert((pSrc != NULL) || (pDest == NULL)); assert(err_code != NULL); assert(err_position != NULL); @@ -1765,634 +1560,48 @@ unsigned short TextTypeWC::to_wc(UCS2_CHAR *pDestUC, return ((pDest - pStart) * sizeof(*pDest)); } -unsigned short TextTypeWC::contains(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) -{ - return EVL_wc_contains(a,this,(UCS2_CHAR*)b,c,(UCS2_CHAR*)d,e); -} - -unsigned short TextTypeWC::like(TDBB a, unsigned char *b, - short c, - unsigned char *d, - short e, - short f) -{ - return EVL_wc_like(a,this,(UCS2_CHAR*)b,c,(UCS2_CHAR*)d,e,f); -} - -unsigned short TextTypeWC::matches(TDBB a, unsigned char *b, short c, - unsigned char *d, short e) -{ - return EVL_wc_matches(a,this,(UCS2_CHAR*)b,c,(UCS2_CHAR*)d,e); -} - -unsigned short TextTypeWC::sleuth_check(TDBB a, unsigned short b, - unsigned char *c, - unsigned short d, - unsigned char *e, - unsigned short f) -{ - return EVL_wc_sleuth_check(a,this,b,(UCS2_CHAR*)c,d,(UCS2_CHAR*)e,f); -} - -unsigned short TextTypeWC::sleuth_merge(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e, - unsigned char *f, - unsigned short g) -{ - return EVL_wc_sleuth_merge(a,this,(UCS2_CHAR*)b,c,(UCS2_CHAR*)d,e,(UCS2_CHAR*)f,g); -} - -unsigned short TextTypeWC::mbtowc(UCS2_CHAR *wc, unsigned char *ptr, unsigned short count) -{ +static void pad_spaces(TDBB tdbb, CHARSET_ID charset, BYTE * ptr, USHORT len) +{ /* byte count */ /************************************** * - * TextTypeWC::mbtowc + * p a d _ s p a c e s * ************************************** * * Functional description - * Get the next character from the multibyte - * input stream. - * Wide character version. - * Returns: - * Count of bytes consumed from the input stream. - * + * Pad a buffer with the character set defined space character. + * **************************************/ + BYTE *end; + const unsigned char *space, *end_space; - assert(ptr); + SET_TDBB(tdbb); - if (count >= 2) { - if (wc) - *wc = *(UCS2_CHAR *) ptr; - return 2; + assert(ptr != NULL); + + CharSet obj = INTL_charset_lookup(tdbb, charset, NULL); + + assert(obj != NULL); + +/* Single-octet character sets are optimized here */ + if (obj.getSpaceLength() == 1) { + end = &ptr[len]; + while (ptr < end) + *ptr++ = *obj.getSpace(); } - if (wc) - *wc = 0; - return (unsigned short)-1; /* No more characters */ -} - - -//=============================================================================== -//=============================================================================== -//=============================================================================== -// Code to handle loading international charset plugins -// in the new c++ OO format. - -static const char *INTL_PLUGIN_DIR = "intl"; -static PluginManager intlPlugins; -static bool loaded = false; - -static void* search_out_alloc_func(const char *sym, CHARSET_ID p1, CHARSET_ID p2) -{ - typedef void* (*lookupFuncType)(CHARSET_ID,CHARSET_ID); - - void* result = 0; - lookupFuncType lookupFunc; - Firebird::string entryPoint(sym); - - if (!loaded) - { - intlPlugins.addSearchPath(INTL_PLUGIN_DIR); - intlPlugins.addIgnoreModule(INTL_MODULE1); - intlPlugins.addIgnoreModule(INTL_MODULE2); - intlPlugins.loadAllPlugins(); - loaded = true; - } - - for(PluginManager::iterator itr = intlPlugins.begin(); - result == 0 && itr != intlPlugins.end(); ++itr) - { - lookupFunc = (lookupFuncType)(*itr).lookupSymbol(entryPoint); - if (!lookupFunc) - continue; - result = (*lookupFunc)(p1,p2); - } - return result; -} - -//=============================================================================== -//=============================================================================== -//=============================================================================== -// This code handles backwards compatibility with the old internation -// character set plugin format. - -// We need all the structure definitions from the old interface -#define INTL_ENGINE_INTERNAL -#include "../jrd/intlobj.h" - -// storage for the loadable modules -static PluginManager intlBCPlugins; -static bool bcLoaded = false; - -class CsConvert_BC : public CsConvert -{ -public: - CsConvert_BC(struct csconvert *csv, bool deleteMemory) : - CsConvert( - csv->csconvert_id, - (const char*)csv->csconvert_name, - csv->csconvert_from, - csv->csconvert_to), - cnvt(csv), - deleteOnDestruct(deleteMemory) - {} - virtual ~CsConvert_BC() { if (deleteOnDestruct) delete cnvt; } - - unsigned short convert(unsigned char *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { - assert(cnvt != NULL); - return (*(reinterpret_cast(cnvt->csconvert_convert))) - (cnvt,a,b,c,d,e,f); - } - -private: - struct csconvert *cnvt; - bool deleteOnDestruct; -}; - -class CharSet_BC : public CharSet -{ -public: - CharSet_BC(MemoryPool &p, struct charset *csStruct) : - CharSet( - csStruct->charset_id, - (const char*)csStruct->charset_name, - csStruct->charset_min_bytes_per_char, - csStruct->charset_max_bytes_per_char, - csStruct->charset_space_length, - (char*)csStruct->charset_space_character), - cs(csStruct) - { - charset_to_unicode = FB_NEW(p) CsConvert_BC(&cs->charset_to_unicode, false); - charset_from_unicode = FB_NEW(p) CsConvert_BC(&cs->charset_from_unicode, false); - } - - ~CharSet_BC() { delete cs; } -private: - struct charset *cs; -}; - -template -class TextType_BC : public T -{ -public: - TextType_BC(struct texttype *textt) : - T( - textt->texttype_type, - (char*)textt->texttype_name, - textt->texttype_character_set, - textt->texttype_country, - textt->texttype_bytes_per_char), - tt(textt) - {} - - unsigned short key_length(unsigned short a) - { - assert(tt); - assert(tt->texttype_fn_key_length); - return (*(reinterpret_cast - (tt->texttype_fn_key_length)))(tt,a); - } - - unsigned short string_to_key(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { - assert(tt); - assert(tt->texttype_fn_string_to_key); - return (*(reinterpret_cast - - (tt->texttype_fn_string_to_key))) - (tt,a,b,c,d,e); - } - - short compare(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { - assert(tt); - assert(tt->texttype_fn_compare); - return (*(reinterpret_cast - - (tt->texttype_fn_compare)))(tt,a,b,c,d); - } - - unsigned short to_upper(unsigned short a) - { - assert(tt); - assert(tt->texttype_fn_to_upper); - return (*(reinterpret_cast - - (tt->texttype_fn_to_upper)))(tt,a); - } - - unsigned short to_lower(unsigned short a) - { - assert(tt); - assert(tt->texttype_fn_to_lower); - return (*(reinterpret_cast - - (tt->texttype_fn_to_lower)))(tt,a); - } - - short str_to_upper(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { - assert(tt); - assert(tt->texttype_fn_str_to_upper); - return (*(reinterpret_cast - - (tt->texttype_fn_str_to_upper))) - (tt,a,b,c,d); - } - - unsigned short to_wc(UCS2_CHAR *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { - assert(tt); - assert(tt->texttype_fn_to_wc); - return (*(reinterpret_cast - - (tt->texttype_fn_to_wc))) - (tt,a,b,c,d,e,f); - } - - unsigned short mbtowc(UCS2_CHAR *a, unsigned char *b, unsigned short c) - { - assert(tt); - if (!tt->texttype_fn_mbtowc) - return T::mbtowc(a,b,c); - return (*(reinterpret_cast< - USHORT (*)(TEXTTYPE, UCS2_CHAR*, UCHAR*, USHORT)> - (tt->texttype_fn_mbtowc)))(tt,a,b,c); - } - - unsigned short contains(TDBB a, unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { - assert(tt); - if (!tt->texttype_fn_contains) - return T::contains(a,b,c,d,e); - return (*(reinterpret_cast< - USHORT (*)(TDBB,TEXTTYPE,UCHAR*,USHORT,UCHAR*,USHORT)> - (tt->texttype_fn_contains))) - (a,tt,b,c,d,e); - } - - unsigned short like(TDBB tdbb, unsigned char *a, - short b, - unsigned char *c, - short d, - short e) - { - assert(tt); - if (!tt->texttype_fn_like) - return T::like(tdbb,a,b,c,d,e); - else - return (*(reinterpret_cast< - USHORT(*)(TDBB,TEXTTYPE,UCHAR*,short,UCHAR*,short,short)> - (tt->texttype_fn_like)))(tdbb,tt,a,b,c,d,e); - } - - unsigned short matches(TDBB tdbb, unsigned char *a, short b, - unsigned char *c, short d) - { - assert(tt); - if (!tt->texttype_fn_matches) - return T::matches(tdbb,a,b,c,d); - return (*(reinterpret_cast< - USHORT (*)(TDBB,TEXTTYPE,UCHAR*,short,UCHAR*,short)> - (tt->texttype_fn_matches))) - (tdbb,tt,a,b,c,d); - } - - unsigned short sleuth_check(TDBB tdbb, unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { - assert(tt); - if (!tt->texttype_fn_sleuth_check) - return T::sleuth_check(tdbb,a,b,c,d,e); - return (*(reinterpret_cast< - USHORT(*)(TDBB,TEXTTYPE,USHORT,UCHAR*,USHORT,UCHAR*,USHORT)> - (tt->texttype_fn_sleuth_check))) - (tdbb,tt,a,b,c,d,e); - } - - unsigned short sleuth_merge(TDBB tdbb, unsigned char *a, - unsigned short b, - unsigned char *c, - unsigned short d, - unsigned char *e, - unsigned short f) - { - assert(tt); - if (!tt->texttype_fn_sleuth_merge) - return T::sleuth_merge(tdbb,a,b,c,d,e,f); - return (*(reinterpret_cast< - USHORT(*)(TDBB,TEXTTYPE,UCHAR*,USHORT,UCHAR*,USHORT,UCHAR*,USHORT)> - (tt->texttype_fn_sleuth_merge))) - (tdbb,tt,a,b,c,d,e,f); - } - -private: - struct texttype *tt; -}; - -static void* intl_back_compat_obj_init_lookup( - USHORT type, - SSHORT parm1, - SSHORT parm2) -{ -/************************************** - * - * intl_back_compat_alloc_func_lookup - * - ************************************** - * - * Functional description - * Find the allocator function for the requested international - * character set using the obsolete c/IB/FB 6.0 interface. - * Search algorithm is: - * Look in intllib - * Look in intllib2 - * Look for a normal UDF entry - * Abort with an error. - * - * Returns: - * FALSE - no errors - * TRUE - error occurred, and parameter was NULL; - * - error occurred, and parameter non-NULL; - * - * - ***************************************/ - USHORT (*function)(); - - if (!bcLoaded) - { - intlBCPlugins.addSearchPath(INTL_PLUGIN_DIR); - bcLoaded = true; - } - - PluginManager::Plugin intlMod1 = intlBCPlugins.findPlugin(INTL_MODULE1); - PluginManager::Plugin intlMod2 = intlBCPlugins.findPlugin(INTL_MODULE2); - - USHORT(*lookup_fn) (USHORT, FPTR_SHORT *, SSHORT, SSHORT); - - INTL_TRACE(("INTL: looking for obj %d ttype %d\n", objtype, parm1)); - - function = NULL; - -#ifdef INTL_BUILTIN - if (LD_lookup(type, &function, parm1, parm2) != 0) - function = NULL; -#else - /* Look for an InterBase supplied object to implement the text type */ - /* The flu.c uses searchpath which expects a file name not a path */ - INTL_TRACE(("INTL: trying %s %s\n", INTL_MODULE1, INTL_LOOKUP_ENTRY1)); - Firebird::string tempStr(INTL_LOOKUP_ENTRY1); - if ( intlMod1 && (lookup_fn = (USHORT(*)(USHORT, USHORT(**)(), short, short)) - (intlMod1.lookupSymbol(tempStr))) ) { - INTL_TRACE(("INTL: calling lookup %s %s\n", INTL_MODULE1, - INTL_LOOKUP_ENTRY1)); - if ((*lookup_fn) (type, &function, parm1, parm2) != 0) { - function = NULL; - } - else - { - return (void*) function; + else { + end = &ptr[len]; + space = obj.getSpace(); + end_space = &space[obj.getSpaceLength()]; + while (ptr < end) { + space = obj.getSpace(); + while (ptr < end && space < end_space) { + *ptr++ = *space++; + } + /* This assert is checking that we didn't have a buffer-end + * in the middle of a space character + */ + assert(!(ptr == end) || (space == end_space)); } } -#endif - -/* Still not found, check the set of supplimental international objects */ -#ifdef INTL_BUILTIN - if (LD2_lookup(type, &function, parm1, parm2) != 0) - function = NULL -#else - /* Look for an InterBase supplied object to implement the text type */ - /* The flu.c uses searchpath which expects a file name not a path */ - INTL_TRACE(("INTL: trying %s %s\n", INTL_MODULE2, INTL_LOOKUP_ENTRY2)); - tempStr = INTL_LOOKUP_ENTRY2; - if ( intlMod2 && (lookup_fn = (USHORT(*)(USHORT, USHORT(**)(), short, short)) - (intlMod2.lookupSymbol(tempStr))) ) { - INTL_TRACE(("INTL: calling lookup %s %s\n", INTL_MODULE2, - INTL_LOOKUP_ENTRY2)); - if ((*lookup_fn) (type, &function, parm1, parm2) != 0) { - function = NULL; - } - else - { - return (void*) function; - } - } -#endif - -/* Still not found, check if there is a UDF in the database defined the right way */ - FUN function_block; - USHORT argcount; - char entry[48]; - -/* EKU: need a replacement for snprintf for systems like SINIX-Z!!! */ - switch (type) { - case type_texttype: -#ifdef HAVE_SNPRINTF - snprintf(entry, sizeof(entry), INTL_USER_ENTRY, parm1); -#else - sprintf(entry, INTL_USER_ENTRY, parm1); -#endif - argcount = 2; - break; - case type_charset: -#ifdef HAVE_SNPRINTF - snprintf(entry, sizeof(entry), "USER_CHARSET_%03d", parm1); -#else - sprintf(entry, "USER_CHARSET_%03d", parm1); -#endif - argcount = 2; - break; - case type_csconvert: -#ifdef HAVE_SNPRINTF - snprintf(entry, sizeof(entry), "USER_TRANSLATE_%03d_%03d", parm1, - parm2); -#else - sprintf(entry, "USER_TRANSLATE_%03d_%03d", parm1, - parm2); -#endif - argcount = 3; - break; - default: - BUGCHECK(1); - break; - } - INTL_TRACE(("INTL: trying user fn %s\n", entry)); - if ( (function_block = FUN_lookup_function((TEXT*)entry, false)) ) { - INTL_TRACE(("INTL: found a user fn, validating\n")); - if ((function_block->fun_count == argcount) && - (function_block->fun_args == argcount) && - (function_block->fun_return_arg == 0) && - (function_block->fun_entrypoint != NULL) && - (function_block->fun_rpt[0].fun_mechanism == FUN_value) && - (function_block->fun_rpt[0].fun_desc.dsc_dtype == dtype_short) - && (function_block->fun_rpt[1].fun_desc.dsc_dtype == - dtype_short) - && (function_block->fun_rpt[argcount - 1]. - fun_desc.dsc_dtype == dtype_short) - && (function_block->fun_rpt[argcount].fun_mechanism == - FUN_reference) - && (function_block->fun_rpt[argcount].fun_desc.dsc_dtype == - dtype_text)) - { - function = (FPTR_SHORT) function_block->fun_entrypoint; - return (void*) function; - } - } - return NULL; } - -static CharSet *BC_CharSetAllocFunc(MemoryPool &p, SSHORT cs_id, SSHORT unused) -{ - typedef USHORT (*CSInitFunc)(CHARSET, SSHORT, SSHORT); - CSInitFunc csInitFunc; - - csInitFunc = (CSInitFunc) intl_back_compat_obj_init_lookup(type_charset, cs_id, unused); - assert(csInitFunc != 0); - CHARSET cs = FB_NEW(p) charset; - memset(cs, 0, sizeof(charset)); - - if (0 != (*csInitFunc)(cs, cs_id, unused)) - { - delete cs; - return 0; - } - - CharSet *result = 0; - try - { - result = FB_NEW(p) CharSet_BC(p, cs); - } - catch(std::exception&) - { - delete cs; - throw; - } - - return result; -} - -static CsConvert *BC_CsConvertAllocFunc(MemoryPool &p, SSHORT from_id, SSHORT to_id) -{ - typedef USHORT (*CVTInitFunc)(CSCONVERT, SSHORT, SSHORT); - CVTInitFunc cvtInitFunc; - - //cvtInitFunc = (CVTInitFunc) intl_back_compat_obj_init_lookup(type_csconvert, from_id, to_id); - cvtInitFunc = (CVTInitFunc) intl_back_compat_obj_init_lookup(type_csconvert, to_id, from_id); - assert(cvtInitFunc != 0); - CSCONVERT cvt = FB_NEW(p) csconvert; - memset(cvt, 0, sizeof(csconvert)); - - //if (0 != (*cvtInitFunc)(cvt, from_id, to_id)) - if (0 != (*cvtInitFunc)(cvt, to_id, from_id)) - { - delete cvt; - return 0; - } - - CsConvert *result = 0; - try - { - result = FB_NEW(p) CsConvert_BC(cvt, true); - } - catch(std::exception&) - { - delete cvt; - throw; - } - - return result; -} - -static TextType *BC_TextTypeAllocFunc(MemoryPool &p, SSHORT tt_id, SSHORT unused) -{ - typedef USHORT (*TTInitFunc)(TEXTTYPE, SSHORT, SSHORT); - TTInitFunc ttInitFunc; - - ttInitFunc = (TTInitFunc) intl_back_compat_obj_init_lookup(type_texttype, tt_id, unused); - assert(ttInitFunc != 0); - TEXTTYPE tt = FB_NEW(p) texttype; - memset(tt, 0, sizeof(texttype)); - - if (0 != (*ttInitFunc)(tt, tt_id, unused)) - { - delete tt; - return 0; - } - - TextType *result = 0; - try - { - if (tt->texttype_bytes_per_char == 1 && tt->texttype_fn_to_wc == NULL) - result = FB_NEW(p) TextType_BC(tt); - else if (tt->texttype_bytes_per_char == 2 && tt->texttype_fn_to_wc == NULL) - result = FB_NEW(p) TextType_BC(tt); - else if (tt->texttype_fn_to_wc != NULL) - result = FB_NEW(p) TextType_BC(tt); - else - BUGCHECK(1); - } - catch(std::exception&) - { - delete tt; - throw; - } - - return result; -} - -static void* intl_back_compat_alloc_func_lookup( - USHORT type, - CHARSET_ID parm1, - CHARSET_ID parm2) -{ - if (NULL != intl_back_compat_obj_init_lookup(type,parm1,parm2)) - { - switch(type) - { - case type_charset: - return (void*)BC_CharSetAllocFunc; - case type_texttype: - return (void*)BC_TextTypeAllocFunc; - case type_csconvert: - return (void*)BC_CsConvertAllocFunc; - default: - BUGCHECK(1); - } - } - - return NULL; -} - diff --git a/src/jrd/intl_builtin.cpp b/src/jrd/intl_builtin.cpp index 4e6e9a7905..1e646ef304 100644 --- a/src/jrd/intl_builtin.cpp +++ b/src/jrd/intl_builtin.cpp @@ -6,941 +6,41 @@ #include "../jrd/intl.h" #include "../intl/country_codes.h" #include "../jrd/gdsassert.h" +#include "../jrd/jrd.h" +#include "../jrd/err_proto.h" +#include "../intl/charsets.h" -// types unsed internal to this file +#define TEXTTYPE_RETURN return (0) + +#define FAMILY_INTERNAL(id_number, name, charset, country) \ + cache->texttype_version = 40; \ + cache->texttype_type = (id_number); \ + cache->texttype_character_set = (charset); \ + cache->texttype_country = (country); \ + cache->texttype_bytes_per_char = 1; \ + cache->texttype_fn_init = (FPTR_SHORT) (name); \ + cache->texttype_fn_key_length = (FPTR_SHORT) internal_keylength; \ + cache->texttype_fn_string_to_key = (FPTR_SHORT) internal_string_to_key; \ + cache->texttype_fn_compare = (FPTR_short) internal_compare; \ + cache->texttype_fn_to_upper = (FPTR_SHORT) internal_ch_to_upper; \ + cache->texttype_fn_to_lower = (FPTR_SHORT) internal_ch_to_lower; \ + cache->texttype_fn_str_to_upper = (FPTR_short) internal_str_to_upper; \ + cache->texttype_fn_mbtowc = (FPTR_short) INTL_builtin_nc_mbtowc; \ + cache->texttype_collation_table = (BYTE *) " "; \ + cache->texttype_toupper_table = NULL; \ + cache->texttype_tolower_table = NULL; \ + cache->texttype_compress_table = NULL; \ + cache->texttype_expand_table = NULL; \ + cache->texttype_name = const_cast(POSIX); + + + +typedef unsigned char FILECHAR; +typedef USHORT UNICODE; + typedef USHORT fss_wchar_t; typedef int fss_size_t; -typedef unsigned char FILECHAR; - -// internal functions -static fss_size_t fss_wctomb(UCHAR *, fss_wchar_t); -static fss_size_t fss_mbtowc(fss_wchar_t *, UCHAR *, fss_size_t); -static unsigned short cvt_utffss_to_ascii(UCHAR *, USHORT, UCHAR *, USHORT, - short*, USHORT *); -static USHORT internal_string_to_key(USHORT, UCHAR *, USHORT, - UCHAR *, USHORT, UCHAR); -static SSHORT internal_compare(USHORT, UCHAR *, USHORT, UCHAR *, UCHAR); -static SSHORT internal_str_to_upper(USHORT, UCHAR *, USHORT, - UCHAR *); -static unsigned short internal_unicode_to_fss( - unsigned char *, - unsigned short, - unsigned char *, - unsigned short , - short *, - unsigned short *); -static USHORT internal_fss_to_unicode ( - UCS2_CHAR*, - USHORT, - NCHAR*, - USHORT, - SSHORT*, - USHORT*); -/********************************************************************************/ -// This module contains the code to handle the default international character -// sets. As such it defines its own subclasses of the international interface. -// The classes are defined in this section and implemented twords the end of the -// file. - - -class TextType_Binary : public TextTypeNC -{ -public: - static TextType *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) TextType_Binary; } - TextType_Binary() : TextTypeNC(ttype_binary, "C.OCTETS", CS_BINARY, CC_C, 1) - {} - - unsigned short key_length(unsigned short len) - { return len; } - unsigned short string_to_key(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { return internal_string_to_key(a,b,c,d,e,'\0'); } - - short compare(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_compare(a,b,c,d,'\0'); } - - unsigned short to_upper(unsigned short ch) - { return (ch); } - - unsigned short to_lower(unsigned short ch) - { return (ch); } - - short str_to_upper(unsigned short, - unsigned char *, - unsigned short, - unsigned char *); -}; - -class TextType_UFSS : public TextTypeMB -{ -public: - static TextType *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) TextType_UFSS; } - TextType_UFSS() : TextTypeMB(ttype_unicode_fss, "C.UNICODE_FSS", CS_UNICODE_FSS, CC_C, 3) - {} - - unsigned short key_length(unsigned short len) - { return len; } - unsigned short string_to_key(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { return internal_string_to_key(a,b,c,d,e,' '); } - - short compare(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_compare(a,b,c,d,' '); } - - unsigned short to_upper(unsigned short ch) - { return (UPPER7(ch)); } - - unsigned short to_lower(unsigned short ch) - { return ((((ch) >= 'A') && ((ch) < 'Z')) ? ((ch) - 'A' + 'a') : (ch)); } - - short str_to_upper(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_str_to_upper(a,b,c,d); } - - unsigned short to_wc(UCS2_CHAR *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { return internal_fss_to_unicode(a,b,c,d,e,f); } - - unsigned short mbtowc(UCS2_CHAR *wc, unsigned char *p, unsigned short n) - { return fss_mbtowc(wc, p, n); } -}; - -class TextType_ASCII : public TextTypeNC -{ -public: - static TextType *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) TextType_ASCII; } - TextType_ASCII() : TextTypeNC(ttype_ascii, "C.ASCII", CS_ASCII, CC_C, 1) - {} - - unsigned short key_length(unsigned short len) - { return len; } - unsigned short string_to_key(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { return internal_string_to_key(a,b,c,d,e,' '); } - - short compare(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_compare(a,b,c,d,' '); } - - unsigned short to_upper(unsigned short ch) - { return (UPPER7(ch)); } - - unsigned short to_lower(unsigned short ch) - { return ((((ch) >= 'A') && ((ch) < 'Z')) ? ((ch) - 'A' + 'a') : (ch)); } - - short str_to_upper(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_str_to_upper(a,b,c,d); } -}; - -class TextType_None : public TextTypeNC -{ -public: - static TextType *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) TextType_None; } - TextType_None() : TextTypeNC(ttype_none, "C", CS_NONE, CC_C, 1) - {} - - unsigned short key_length(unsigned short len) - { return len; } - unsigned short string_to_key(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d, - unsigned short e) - { return internal_string_to_key(a,b,c,d,e,' '); } - - short compare(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_compare(a,b,c,d,' '); } - - unsigned short to_upper(unsigned short ch) - { return (UPPER7(ch)); } - - unsigned short to_lower(unsigned short ch) - { return ((((ch) >= 'A') && ((ch) < 'Z')) ? ((ch) - 'A' + 'a') : (ch)); } - - short str_to_upper(unsigned short a, - unsigned char *b, - unsigned short c, - unsigned char *d) - { return internal_str_to_upper(a,b,c,d); } -}; - -class CsConvert_ASCII_UFSS : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_ASCII_UFSS; } - CsConvert_ASCII_UFSS() : CsConvert(0, "DIRECT", CS_ASCII, CS_UNICODE_FSS) - {} - - unsigned short convert(unsigned char *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { return cvt_utffss_to_ascii(a,b,c,d,e,f); } -}; - -class CsConvert_UFSS_ASCII : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_UFSS_ASCII; } - CsConvert_UFSS_ASCII() : CsConvert(0, "DIRECT", CS_UNICODE_FSS, CS_ASCII) - {} - unsigned short convert(unsigned char *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { return cvt_utffss_to_ascii(a,b,c,d,e,f); } -}; - -class CsConvert_UFSS_None : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_UFSS_None; } - CsConvert_UFSS_None() : CsConvert(0, "DIRECT", CS_UNICODE_FSS, CS_NONE) - {} - unsigned short convert(unsigned char *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { return cvt_utffss_to_ascii(a,b,c,d,e,f); } -}; - -class CsConvert_None_Unicode : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_None_Unicode; } - CsConvert_None_Unicode() : CsConvert(0, "DIRECT", CS_NONE, CS_UNICODE_UCS2) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CsConvert_Unicode_None : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_Unicode_None; } - CsConvert_Unicode_None() : CsConvert(0, "DIRECT", CS_UNICODE_UCS2, CS_NONE) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CsConvert_ASCII_Unicode : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_ASCII_Unicode; } - CsConvert_ASCII_Unicode() : CsConvert(0, "DIRECT", CS_ASCII, CS_UNICODE_UCS2) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CsConvert_Unicode_ASCII : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_Unicode_ASCII; } - CsConvert_Unicode_ASCII() : CsConvert(0, "DIRECT", CS_UNICODE_UCS2, CS_ASCII) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CsConvert_UFSS_Unicode : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_UFSS_Unicode; } - CsConvert_UFSS_Unicode() : CsConvert(0, "DIRECT", CS_UNICODE_FSS, CS_UNICODE_UCS2) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CsConvert_Unicode_UFSS : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_Unicode_UFSS; } - CsConvert_Unicode_UFSS() : CsConvert(0, "DIRECT", CS_UNICODE_UCS2, CS_UNICODE_FSS) - {} - unsigned short convert(unsigned char *a, - unsigned short b, - unsigned char *c, - unsigned short d, - short *e, - unsigned short *f) - { return internal_unicode_to_fss(a,b,c,d,e,f); } -}; - -class CsConvert_Binary_Unicode : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_Binary_Unicode; } - CsConvert_Binary_Unicode() : CsConvert(0, "DIRECT", CS_BINARY, CS_UNICODE_UCS2) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CsConvert_Unicode_Binary : public CsConvert -{ -public: - static CsConvert *object_factory(MemoryPool& p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CsConvert_Unicode_Binary; } - CsConvert_Unicode_Binary() : CsConvert(0, "DIRECT", CS_UNICODE_UCS2, CS_BINARY) - {} - unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*); -}; - -class CharSet_None : public CharSet -{ -public: - static CharSet *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CharSet_None(p); } - CharSet_None(MemoryPool &p) : CharSet(CS_NONE, "NONE", 1, 1, 1, " ") - { - charset_to_unicode = CsConvert_None_Unicode::object_factory(p,0,0); - charset_from_unicode = CsConvert_Unicode_None::object_factory(p,0,0); - } -}; - -class CharSet_ASCII : public CharSet -{ -public: - static CharSet *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CharSet_ASCII(p); } - CharSet_ASCII(MemoryPool &p) : CharSet(CS_ASCII, "ASCII", 1, 1, 1, " ") - { - charset_to_unicode = CsConvert_ASCII_Unicode::object_factory(p,0,0); - charset_from_unicode = CsConvert_Unicode_ASCII::object_factory(p,0,0); - } -}; - -class CharSet_Unicode_FSS : public CharSet -{ -public: - static CharSet *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CharSet_Unicode_FSS(p); } - CharSet_Unicode_FSS(MemoryPool &p) : CharSet(CS_UNICODE_FSS, "UNICODE_FSS", 1, 1, 1, " ") - { - charset_to_unicode = CsConvert_UFSS_Unicode::object_factory(p,0,0); - charset_from_unicode = CsConvert_Unicode_UFSS::object_factory(p,0,0); - } -}; - -class CharSet_Unicode : public CharSet -{ -public: - static CharSet *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CharSet_Unicode(p); } - CharSet_Unicode(MemoryPool &p) : CharSet(CS_UNICODE_UCS2, "UNICODE_UCS2", 2, 2, 2, 0) - { - static const UCS2_CHAR space = 0x0020; - charset_space_character = (const char *) & space; /* 0x0020 */ - } -}; - -class CharSet_Binary : public CharSet -{ -public: - static CharSet *object_factory(MemoryPool &p, CHARSET_ID u1, CHARSET_ID u2) - { return FB_NEW(p) CharSet_Binary(p); } - CharSet_Binary(MemoryPool &p) : CharSet(CS_BINARY, "BINARY", 1, 1, 1, "\0") - { - charset_to_unicode = CsConvert_Binary_Unicode::object_factory(p,0,0); - charset_from_unicode = CsConvert_Unicode_Binary::object_factory(p,0,0); - } -}; - -/********************************************************************************/ - -#ifndef HAVE_SWAB -#ifdef HAVE__SWAB -#define swab _swab -#else // use generic swab(). Slow (but faster than previous implementation) and buggy -void swab(char * a, char * b, int n) -{ - while(--n>0) - { - *b++ = a[1]; - *b++ = *a++; - a++; n--; - } -} -#endif -#endif - -unsigned short CsConvert_Unicode_Binary::convert( - unsigned char *pDest, - unsigned short nDest, - unsigned char *pSrcUC, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * CsConvert_Unicode_Binary::convert - * - ************************************** - * - * Functional description - * Convert a wc string to network form - high-endian - * byte stream. - * - *************************************/ - unsigned short res; - - assert((pSrcUC != NULL) || (pDest == NULL)); - assert(err_code != NULL); - assert(err_position != NULL); - - *err_code = 0; - if (pDest == NULL) /* length estimate needed? */ - return (nSrc); - - assert(nSrc&1 == 0); // check for even length - - if (nSrc>nDest) { - *err_code = CS_TRUNCATION_ERROR; - } - res = nSrc>nDest?nDest:nSrc; -#ifdef WORDS_BIGENDIAN - MOVE_FAST(pSrcUC,pDest,res); -#else - swab((char *)pSrcUC,(char *)pDest,res); -#endif - *err_position = res; - - return res; -} - - -unsigned short CsConvert_Binary_Unicode::convert( - unsigned char *pDestUC, - unsigned short nDest, - unsigned char *pSrc, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * CsConvert_Binary_Unicode::convert - * - ************************************** - * - * Functional description - * Convert a wc string from network form - high-endian - * byte stream. - * Symmetrical with CsConvert_Unicode_Binary::convert - * but really the same - * - *************************************/ - unsigned short res; - - assert((pSrc != NULL) || (pDestUC == NULL)); - assert(err_code != NULL); - assert(err_position != NULL); - - *err_code = 0; - if (pDestUC == NULL) /* length estimate needed? */ - return (nSrc); - - assert(nSrc&1 == 0); - - if (nSrc>nDest) { - *err_code = CS_TRUNCATION_ERROR; - } - res = nSrc>nDest?nDest:nSrc; -#ifdef WORDS_BIGENDIAN - MOVE_FAST(pSrc,pDestUC,res); -#else - swab((char *)pSrc,(char *)pDestUC,res); -#endif - *err_position = res; - - return res; -} - -unsigned short CsConvert_UFSS_Unicode::convert( - unsigned char *dest_ptrUC, - unsigned short dest_len, - unsigned char *src_ptr, - unsigned short src_len, - short *err_code, - unsigned short *err_position) -{ - UCS2_CHAR *start, *dest_ptr = (UCS2_CHAR*)dest_ptrUC; - USHORT src_start = src_len; - fss_size_t res; - - assert(src_ptr != NULL || dest_ptr == NULL); - assert(err_code != NULL); - assert(err_position != NULL); - - *err_code = 0; - -/* See if we're only after a length estimate */ - if (dest_ptr == NULL) - return (src_len * 2); /* All single byte narrow characters */ - - start = dest_ptr; - src_start = src_len; - while ((src_len) && (dest_len >= sizeof(*dest_ptr))) { - res = fss_mbtowc(dest_ptr, src_ptr, src_len); - if (res == -1) { - *err_code = CS_BAD_INPUT; - break; - } - assert(res <= src_len); - dest_ptr++; - dest_len -= sizeof(*dest_ptr); - src_ptr += res; - src_len -= res; - } - if (src_len && !*err_code) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = src_start - src_len; - return ((dest_ptr - start) * sizeof(*dest_ptr)); -} - -unsigned short CsConvert_Unicode_ASCII::convert( - unsigned char *pDest, - unsigned short nDest, - unsigned char *pSrcUC, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * CsConvert_Unicode_ASCII::convert - * - ************************************** - * - * Functional description - * Convert UNICODE to CHARACTER SET ASCII (wide char). - * Byte values below 128 treated as ASCII. - * Byte values >= 128 create CONVERT_ERROR - * - *************************************/ - NCHAR *pStart; - UCS2_CHAR *pStart_src, *pSrc = (UCS2_CHAR*)pSrcUC; - - assert((pSrc != NULL) || (pDest == NULL)); - assert(err_code != NULL); - - *err_code = 0; - if (pDest == NULL) /* length estimate needed? */ - return (nSrc / 2); - pStart = pDest; - pStart_src = pSrc; - while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { - if (*pSrc > 127) { - *err_code = CS_CONVERT_ERROR; - break; - } - *pDest++ = *pSrc++; - nDest -= sizeof(*pDest); - nSrc -= sizeof(*pSrc); - } - if (!*err_code && nSrc) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = (pSrc - pStart_src) * sizeof(*pSrc); - - return ((pDest - pStart) * sizeof(*pDest)); -} - -unsigned short CsConvert_ASCII_Unicode::convert( - unsigned char *pDestUC, - unsigned short nDest, - unsigned char *pSrc, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * CsConvert_ASCII_Unicode::convert - * - ************************************** - * - * Functional description - * Convert CHARACTER SET NONE to UNICODE (wide char). - * Byte values below 128 treated as ASCII. - * Byte values >= 128 create BAD_INPUT - * - *************************************/ - UCS2_CHAR *pStart, *pDest = (UCS2_CHAR*)pDestUC; - UCHAR *pStart_src; - - assert((pSrc != NULL) || (pDest == NULL)); - assert(err_code != NULL); - - *err_code = 0; - if (pDest == NULL) /* length estimate needed? */ - return (2 * nSrc); - pStart = pDest; - pStart_src = pSrc; - while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { - if (*pSrc > 127) { - *err_code = CS_BAD_INPUT; - break; - } - *pDest++ = *pSrc++; - nDest -= sizeof(*pDest); - nSrc -= sizeof(*pSrc); - } - if (!*err_code && nSrc) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = (pSrc - pStart_src) * sizeof(*pSrc); - - return ((pDest - pStart) * sizeof(*pDest)); -} - -unsigned short CsConvert_Unicode_None::convert( - unsigned char *pDest, - unsigned short nDest, - unsigned char *pSrcUC, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * w c _ t o _ n c - * - ************************************** - * - * Functional description - * - **************************************/ - NCHAR *pStart; - UCS2_CHAR *pStart_src, *pSrc = (UCS2_CHAR*)pSrcUC; - - assert((pSrc != NULL) || (pDest == NULL)); - assert(err_code != NULL); - assert(err_position != NULL); - - *err_code = 0; - if (pDest == NULL) /* length estimate needed? */ - return ((nSrc + 1) / 2); - pStart = pDest; - pStart_src = pSrc; - while (nDest && nSrc >= sizeof(*pSrc)) { - if (*pSrc >= 256) { - *err_code = CS_CONVERT_ERROR; - break; - } - *pDest++ = *pSrc++; - nDest -= sizeof(*pDest); - nSrc -= sizeof(*pSrc); - } - if (!*err_code && nSrc) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = (pSrc - pStart_src) * sizeof(*pSrc); - - return ((pDest - pStart) * sizeof(*pDest)); -} - -unsigned short CsConvert_None_Unicode::convert( - unsigned char *pDestUC, - unsigned short nDest, - unsigned char *pSrc, - unsigned short nSrc, - short *err_code, - unsigned short *err_position) -{ -/************************************** - * - * CsConvert_None_Unicode::convert - * - ************************************** - * - * Functional description - * Convert CHARACTER SET NONE to UNICODE (wide char). - * Byte values below 128 treated as ASCII. - * Byte values >= 128 create CONVERT ERROR - * - *************************************/ - UCS2_CHAR *pStart, *pDest = (UCS2_CHAR*)pDestUC; - UCHAR *pStart_src; - - assert((pSrc != NULL) || (pDest == NULL)); - assert(err_code != NULL); - - *err_code = 0; - if (pDest == NULL) /* length estimate needed? */ - return (2 * nSrc); - pStart = pDest; - pStart_src = pSrc; - while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { - if (*pSrc > 127) { - *err_code = CS_CONVERT_ERROR; - break; - } - *pDest++ = *pSrc++; - nDest -= sizeof(*pDest); - nSrc -= sizeof(*pSrc); - } - if (!*err_code && nSrc) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = (pSrc - pStart_src) * sizeof(*pSrc); - - return ((pDest - pStart) * sizeof(*pDest)); -} - -static unsigned short cvt_utffss_to_ascii(UCHAR * pDest, USHORT nDest, /* byte count */ - UCHAR * pSrc, USHORT nSrc, /* byte count */ - short *err_code, unsigned short *err_position) -{ -/************************************** - * - * c v t _ u t f f s s _ t o _ a s c i i - * - ************************************** - * - * Functional description - * Perform a pass-through transformation of ASCII to Unicode - * in FSS format. Note that any byte values greater than 127 - * cannot be converted in either direction, so the same - * routine does double duty. - * - *************************************/ - UCHAR *pStart; - UCHAR *pStart_src; - - assert((pSrc != NULL) || (pDest == NULL)); - assert(err_code != NULL); - - *err_code = 0; - if (pDest == NULL) /* length estimate needed? */ - return (nSrc); - pStart = pDest; - pStart_src = pSrc; - while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { - if (*pSrc > 127) { - /* In the cvt_ascii_to_utffss case this should be CS_BAD_INPUT */ - /* but not in cvt_none_to_utffss or cvt_utffss_to_ascii */ - *err_code = CS_CONVERT_ERROR; - break; - } - *pDest++ = *pSrc++; - nDest -= sizeof(*pDest); - nSrc -= sizeof(*pSrc); - } - if (!*err_code && nSrc) { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = (pSrc - pStart_src) * sizeof(*pSrc); - - return ((pDest - pStart) * sizeof(*pDest)); -} - -/* - * The following was provided by Ken Thompson of AT&T Bell Laboratories, - * , on Tue, 8 Sep 92 03:22:07 EDT, to the X/Open - * Joint Internationalization Group. Some minor formatting changes have - * been made by Glenn Adams, . - * - * ------------------------------------------------------------------------- - * File System Safe Universal Character Set Transformation Format (FSS-UTF) - * ------------------------------------------------------------------------- - * - * With the approval of ISO/IEC 10646 (Unicode) as an international - * standard and the anticipated wide spread use of this universal coded - * character set (UCS), it is necessary for historically ASCII based - * operating systems to devise ways to cope with representation and - * handling of the large number of characters that are possible to be - * encoded by this new standard. - * - * There are several challenges presented by UCS which must be dealt with - * by historical operating systems and the C-language programming - * environment. The most significant of these challenges is the encoding - * scheme used by UCS. More precisely, the challenge is the marrying of - * the UCS standard with existing programming languages and existing - * operating systems and utilities. - * - * The challenges of the programming languages and the UCS standard are - * being dealt with by other activities in the industry. However, we are - * still faced with the handling of UCS by historical operating systems - * and utilities. Prominent among the operating system UCS handling - * concerns is the representation of the data within the file system. An - * underlying assumption is that there is an absolute requirement to - * maintain the existing operating system software investment while at - * the same time taking advantage of the use the large number of - * characters provided by the UCS. - * - * UCS provides the capability to encode multi-lingual text within a - * single coded character set. However, UCS and its UTF variant do not - * protect null bytes and/or the ASCII slash ("/") making these character - * encodings incompatible with existing Unix implementations. The - * following proposal provides a Unix compatible transformation format of - * UCS such that Unix systems can support multi-lingual text in a single - * encoding. This transformation format encoding is intended to be used - * as a file code. This transformation format encoding of UCS is - * intended as an intermediate step towards full UCS support. However, - * since nearly all Unix implementations face the same obstacles in - * supporting UCS, this proposal is intended to provide a common and - * compatible encoding during this transition stage. - * - * Goal/Objective - * -------------- - * - * With the assumption that most, if not all, of the issues surrounding - * the handling and storing of UCS in historical operating system file - * systems are understood, the objective is to define a UCS - * transformation format which also meets the requirement of being usable - * on a historical operating system file system in a non-disruptive - * manner. The intent is that UCS will be the process code for the - * transformation format, which is usable as a file code. - * - * Criteria for the Transformation Format - * -------------------------------------- - * - * Below are the guidelines that were used in defining the UCS - * transformation format: - * - * 1) Compatibility with historical file systems: - * - * Historical file systems disallow the null byte and the ASCII - * slash character as a part of the file name. - * - * 2) Compatibility with existing programs: - * - * The existing model for multibyte processing is that ASCII does - * not occur anywhere in a multibyte encoding. There should be - * no ASCII code values for any part of a transformation format - * representation of a character that was not in the ASCII - * character set in the UCS representation of the character. - * - * 3) Ease of conversion from/to UCS. - * - * 4) The first byte should indicate the number of bytes to - * follow in a multibyte sequence. - * - * 5) The transformation format should not be extravagant in - * terms of number of bytes used for encoding. - * - * 6) It should be possible to find the start of a character - * efficiently starting from an arbitrary location in a byte - * stream. - * - * Proposed FSS-UTF - * ---------------- - * - * The proposed UCS transformation format encodes UCS values in the range - * [0,0x7fffffff] using multibyte characters of lengths 1, 2, 3, 4, 5, - * and 6 bytes. For all encodings of more than one byte, the initial - * byte determines the number of bytes used and the high-order bit in - * each byte is set. Every byte that does not start 10xxxxxx is the - * start of a UCS character sequence. - * - * An easy way to remember this transformation format is to note that the - * number of high-order 1's in the first byte signifies the number of - * bytes in the multibyte character: - * - * Bits Hex Min Hex Max Byte Sequence in Binary - * 7 00000000 0000007f 0vvvvvvv - * 11 00000080 000007FF 110vvvvv 10vvvvvv - * 16 00000800 0000FFFF 1110vvvv 10vvvvvv 10vvvvvv - * 21 00010000 001FFFFF 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv - * 26 00200000 03FFFFFF 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv - * 31 04000000 7FFFFFFF 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv - * - * The UCS value is just the concatenation of the v bits in the multibyte - * encoding. When there are multiple ways to encode a value, for example - * UCS 0, only the SSHORTest encoding is legal. - * - * Below are sample implementations of the C standard wctomb() and - * mbtowc() functions which demonstrate the algorithms for converting - * from UCS to the transformation format and converting from the - * transformation format to UCS. The sample implementations include error - * checks, some of which may not be necessary for conformance: - * - */ typedef struct { int cmask; @@ -950,7 +50,7 @@ typedef struct { SLONG lval; } Tab; -static const Tab tab[] = { +static CONST Tab tab[] = { { 0x80, 0x00, 0 * 6, 0x7F, 0 }, /* 1 byte sequence */ { 0xE0, 0xC0, 1 * 6, 0x7FF, 0x80 }, /* 2 byte sequence */ { 0xF0, 0xE0, 2 * 6, 0xFFFF, 0x800 }, /* 3 byte sequence */ @@ -960,7 +60,6 @@ static const Tab tab[] = { { 0, 0, 0, 0, 0 } /* end of table */ }; - static fss_size_t fss_mbtowc(fss_wchar_t * p, UCHAR * s, fss_size_t n) { SLONG l; @@ -1022,14 +121,175 @@ static fss_size_t fss_wctomb(UCHAR * s, fss_wchar_t wc) return -1; } +static SSHORT internal_fss_mbtowc(TEXTTYPE * obj, + WCHAR * wc, NCHAR * p, USHORT n) +{ +/************************************** + * + * I N T L _ f s s _ m b t o w c + * + ************************************** + * + * Functional description + * InterBase interface to mbtowc function for Unicode + * text in FSS bytestream format. + * + * Return: (common to all mbtowc routines) + * -1 Error in parsing next character + * Count of characters consumed. + * *wc Next character from byte steam (if wc <> NULL) + * + * Note: This routine has a cousin in intl/cv_utffss.c + * + **************************************/ + assert(obj); + assert(wc); + assert(p); + return fss_mbtowc(wc, p, n); +} -/************************************************************************************/ -static unsigned short internal_string_to_key( +static USHORT internal_fss_to_unicode(CSCONVERT obj, + UNICODE * dest_ptr, USHORT dest_len, /* BYTE count */ + NCHAR * src_ptr, + USHORT src_len, + SSHORT * err_code, + USHORT * err_position) +{ + UNICODE *start; + USHORT src_start = src_len; + fss_size_t res; + + assert(src_ptr != NULL || dest_ptr == NULL); + assert(err_code != NULL); + assert(err_position != NULL); + assert(obj != NULL); + + *err_code = 0; + +/* See if we're only after a length estimate */ + if (dest_ptr == NULL) + return (src_len * 2); /* All single byte narrow characters */ + + start = dest_ptr; + src_start = src_len; + while ((src_len) && (dest_len >= sizeof(*dest_ptr))) { + res = fss_mbtowc(dest_ptr, src_ptr, src_len); + if (res == -1) { + *err_code = CS_BAD_INPUT; + break; + } + assert(res <= src_len); + dest_ptr++; + dest_len -= sizeof(*dest_ptr); + src_ptr += res; + src_len -= res; + } + if (src_len && !*err_code) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = src_start - src_len; + return ((dest_ptr - start) * sizeof(*dest_ptr)); +} + +USHORT internal_unicode_to_fss(CSCONVERT obj, + MBCHAR * fss_str, + USHORT fss_len, + UNICODE * unicode_str, USHORT unicode_len, /* BYTE count */ + SSHORT * err_code, + USHORT * err_position) +{ + UCHAR *start; + USHORT src_start = unicode_len; + UCHAR tmp_buffer[6]; + UCHAR *p; + fss_size_t res; + + assert(unicode_str != NULL || fss_str == NULL); + assert(err_code != NULL); + assert(err_position != NULL); + assert(obj != NULL); + assert(obj->csconvert_convert == (FPTR_SHORT) internal_unicode_to_fss); + + *err_code = 0; + +/* See if we're only after a length estimate */ + if (fss_str == NULL) + return ((unicode_len + 1) / 2 * 3); /* worst case - all han character input */ + + start = fss_str; + while ((fss_len) && (unicode_len >= sizeof(*unicode_str))) { + /* Convert the wide character into temp buffer */ + res = fss_wctomb(tmp_buffer, *unicode_str); + if (res == -1) { + *err_code = CS_BAD_INPUT; + break; + } + /* will the mb sequence fit into space left? */ + if (res > fss_len) { + *err_code = CS_TRUNCATION_ERROR; + break; + } + /* copy the converted bytes into the destination */ + p = tmp_buffer; + for (; res; res--, fss_len--) + *fss_str++ = *p++; + unicode_len -= sizeof(*unicode_str); + unicode_str++; + } + if (unicode_len && !*err_code) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = src_start - unicode_len; + return ((fss_str - start) * sizeof(*fss_str)); +} + +static SSHORT internal_str_copy( + TEXTTYPE obj, + USHORT inLen, + UCHAR * src, USHORT outLen, UCHAR * dest) +{ +/************************************** + * + * i n t e r n a l _ s t r _ c o p y + * + ************************************** + * + * Functional description + * Note: dest may equal src. + * + **************************************/ + UCHAR *pStart; + + pStart = dest; + while (inLen-- && outLen--) { + *dest++ = *src++; + } + + return (dest - pStart); +} + +static USHORT internal_keylength(TEXTTYPE obj, USHORT iLength) +{ +/************************************** + * + * i n t e r n a l _ k e y l e n g t h + * + ************************************** + * + * Functional description + * + **************************************/ + + return (iLength); +} + +static USHORT internal_string_to_key( + TEXTTYPE obj, USHORT inLen, UCHAR * src, USHORT outLen, -UCHAR * dest, USHORT partial, UCHAR pad_char) +UCHAR * dest, USHORT partial) { /************************************** * @@ -1041,8 +301,10 @@ UCHAR * dest, USHORT partial, UCHAR pad_char) * **************************************/ UCHAR *pStart; + UCHAR pad_char; pStart = dest; + pad_char = *obj->texttype_collation_table; while (inLen-- && outLen--) *dest++ = *src++; @@ -1056,8 +318,10 @@ UCHAR * dest, USHORT partial, UCHAR pad_char) return (dest - pStart); } -static SSHORT internal_compare(USHORT length1, - UCHAR * p1, USHORT length2, UCHAR * p2, UCHAR pad) +static SSHORT internal_compare( + TEXTTYPE obj, + USHORT length1, + UCHAR * p1, USHORT length2, UCHAR * p2) { /************************************** * @@ -1069,7 +333,9 @@ static SSHORT internal_compare(USHORT length1, * **************************************/ SSHORT fill; + UCHAR pad; + pad = (obj->texttype_type == ttype_binary) ? 0 : ' '; fill = length1 - length2; if (length1 >= length2) { if (length2) @@ -1111,30 +377,133 @@ static SSHORT internal_compare(USHORT length1, return 0; } -short TextType_Binary::str_to_upper(USHORT inLen, - UCHAR * src, USHORT outLen, UCHAR * dest) +static USHORT internal_ch_to_upper(TEXTTYPE obj, UCHAR ch) { /************************************** * - * TextType_Binary::str_to_upper + * i n t e r n a l _ c h _ t o _ u p p e r * ************************************** * * Functional description - * Note: dest may equal src. * **************************************/ - UCHAR *pStart; - pStart = dest; - while (inLen-- && outLen--) { - *dest++ = *src++; - } - - return (dest - pStart); + return (UPPER7(ch)); } -static SSHORT internal_str_to_upper(USHORT inLen, +static USHORT internal_ch_to_lower(TEXTTYPE obj, UCHAR ch) +{ +/************************************** + * + * i n t e r n a l _ c h _ t o _ l o w e r + * + ************************************** + * + * Functional description + * + **************************************/ + + return ((((ch) >= 'A') && ((ch) < 'Z')) ? ((ch) - 'A' + 'a') : (ch)); +} + +SSHORT INTL_builtin_nc_mbtowc(TEXTTYPE obj, + WCHAR * wc, UCHAR * ptr, USHORT count) +{ +/************************************** + * + * i n t e r n a l _ n c _ m b t o w c + * + ************************************** + * + * Functional description + * Get the next character from the multibyte + * input stream. + * Narrow character version. + * Returns: + * Count of bytes consumed from the input stream. + * + **************************************/ + + assert(obj); + assert(ptr); + + if (count >= 1) { + if (wc) + *wc = *ptr; + return 1; + } + if (wc) + *wc = 0; + return -1; /* No more characters */ +} + +SSHORT INTL_builtin_mb_mbtowc(TEXTTYPE obj, + WCHAR * wc, UCHAR * ptr, USHORT count) +{ +/************************************** + * + * i n t e r n a l _ m b _ m b t o w c + * + ************************************** + * + * Functional description + * Get the next character from the multibyte + * input stream. + * Multibyte version character version. + * Returns: + * Count of bytes consumed from the input stream. + * + **************************************/ + + assert(obj); + assert(ptr); + + if (count >= 2) { + if (wc) + *wc = *(WCHAR *) ptr; + return 2; + } + if (wc) + *wc = 0; + return -1; /* No more characters */ +} + + +SSHORT INTL_builtin_wc_mbtowc(TEXTTYPE obj, + WCHAR * wc, UCHAR * ptr, USHORT count) +{ +/************************************** + * + * i n t e r n a l _ w c _ m b t o w c + * + ************************************** + * + * Functional description + * Get the next character from the multibyte + * input stream. + * Wide character version. + * Returns: + * Count of bytes consumed from the input stream. + * + **************************************/ + + assert(obj); + assert(ptr); + + if (count >= 2) { + if (wc) + *wc = *(WCHAR *) ptr; + return 2; + } + if (wc) + *wc = 0; + return -1; /* No more characters */ +} + +static SSHORT internal_str_to_upper( + TEXTTYPE obj, + USHORT inLen, UCHAR * src, USHORT outLen, UCHAR * dest) { /************************************** @@ -1148,7 +517,6 @@ static SSHORT internal_str_to_upper(USHORT inLen, * **************************************/ UCHAR *pStart; - pStart = dest; while (inLen-- && outLen--) { *dest++ = UPPER7(*src); @@ -1158,186 +526,150 @@ static SSHORT internal_str_to_upper(USHORT inLen, return (dest - pStart); } -unsigned short internal_unicode_to_fss( - unsigned char *fss_strUC, - unsigned short fss_len, - unsigned char *unicode_strUC, - unsigned short unicode_len, - short *err_code, - unsigned short *err_position) +static USHORT internal_ch_copy(TEXTTYPE obj, UCHAR ch) { - MBCHAR *fss_str = (MBCHAR*)fss_strUC; - UCS2_CHAR *unicode_str = (UCS2_CHAR*)unicode_strUC; - UCHAR *start; - USHORT src_start = unicode_len; - UCHAR tmp_buffer[6]; - UCHAR *p; - fss_size_t res; +/************************************** + * + * i n t e r n a l _ c h _ c o p y + * + ************************************** + * + * Functional description + * + **************************************/ - assert(unicode_str != NULL || fss_str == NULL); + return (ch); +} + +static USHORT wc_to_nc(CSCONVERT obj, NCHAR * pDest, USHORT nDest, /* byte count */ + WCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) +{ +/************************************** + * + * w c _ t o _ n c + * + ************************************** + * + * Functional description + * + **************************************/ + NCHAR *pStart; + WCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); assert(err_code != NULL); assert(err_position != NULL); *err_code = 0; - -/* See if we're only after a length estimate */ - if (fss_str == NULL) - return ((unicode_len + 1) / 2 * 3); /* worst case - all han character input */ - - start = fss_str; - while ((fss_len) && (unicode_len >= sizeof(*unicode_str))) { - /* Convert the wide character into temp buffer */ - res = fss_wctomb(tmp_buffer, *unicode_str); - if (res == -1) { - *err_code = CS_BAD_INPUT; + if (pDest == NULL) /* length estimate needed? */ + return ((nSrc + 1) / 2); + pStart = pDest; + pStart_src = pSrc; + while (nDest && nSrc >= sizeof(*pSrc)) { + if (*pSrc >= 256) { + *err_code = CS_CONVERT_ERROR; break; } - /* will the mb sequence fit into space left? */ - if (res > fss_len) { - *err_code = CS_TRUNCATION_ERROR; - break; - } - /* copy the converted bytes into the destination */ - p = tmp_buffer; - for (; res; res--, fss_len--) - *fss_str++ = *p++; - unicode_len -= sizeof(*unicode_str); - unicode_str++; + *pDest++ = *pSrc++; + nDest -= sizeof(*pDest); + nSrc -= sizeof(*pSrc); } - if (unicode_len && !*err_code) { + if (!*err_code && nSrc) { *err_code = CS_TRUNCATION_ERROR; } - *err_position = src_start - unicode_len; - return ((fss_str - start) * sizeof(*fss_str)); + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); } -static USHORT internal_fss_to_unicode ( - UCS2_CHAR *dest_ptr, - USHORT dest_len, /* BYTE count */ - NCHAR *src_ptr, - USHORT src_len, - SSHORT *err_code, - USHORT *err_position) + +static USHORT mb_to_wc(CSCONVERT obj, WCHAR * pDest, USHORT nDest, /* byte count */ + MBCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) { - UCS2_CHAR *start; - USHORT src_start = src_len; - fss_size_t res; - - assert (src_ptr != NULL || dest_ptr == NULL); - assert (err_code != NULL); - assert (err_position != NULL); - +/************************************** + * + * m b _ t o _ w c + * + ************************************** + * + * Functional description + * Convert a wc string from network form - high-endian + * byte stream. + * + *************************************/ + WCHAR *pStart; + MBCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); + assert(err_code != NULL); + assert(err_position != NULL); + *err_code = 0; - - /* See if we're only after a length estimate */ - if (dest_ptr == NULL) - return (src_len*2); /* All single byte narrow characters */ - - start = dest_ptr; - src_start = src_len; - while ((src_len) && (dest_len >= sizeof (*dest_ptr))) - { - res = fss_mbtowc (dest_ptr, src_ptr, src_len); - if (res == -1) - { - *err_code = CS_BAD_INPUT; - break; - } - assert (res <= src_len); - dest_ptr++; - dest_len -= sizeof (*dest_ptr); - src_ptr += res; - src_len -= res; - } - if (src_len && !*err_code) - { - *err_code = CS_TRUNCATION_ERROR; - } - *err_position = src_start - src_len; - return ((dest_ptr - start)*sizeof (*dest_ptr)); -} - -CharSetAllocFunc INTL_charset_alloc_func(short charset) -{ - switch(charset) - { - case CS_NONE: - return CharSet_None::object_factory; - case CS_ASCII: - return CharSet_ASCII::object_factory; - case CS_UNICODE_FSS: - return CharSet_Unicode_FSS::object_factory; - case CS_UNICODE_UCS2: - return CharSet_Unicode::object_factory; - case CS_BINARY: - return CharSet_Binary::object_factory; - default: - return NULL; - } - return NULL; -} - -TextTypeAllocFunc INTL_texttype_alloc_func(short ttype) -{ - switch(ttype) - { - case ttype_none: - return TextType_None::object_factory; - case ttype_ascii: - return TextType_ASCII::object_factory; - case ttype_unicode_fss: - return TextType_UFSS::object_factory; - case ttype_binary: - return TextType_Binary::object_factory; - default: - return NULL; + if (pDest == NULL) /* length estimate needed? */ + return (nSrc); + pStart = pDest; + pStart_src = pSrc; + while (nDest > 1 && nSrc > 1) { + *pDest++ = *pSrc * 256 + *(pSrc + 1); + pSrc += 2; + nDest -= 2; + nSrc -= 2; } - return NULL; + if (!*err_code && nSrc) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); } -CsConvertAllocFunc INTL_csconvert_alloc_func(short from, short to) + +static USHORT wc_to_mb(CSCONVERT obj, MBCHAR * pDest, USHORT nDest, /* byte count */ + WCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) { - if (from == CS_ASCII && to == CS_UNICODE_FSS) - return CsConvert_ASCII_UFSS::object_factory; - if (from == CS_UNICODE_FSS && to == CS_ASCII) - return CsConvert_UFSS_ASCII::object_factory; - if (from == CS_UNICODE_FSS && to == CS_NONE) - return CsConvert_UFSS_None::object_factory; - return NULL; +/************************************** + * + * w c _ t o _ m b + * + ************************************** + * + * Functional description + * Convert a wc string to network form - high-endian + * byte stream. + * + *************************************/ + MBCHAR *pStart; + WCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); + assert(err_code != NULL); + assert(err_position != NULL); + + *err_code = 0; + if (pDest == NULL) /* length estimate needed? */ + return (nSrc); + pStart = pDest; + pStart_src = pSrc; + while (nDest > 1 && nSrc > 1) { + *pDest++ = *pSrc / 256; + *pDest++ = *pSrc++ % 256; + nDest -= 2; + nSrc -= 2; + } + if (!*err_code && nSrc) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); } -#if NOT_USED_OR_REPLACED -//======================================================================================== -//======================================================================================== -//======================================================================================== -//======================================================================================== -// -// JMB: absolete code - to be removed later -#define TEXTTYPE_RETURN return (0) - -#define FAMILY_INTERNAL(id_number, name, charset, country) \ - cache->texttype_version = 40; \ - cache->texttype_type = (id_number); \ - cache->texttype_character_set = (charset); \ - cache->texttype_country = (country); \ - cache->texttype_bytes_per_char = 1; \ - cache->texttype_fn_init = (FPTR_SHORT) (name); \ - cache->texttype_fn_key_length = (FPTR_SHORT) internal_keylength; \ - cache->texttype_fn_string_to_key = (FPTR_SHORT) internal_string_to_key; \ - cache->texttype_fn_compare = (FPTR_short) internal_compare; \ - cache->texttype_fn_to_upper = (FPTR_SHORT) internal_ch_to_upper; \ - cache->texttype_fn_to_lower = (FPTR_SHORT) internal_ch_to_lower; \ - cache->texttype_fn_str_to_upper = (FPTR_short) internal_str_to_upper; \ - cache->texttype_fn_mbtowc = (FPTR_short) internal_nc_mbtowc; \ - cache->texttype_collation_table = (BYTE *) " "; \ - cache->texttype_toupper_table = NULL; \ - cache->texttype_tolower_table = NULL; \ - cache->texttype_compress_table = NULL; \ - cache->texttype_expand_table = NULL; \ - cache->texttype_name = const_cast(POSIX); - - - static USHORT ttype_ascii_init(TEXTTYPE cache, USHORT parm1, USHORT dummy) { /************************************** @@ -1394,8 +726,8 @@ static USHORT ttype_unicode_fss_init( FAMILY_INTERNAL(ttype_unicode_fss, ttype_unicode_fss_init, CS_UNICODE_FSS, CC_C); cache->texttype_bytes_per_char = 3; - cache->texttype_fn_to_wc = (FPTR_SHORT) INTL_fss_to_unicode; - cache->texttype_fn_mbtowc = (FPTR_short) INTL_fss_mbtowc; + cache->texttype_fn_to_wc = (FPTR_SHORT) internal_fss_to_unicode; + cache->texttype_fn_mbtowc = (FPTR_short) internal_fss_mbtowc; TEXTTYPE_RETURN; } @@ -1460,6 +792,219 @@ BYTE * from_unicode_tbl2) } +static void common_convert_init( + CSCONVERT csptr, + USHORT to_cs, + USHORT from_cs, + FPTR_SHORT cvt_fn, +BYTE * datatable, BYTE * datatable2) +{ +/************************************** + * + * c o m m o n _ c o n v e r t _ i n i t + * + ************************************** + * + * Functional description + * + **************************************/ + + csptr->csconvert_version = 40; + csptr->csconvert_name = (ASCII *) "DIRECT"; + csptr->csconvert_from = from_cs; + csptr->csconvert_to = to_cs; + csptr->csconvert_convert = cvt_fn; + csptr->csconvert_datatable = datatable; + csptr->csconvert_misc = datatable2; +} + +static USHORT cvt_ascii_to_unicode(CSCONVERT obj, WCHAR * pDest, USHORT nDest, /* byte count */ + UCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) +{ +/************************************** + * + * c v t _ a s c i i _ t o _ u n i c o d e + * + ************************************** + * + * Functional description + * Convert CHARACTER SET NONE to UNICODE (wide char). + * Byte values below 128 treated as ASCII. + * Byte values >= 128 create BAD_INPUT + * + *************************************/ + WCHAR *pStart; + UCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); + assert(err_code != NULL); + + *err_code = 0; + if (pDest == NULL) /* length estimate needed? */ + return (2 * nSrc); + pStart = pDest; + pStart_src = pSrc; + while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { + if (*pSrc > 127) { + *err_code = CS_BAD_INPUT; + break; + } + *pDest++ = *pSrc++; + nDest -= sizeof(*pDest); + nSrc -= sizeof(*pSrc); + } + if (!*err_code && nSrc) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); +} + +static USHORT cvt_unicode_to_ascii(CSCONVERT obj, NCHAR * pDest, USHORT nDest, /* byte count */ + WCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) +{ +/************************************** + * + * c v t _ u n i c o d e _ t o _ a s c i i + * + ************************************** + * + * Functional description + * Convert UNICODE to CHARACTER SET ASCII (wide char). + * Byte values below 128 treated as ASCII. + * Byte values >= 128 create CONVERT_ERROR + * + *************************************/ + NCHAR *pStart; + WCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); + assert(err_code != NULL); + + *err_code = 0; + if (pDest == NULL) /* length estimate needed? */ + return (nSrc / 2); + pStart = pDest; + pStart_src = pSrc; + while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { + if (*pSrc > 127) { + *err_code = CS_CONVERT_ERROR; + break; + } + *pDest++ = *pSrc++; + nDest -= sizeof(*pDest); + nSrc -= sizeof(*pSrc); + } + if (!*err_code && nSrc) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); +} + +static USHORT cvt_none_to_unicode(CSCONVERT obj, WCHAR * pDest, USHORT nDest, /* byte count */ + UCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) +{ +/************************************** + * + * c v t _ n o n e _ t o _ u n i c o d e + * + ************************************** + * + * Functional description + * Convert CHARACTER SET NONE to UNICODE (wide char). + * Byte values below 128 treated as ASCII. + * Byte values >= 128 create CONVERT ERROR + * + *************************************/ + WCHAR *pStart; + UCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); + assert(err_code != NULL); + + *err_code = 0; + if (pDest == NULL) /* length estimate needed? */ + return (2 * nSrc); + pStart = pDest; + pStart_src = pSrc; + while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { + if (*pSrc > 127) { + *err_code = CS_CONVERT_ERROR; + break; + } + *pDest++ = *pSrc++; + nDest -= sizeof(*pDest); + nSrc -= sizeof(*pSrc); + } + if (!*err_code && nSrc) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); +} + +static USHORT cvt_utffss_to_ascii(CSCONVERT obj, UCHAR * pDest, USHORT nDest, /* byte count */ + UCHAR * pSrc, USHORT nSrc, /* byte count */ + SSHORT * err_code, USHORT * err_position) +{ +/************************************** + * + * c v t _ u t f f s s _ t o _ a s c i i + * also + * c v t _ a s c i i _ t o _ u t f f s s + * also + * c v t _ n o n e _ t o _ u t f f s s + * + ************************************** + * + * Functional description + * Perform a pass-through transformation of ASCII to Unicode + * in FSS format. Note that any byte values greater than 127 + * cannot be converted in either direction, so the same + * routine does double duty. + * + *************************************/ + UCHAR *pStart; + UCHAR *pStart_src; + + assert(obj != NULL); + assert((pSrc != NULL) || (pDest == NULL)); + assert(err_code != NULL); + + *err_code = 0; + if (pDest == NULL) /* length estimate needed? */ + return (nSrc); + pStart = pDest; + pStart_src = pSrc; + while (nDest >= sizeof(*pDest) && nSrc >= sizeof(*pSrc)) { + if (*pSrc > 127) { + /* In the cvt_ascii_to_utffss case this should be CS_BAD_INPUT */ + /* but not in cvt_none_to_utffss or cvt_utffss_to_ascii */ + *err_code = CS_CONVERT_ERROR; + break; + } + *pDest++ = *pSrc++; + nDest -= sizeof(*pDest); + nSrc -= sizeof(*pSrc); + } + if (!*err_code && nSrc) { + *err_code = CS_TRUNCATION_ERROR; + } + *err_position = (pSrc - pStart_src) * sizeof(*pSrc); + + return ((pDest - pStart) * sizeof(*pDest)); +} + static USHORT cs_ascii_init(CHARSET csptr, USHORT cs_id, USHORT dummy) { /************************************** @@ -1521,10 +1066,10 @@ static USHORT cs_unicode_fss_init(CHARSET csptr, USHORT cs_id, USHORT dummy) common_8bit_init(csptr, CS_UNICODE_FSS, (ASCII *) "UNICODE_FSS", NULL, NULL, NULL); common_convert_init(&csptr->charset_to_unicode, CS_UNICODE_UCS2, - CS_UNICODE_FSS, (FPTR_SHORT) INTL_fss_to_unicode, + CS_UNICODE_FSS, (FPTR_SHORT) internal_fss_to_unicode, NULL, NULL); common_convert_init(&csptr->charset_from_unicode, CS_UNICODE_FSS, - CS_UNICODE_UCS2, (FPTR_SHORT) INTL_unicode_to_fss, NULL, + CS_UNICODE_UCS2, (FPTR_SHORT) internal_unicode_to_fss, NULL, NULL); CHARSET_RETURN; } @@ -1544,8 +1089,8 @@ static USHORT cs_unicode_ucs2_init(CHARSET csptr, USHORT cs_id, USHORT dummy) static const UCS2_CHAR space = 0x0020; csptr->charset_version = 40; - csptr->charset_id = CS_UNICODE; - csptr->charset_name = (*const* ASCII) "UNICODE_UCS2"; + csptr->charset_id = CS_UNICODE_UCS2; + csptr->charset_name = "UNICODE_UCS2"; csptr->charset_flags = 0; csptr->charset_min_bytes_per_char = 2; csptr->charset_max_bytes_per_char = 2; @@ -1603,4 +1148,51 @@ static USHORT cvt_ascii_utf_init( (FPTR_SHORT) cvt_utffss_to_ascii, NULL, NULL); CONVERT_RETURN; } + +FPTR_SHORT INTL_builtin_lookup(USHORT objtype, SSHORT parm1, SSHORT parm2) { + switch (objtype) { + case type_texttype: + if (parm1 == ttype_none) + return (FPTR_SHORT)ttype_none_init; + if (parm1 == ttype_ascii) + return (FPTR_SHORT)ttype_ascii_init; + if (parm1 == ttype_unicode_fss) + return (FPTR_SHORT)ttype_unicode_fss_init; + if (parm1 == ttype_binary) + return (FPTR_SHORT)ttype_binary_init; + break; + case type_charset: + if (parm1 == CS_NONE) + return (FPTR_SHORT)cs_none_init; + if (parm1 == CS_ASCII) + return (FPTR_SHORT)cs_ascii_init; + if (parm1 == CS_UNICODE_FSS) + return (FPTR_SHORT)cs_unicode_fss_init; + if (parm1 == CS_UNICODE_UCS2) + return (FPTR_SHORT)cs_unicode_ucs2_init; + if (parm1 == CS_BINARY) + return (FPTR_SHORT)cs_binary_init; + break; + case type_csconvert: + if (((parm1 == CS_ASCII) && (parm2 == CS_UNICODE_FSS)) || + ((parm2 == CS_ASCII) && (parm1 == CS_UNICODE_FSS))) + return (FPTR_SHORT)cvt_ascii_utf_init; + + /* converting FROM NONE to UNICODE has a short cut + * - it's treated like ASCII */ + if ((parm2 == CS_NONE) && (parm1 == CS_UNICODE_FSS)) + return (FPTR_SHORT)cvt_ascii_utf_init; + +#ifdef DEV_BUILD + /* Converting TO character set NONE should have been handled at + * a higher level + */ + assert(parm1 != CS_NONE); #endif + break; + default: + BUGCHECK(1); + break; + } + return NULL; +} diff --git a/src/jrd/intl_classes.h b/src/jrd/intl_classes.h index 5c6896ffbf..f8d8cc72b2 100644 --- a/src/jrd/intl_classes.h +++ b/src/jrd/intl_classes.h @@ -24,328 +24,277 @@ #ifndef JRD_INTL_CLASSES_H #define JRD_INTL_CLASSES_H -#include "../common/classes/alloc.h" - -typedef unsigned short CHARSET_ID; -typedef unsigned short COLLATE_ID; -typedef unsigned short TTYPE_ID; -typedef unsigned short UCS2_CHAR; -typedef unsigned char NCHAR; -typedef unsigned char MBCHAR; -typedef class tdbb *TDBB; -typedef signed char ASCII; -typedef unsigned char BYTE; -typedef unsigned short (*FPTR_SHORT) (); - -enum intl_object_types -{ - type_texttype = 54, - type_charset = 55, - type_csconvert = 56 -}; +#include "firebird.h" +#include "../jrd/jrd.h" +#include "../jrd/constants.h" +#include "../jrd/intlobj.h" class TextType { public: - TextType(unsigned short type, const char *name, CHARSET_ID cs_id, - short country, unsigned char bpc) : - texttype_type(type), - texttype_name(name), - texttype_character_set(cs_id), - texttype_country(country), - texttype_bytes_per_char(bpc) - {} + TextType(struct texttype *_tt) : tt(_tt) {} - // texttype_fn_init - //static texttype *alloc(MemoryPool &, short parm1, short parm2); - virtual unsigned short key_length(unsigned short) = 0; - virtual unsigned short string_to_key(unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short) = 0; - virtual short compare(unsigned short, - unsigned char*, - unsigned short, - unsigned char*) = 0; - virtual unsigned short to_upper(unsigned short) = 0; - virtual unsigned short to_lower(unsigned short) = 0; - virtual short str_to_upper(unsigned short, - unsigned char*, - unsigned short, - unsigned char*) = 0; - /* SD: to_wc returns estimated or real length of the result string in bytes that is rather strange */ - virtual unsigned short to_wc(UCS2_CHAR*, // destination buffer - unsigned short, // length of the destination buffer in bytes - unsigned char*, // source buffer - unsigned short, // length of source buffer in bytes - short*, // variable to return error code - unsigned short*) = 0; // variable to return offset of the first - // unprocessed char - virtual unsigned short contains(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short) = 0; - virtual unsigned short like(TDBB, unsigned char*, - short, - unsigned char*, - short, - short) = 0; - virtual unsigned short matches(TDBB, unsigned char*, short, - unsigned char*, short) = 0; - virtual unsigned short sleuth_check(TDBB, unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short) = 0; - virtual unsigned short sleuth_merge(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short) = 0; - virtual unsigned short mbtowc(UCS2_CHAR*, unsigned char*, unsigned short) = 0; - //virtual short get_wchar(unsigned short*, unsigned char*, unsigned short) = 0; + // copy constructor + TextType(TextType& obj) : tt(obj.tt) {} - //unsigned short getVersion() { return texttype_version; } - //unsigned short getFlags() { return texttype_flags; } - unsigned short getType() { return texttype_type; } - const signed char *getName() { return (const signed char*)texttype_name; } - CHARSET_ID getCharSet() { return texttype_character_set; } - short getCountry() { return texttype_country; } - unsigned char getBytesPerChar() { return texttype_bytes_per_char; } + USHORT key_length(USHORT a) { + assert(tt); + assert(tt->texttype_fn_key_length); + return (*(reinterpret_cast + (tt->texttype_fn_key_length)))(tt,a); + } -protected: - unsigned short texttype_type; /* Interpretation ID */ - const char *texttype_name; - CHARSET_ID texttype_character_set; /* ID of base character set */ - short texttype_country; /* ID of base country values */ - unsigned char texttype_bytes_per_char; /* max bytes per character */ + USHORT string_to_key(USHORT a, + UCHAR *b, + USHORT c, + UCHAR *d, + USHORT e) + { + assert(tt); + assert(tt->texttype_fn_string_to_key); + return (*(reinterpret_cast + + (tt->texttype_fn_string_to_key))) + (tt,a,b,c,d,e); + } + + SSHORT compare(USHORT a, + UCHAR *b, + USHORT c, + UCHAR *d) + { + assert(tt); + assert(tt->texttype_fn_compare); + return (*(reinterpret_cast + + (tt->texttype_fn_compare)))(tt,a,b,c,d); + } + + USHORT to_upper(USHORT a) + { + assert(tt); + assert(tt->texttype_fn_to_upper); + return (*(reinterpret_cast + + (tt->texttype_fn_to_upper)))(tt,a); + } + + USHORT to_lower(USHORT a) + { + assert(tt); + assert(tt->texttype_fn_to_lower); + return (*(reinterpret_cast + + (tt->texttype_fn_to_lower)))(tt,a); + } + + SSHORT str_to_upper(USHORT a, + UCHAR *b, + USHORT c, + UCHAR *d) + { + assert(tt); + assert(tt->texttype_fn_str_to_upper); + return (*(reinterpret_cast + + (tt->texttype_fn_str_to_upper))) + (tt,a,b,c,d); + } + + USHORT to_wc(UCS2_CHAR *a, + USHORT b, + UCHAR *c, + USHORT d, + SSHORT *e, + USHORT *f) + { + assert(tt); + assert(tt->texttype_fn_to_wc); + return (*(reinterpret_cast + + (tt->texttype_fn_to_wc))) + (tt,a,b,c,d,e,f); + } + + USHORT mbtowc(UCS2_CHAR *a, UCHAR *b, USHORT c) + { + assert(tt); + assert(tt->texttype_fn_mbtowc); + return (*(reinterpret_cast< + USHORT (*)(TEXTTYPE, UCS2_CHAR*, UCHAR*, USHORT)> + (tt->texttype_fn_mbtowc)))(tt,a,b,c); + } + + USHORT contains(class tdbb *a, UCHAR *b, + USHORT c, + UCHAR *d, + USHORT e) + { + assert(tt); + assert(tt->texttype_fn_contains); + return (*(reinterpret_cast< + USHORT (*)(class tdbb *,TextType,UCHAR*,USHORT,UCHAR*,USHORT)> + (tt->texttype_fn_contains))) + (a,tt,b,c,d,e); + } + + USHORT like(class tdbb *tdbb, UCHAR *a, + SSHORT b, + UCHAR *c, + SSHORT d, + SSHORT e) + { + assert(tt); + assert(tt->texttype_fn_like); + return (*(reinterpret_cast< + USHORT(*)(class tdbb *,TextType,UCHAR*,short,UCHAR*,short,short)> + (tt->texttype_fn_like)))(tdbb,tt,a,b,c,d,e); + } + + USHORT matches(class tdbb *tdbb, UCHAR *a, SSHORT b, UCHAR *c, SSHORT d) + { + assert(tt); + assert(tt->texttype_fn_matches); + return (*(reinterpret_cast< + USHORT (*)(class tdbb *,TextType,UCHAR*,short,UCHAR*,short)> + (tt->texttype_fn_matches))) + (tdbb,tt,a,b,c,d); + } + + USHORT sleuth_check(class tdbb *tdbb, USHORT a, + UCHAR *b, + USHORT c, + UCHAR *d, + USHORT e) + { + assert(tt); + assert(tt->texttype_fn_sleuth_check); + return (*(reinterpret_cast< + USHORT(*)(class tdbb *,TextType,USHORT,UCHAR*,USHORT,UCHAR*,USHORT)> + (tt->texttype_fn_sleuth_check))) + (tdbb,tt,a,b,c,d,e); + } + + USHORT sleuth_merge(class tdbb *tdbb, UCHAR *a, + USHORT b, + UCHAR *c, + USHORT d, + UCHAR *e, + USHORT f) + { + assert(tt); + assert(tt->texttype_fn_sleuth_merge); + return (*(reinterpret_cast< + USHORT(*)(class tdbb *,TextType,UCHAR*,USHORT,UCHAR*,USHORT,UCHAR*,USHORT)> + (tt->texttype_fn_sleuth_merge))) + (tdbb,tt,a,b,c,d,e,f); + } + + + USHORT getType() const { + assert(tt); + return tt->texttype_type; + } + + const char *getName() const { + assert(tt); + return tt->texttype_name; + } + + CHARSET_ID getCharSet() const { + assert(tt); + return tt->texttype_character_set; + } + + SSHORT getCountry() const { + assert(tt); + return tt->texttype_country; + } + + UCHAR getBytesPerChar() const { + assert(tt); + return tt->texttype_bytes_per_char; + } + friend bool operator ==(const TextType& tt1, const TextType& tt2); + friend bool operator !=(const TextType& tt1, const TextType& tt2); + +private: + struct texttype *tt; }; -class TextTypeNC : public TextType -{ -public: - TextTypeNC(unsigned short type, const char *name, CHARSET_ID cs_id, - short country, unsigned char bpc) : - TextType(type, name, cs_id, country, bpc) - {} - - unsigned short to_wc(UCS2_CHAR*, // destination buffer - unsigned short, // length of the destination buffer in bytes - unsigned char*, // source buffer - unsigned short, // length of source buffer in bytes - short*, // variable to return error code - unsigned short*); // variable to return offset of the first - // unprocessed char - unsigned short contains(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short like(TDBB, unsigned char*, - short, - unsigned char*, - short, - short); - unsigned short matches(TDBB, unsigned char*, short, - unsigned char*, short); - unsigned short sleuth_check(TDBB, unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short sleuth_merge(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short mbtowc(UCS2_CHAR*, unsigned char*, unsigned short); -}; - -class TextTypeWC : public TextType -{ -public: - TextTypeWC(unsigned short type, const char *name, CHARSET_ID cs_id, - short country, unsigned char bpc) : - TextType(type, name, cs_id, country, bpc) - {} - - unsigned short to_wc(UCS2_CHAR*, // destination buffer - unsigned short, // length of the destination buffer in bytes - unsigned char*, // source buffer - unsigned short, // length of source buffer in bytes - short*, // variable to return error code - unsigned short*); // variable to return offset of the first - // unprocessed char - unsigned short contains(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short like(TDBB, unsigned char*, - short, - unsigned char*, - short, - short); - unsigned short matches(TDBB, unsigned char*, short, - unsigned char*, short); - unsigned short sleuth_check(TDBB, unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short sleuth_merge(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short mbtowc(UCS2_CHAR*, unsigned char*, unsigned short); -}; - -class TextTypeMB : public TextType -{ -public: - TextTypeMB(unsigned short type, const char *name, CHARSET_ID cs_id, - short country, unsigned char bpc) : - TextType(type, name, cs_id, country, bpc) - {} - - unsigned short contains(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short like(TDBB, unsigned char*, - short, - unsigned char*, - short, - short); - unsigned short matches(TDBB, unsigned char*, short, - unsigned char*, short); - unsigned short sleuth_check(TDBB, unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short sleuth_merge(TDBB, unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - unsigned char*, - unsigned short); - unsigned short mbtowc(UCS2_CHAR*, unsigned char*, unsigned short); -}; - -#define TEXTTYPE_init 1 /* object has been init'ed */ -#define TEXTTYPE_reverse_secondary 2 /* Reverse order of secondary keys */ -#define TEXTTYPE_ignore_specials 4 /* Do not put special values in keys */ -#define TEXTTYPE_expand_before 8 /* Expansion weights before litagure */ +static inline bool operator ==(const TextType& tt1, const TextType& tt2) { + return tt1.tt == tt2.tt; +} +static inline bool operator !=(const TextType& tt1, const TextType& tt2) { + return tt1.tt != tt2.tt; +} class CsConvert { public: - CsConvert(short id, const char *name, CHARSET_ID from, CHARSET_ID to) : - csconvert_id(id), - csconvert_name(name), - csconvert_from(from), - csconvert_to(to) - {} + CsConvert(struct csconvert *_cnvt) : cnvt(_cnvt) {} + CsConvert(CsConvert& obj) : cnvt(obj.cnvt) {} - virtual unsigned short convert(unsigned char*, - unsigned short, - unsigned char*, - unsigned short, - short*, - unsigned short*) = 0; + USHORT convert(UCHAR *a, + USHORT b, + UCHAR *c, + USHORT d, + SSHORT *e, + USHORT *f) + { + assert(cnvt != NULL); + return (*(reinterpret_cast(cnvt->csconvert_convert))) + (cnvt,a,b,c,d,e,f); + } - //unsigned short getVersion() { return csconvert_version; } - //unsigned short getFlags() { return csconvert_flags; } - short getId() { return csconvert_id; } - const signed char *getName() { return (const signed char*)csconvert_name; } - CHARSET_ID getFromCS() { return csconvert_from; } - CHARSET_ID getToCS() { return csconvert_to; } - -protected: - short csconvert_id; - const char *csconvert_name; - CHARSET_ID csconvert_from; - CHARSET_ID csconvert_to; + SSHORT getId() const { assert(cnvt); return cnvt->csconvert_id; } + const char *getName() const { assert(cnvt); return cnvt->csconvert_name; } + CHARSET_ID getFromCS() const { assert(cnvt); return cnvt->csconvert_from; } + CHARSET_ID getToCS() const { assert(cnvt); return cnvt->csconvert_to; } + friend bool operator ==(const CsConvert& cv1, const CsConvert& cv2); + friend bool operator !=(const CsConvert& cv1, const CsConvert& cv2); +private: + struct csconvert *cnvt; }; -/* values for csconvert_flags */ - -#define CONVERTTYPE_init 1 /* object has been init'ed */ - -/* Conversion error codes */ - -#define CS_TRUNCATION_ERROR 1 /* output buffer too small */ -#define CS_CONVERT_ERROR 2 /* can't remap a character */ -#define CS_BAD_INPUT 3 /* input string detected as bad */ - -#define CS_CANT_MAP 0 /* Flag table entries that don't map */ - - - +static inline bool operator ==(const CsConvert& cv1, const CsConvert& cv2) { + return cv1.cnvt == cv2.cnvt; +} +static inline bool operator !=(const CsConvert& cv1, const CsConvert& cv2) { + return cv1.cnvt != cv2.cnvt; +} class CharSet { public: - CharSet(CHARSET_ID id, const char *name, unsigned char mnBpc, unsigned char mxBpc, - unsigned char spLen, const char *spc) : - charset_id(id), - charset_name(name), - charset_min_bytes_per_char(mnBpc), - charset_max_bytes_per_char(mxBpc), - charset_space_length(spLen), - charset_space_character(spc), - charset_to_unicode(0), - charset_from_unicode(0) - {} + CharSet(struct charset *_cs) : cs(_cs) {} + CharSet(CharSet &obj) : cs(obj.cs) {}; - virtual ~CharSet() - { delete charset_to_unicode; delete charset_from_unicode; } + CHARSET_ID getId() const { assert(cs); return cs->charset_id; } + const char *getName() const { assert(cs); return cs->charset_name; } + UCHAR minBytesPerChar() const { assert(cs); return cs->charset_min_bytes_per_char; } + UCHAR maxBytesPerChar() const { assert(cs); return cs->charset_max_bytes_per_char; } + UCHAR getSpaceLength() const { assert(cs); return cs->charset_space_length; } + const UCHAR *getSpace() const { assert(cs); return cs->charset_space_character; } - //unsigned short getVersion() { return charset_version; } - //unsigned short getFlags() { return charset_flags; } - CHARSET_ID getId() { return charset_id; } - const signed char *getName() { return (const signed char*)charset_name; } - unsigned char minBytesPerChar() { return charset_min_bytes_per_char; } - unsigned char maxBytesPerChar() { return charset_max_bytes_per_char; } - unsigned char getSpaceLength() { return charset_space_length; } - const unsigned char *getSpace() { return (const unsigned char*)charset_space_character; } - - CsConvert *getConvToUnicode() { return charset_to_unicode; } - CsConvert *getConvFromUnicode() { return charset_from_unicode; } + CsConvert getConvToUnicode() { assert(cs); return &cs->charset_to_unicode; } + CsConvert getConvFromUnicode() { assert(cs); return &cs->charset_from_unicode; } -protected: - CHARSET_ID charset_id; - const char *charset_name; - unsigned char charset_min_bytes_per_char; - unsigned char charset_max_bytes_per_char; - unsigned char charset_space_length; - const char *charset_space_character; - - CsConvert *charset_to_unicode; - CsConvert *charset_from_unicode; - -/* These need to be moved elsewhere. They don't belong in this interface - VEC charset_converters; - VEC charset_collations; -*/ + friend bool operator ==(const CharSet& cs1, const CharSet& cs2); + friend bool operator !=(const CharSet& cs1, const CharSet& cs2); +private: + struct charset *cs; }; -/* values for charset_flags */ +static inline bool operator ==(const CharSet& cs1, const CharSet& cs2) { + return cs1.cs == cs2.cs; +} -#define CHARSET_init 1 -#define CHARSET_narrow 2 -#define CHARSET_multi 4 -#define CHARSET_wide 8 - - -typedef CharSet *(*CharSetAllocFunc)(MemoryPool&, CHARSET_ID, CHARSET_ID); -typedef TextType *(*TextTypeAllocFunc)(MemoryPool&, CHARSET_ID, CHARSET_ID); -typedef CsConvert *(*CsConvertAllocFunc)(MemoryPool&, CHARSET_ID, CHARSET_ID); +static inline bool operator !=(const CharSet& cs1, const CharSet& cs2) { + return cs1.cs != cs2.cs; +} #endif /* JRD_INTL_CLASSES_H */ diff --git a/src/jrd/intl_proto.h b/src/jrd/intl_proto.h index aa1cb01b5f..3dfe74744e 100644 --- a/src/jrd/intl_proto.h +++ b/src/jrd/intl_proto.h @@ -26,34 +26,35 @@ #include "../jrd/intl_classes.h" -CHARSET_ID INTL_charset(TDBB, USHORT, FPTR_VOID); -int INTL_compare(TDBB, const struct dsc*, const struct dsc*, FPTR_VOID); +CHARSET_ID INTL_charset(TDBB, USHORT, FPTR_STATUS); +int INTL_compare(TDBB, const struct dsc*, const struct dsc*, FPTR_STATUS); USHORT INTL_convert_bytes(TDBB, CHARSET_ID, UCHAR *, USHORT, CHARSET_ID, - BYTE *, USHORT, FPTR_VOID); -CsConvert* INTL_convert_lookup(TDBB, CHARSET_ID, CHARSET_ID); -int INTL_convert_string(struct dsc*, const struct dsc*, FPTR_VOID); + BYTE *, USHORT, FPTR_STATUS); +CsConvert INTL_convert_lookup(TDBB, CHARSET_ID, CHARSET_ID); +int INTL_convert_string(struct dsc*, const struct dsc*, FPTR_STATUS); int INTL_data(const struct dsc*); int INTL_data_or_binary(const struct dsc*); int INTL_defined_type(TDBB, ISC_STATUS *, SSHORT); -//SSHORT INTL_fss_mbtowc(struct texttype **, unsigned short *, -// unsigned char *, USHORT); -//USHORT INTL_fss_to_unicode(CsConvert *, USHORT *, -// USHORT, unsigned char *, USHORT, -// SSHORT *, USHORT *); -unsigned short INTL_getch(TDBB, TextType**, SSHORT, +unsigned short INTL_getch(TDBB, TextType*, SSHORT, UCHAR **, USHORT *); void INTL_init(TDBB); USHORT INTL_key_length(TDBB, USHORT, USHORT); -CharSet* INTL_charset_lookup(TDBB tdbb, SSHORT parm1, ISC_STATUS * status); -TextType* INTL_texttype_lookup(TDBB tdbb, SSHORT parm1, FPTR_VOID err, +CharSet INTL_charset_lookup(TDBB tdbb, SSHORT parm1, ISC_STATUS * status); +TextType INTL_texttype_lookup(TDBB tdbb, SSHORT parm1, FPTR_STATUS err, ISC_STATUS * status); -//void* INTL_obj_lookup(TDBB, USHORT, SSHORT, FPTR_VOID, ISC_STATUS *); void INTL_pad_spaces(TDBB, struct dsc *, UCHAR *, USHORT); USHORT INTL_string_to_key(TDBB, USHORT, struct dsc *, struct dsc *, USHORT); int INTL_str_to_upper(TDBB, struct dsc *); -//USHORT INTL_unicode_to_fss(CsConvert *, unsigned char *, USHORT, -// USHORT *, USHORT, SSHORT *, USHORT *); UCHAR INTL_upper(TDBB, USHORT, UCHAR); +// Built-in charsets interface +FPTR_SHORT INTL_builtin_lookup(USHORT, SSHORT, SSHORT); +SSHORT INTL_builtin_nc_mbtowc(TEXTTYPE obj, + WCHAR * wc, UCHAR * ptr, USHORT count); +SSHORT INTL_builtin_mb_mbtowc(TEXTTYPE obj, + WCHAR * wc, UCHAR * ptr, USHORT count); +SSHORT INTL_builtin_wc_mbtowc(TEXTTYPE obj, + WCHAR * wc, UCHAR * ptr, USHORT count); + #endif // JRD_INTL_PROTO_H diff --git a/src/jrd/intlobj.h b/src/jrd/intlobj.h index fefb1e6254..ac6e6c7fa8 100644 --- a/src/jrd/intlobj.h +++ b/src/jrd/intlobj.h @@ -31,21 +31,21 @@ extern "C" { #endif -#define USHORT unsigned short -#define SSHORT short -#define UCHAR unsigned char -#define CHAR char -#define SCHAR char -#define ULONG unsigned long -#define LONG long -#define SLONG signed long -#define VEC void* -#define BYTE unsigned char +#ifndef INCLUDE_FB_TYPES_H +typedef unsigned short USHORT; +typedef short SSHORT; +typedef unsigned char UCHAR; +typedef char CHAR; +typedef char SCHAR; +typedef unsigned char BYTE; -/* duplicate definition from flu.c */ +#pragma FB_COMPILER_MESSAGE("64-bit readiness problem!") +typedef unsigned long ULONG; +typedef long LONG; +typedef signed long SLONG; +#endif typedef SSHORT(*FPTR_short) (); -#ifndef INTL_ENGINE_INTERNAL typedef USHORT(*FPTR_SHORT) (); typedef SSHORT CHARSET_ID; @@ -55,12 +55,14 @@ typedef SCHAR ASCII; typedef unsigned char NCHAR; /* Narrow Char */ typedef unsigned short UCS2_CHAR; /* Not very Wide Char */ typedef unsigned char MBCHAR; /* Multibyte Char */ +typedef class vec* VEC; #define type_texttype 54 #define type_charset 55 #define type_csconvert 56 -#define MAX_KEY 256 +#ifndef JRD_CONSTANTS_H +#define MAX_KEY 256 #endif typedef struct intl_blk { @@ -98,12 +100,17 @@ typedef struct texttype { FPTR_SHORT texttype_fn_to_lower; /* One ch to lowercase */ FPTR_short texttype_fn_str_to_upper; /* Convert string to uppercase */ FPTR_SHORT texttype_fn_to_wc; /* convert string to wc */ + + // INTERNAL FUNCTIONS - do not implement in collation drivers ! FPTR_SHORT texttype_fn_contains; /* s1 contains s2? */ FPTR_SHORT texttype_fn_like; /* s1 like s2? */ FPTR_SHORT texttype_fn_matches; /* s1 matches s2 */ FPTR_SHORT texttype_fn_sleuth_check; /* s1 sleuth s2 */ FPTR_SHORT texttype_fn_sleuth_merge; /* aux function for sleuth */ + //\\ END OF INTERNAL FUNCTIONS + FPTR_short texttype_fn_mbtowc; /* get next character */ + BYTE *texttype_collation_table; BYTE *texttype_toupper_table; BYTE *texttype_tolower_table; diff --git a/src/jrd/mov.cpp b/src/jrd/mov.cpp index 4aec5c400f..1c32d5c6c3 100644 --- a/src/jrd/mov.cpp +++ b/src/jrd/mov.cpp @@ -54,7 +54,7 @@ int MOV_compare(const dsc* arg1, const dsc* arg2) * **************************************/ - return CVT2_compare(arg1, arg2, (FPTR_VOID) ERR_post); + return CVT2_compare(arg1, arg2, ERR_post); } @@ -72,7 +72,7 @@ double MOV_date_to_double(const dsc* desc) * **************************************/ - return CVT_date_to_double(desc, (FPTR_VOID) ERR_post); + return CVT_date_to_double(desc, ERR_post); } @@ -125,7 +125,7 @@ void MOV_double_to_date(double real, SLONG fixed[2]) * **************************************/ - CVT_double_to_date(real, fixed, (FPTR_VOID) ERR_post); + CVT_double_to_date(real, fixed, ERR_post); } @@ -298,7 +298,7 @@ double MOV_get_double(const dsc* desc) * **************************************/ - return CVT_get_double(desc, (FPTR_VOID) ERR_post); + return CVT_get_double(desc, ERR_post); } @@ -316,7 +316,7 @@ SLONG MOV_get_long(const dsc* desc, SSHORT scale) * **************************************/ - return CVT_get_long(desc, scale, (FPTR_VOID) ERR_post); + return CVT_get_long(desc, scale, ERR_post); } @@ -334,7 +334,7 @@ SINT64 MOV_get_int64(const dsc* desc, SSHORT scale) * **************************************/ - return CVT_get_int64(desc, scale, (FPTR_VOID) ERR_post); + return CVT_get_int64(desc, scale, ERR_post); } @@ -356,7 +356,7 @@ void MOV_get_metadata_str(const dsc* desc, TEXT* buffer, USHORT buffer_length) UCHAR *ptr; USHORT length = CVT_get_string_ptr(desc, &dummy_type, &ptr, - NULL, 0, (FPTR_VOID) ERR_post); + NULL, 0, ERR_post); #ifdef DEV_BUILD if ((dummy_type != ttype_metadata) && @@ -383,7 +383,7 @@ void MOV_get_name(const dsc* desc, TEXT* string) * **************************************/ - CVT2_get_name(desc, string, (FPTR_VOID) ERR_post); + CVT2_get_name(desc, string, ERR_post); } @@ -401,7 +401,7 @@ SQUAD MOV_get_quad(const dsc* desc, SSHORT scale) * **************************************/ - return CVT_get_quad(desc, scale, (FPTR_VOID) ERR_post); + return CVT_get_quad(desc, scale, ERR_post); } @@ -427,8 +427,7 @@ int MOV_get_string_ptr( * **************************************/ - return CVT_get_string_ptr(desc, ttype, address, temp, length, - (FPTR_VOID) ERR_post); + return CVT_get_string_ptr(desc, ttype, address, temp, length, ERR_post); } @@ -462,7 +461,7 @@ GDS_DATE MOV_get_sql_date(const dsc* desc) * **************************************/ - return CVT_get_sql_date(desc, (FPTR_VOID) ERR_post); + return CVT_get_sql_date(desc, ERR_post); } @@ -479,7 +478,7 @@ GDS_TIME MOV_get_sql_time(const dsc* desc) * **************************************/ - return CVT_get_sql_time(desc, (FPTR_VOID) ERR_post); + return CVT_get_sql_time(desc, ERR_post); } @@ -496,7 +495,7 @@ GDS_TIMESTAMP MOV_get_timestamp(const dsc* desc) * **************************************/ - return CVT_get_timestamp(desc, (FPTR_VOID) ERR_post); + return CVT_get_timestamp(desc, ERR_post); } @@ -525,8 +524,7 @@ int MOV_make_string(const dsc* desc, * **************************************/ - return CVT_make_string(desc, ttype, address, temp, length, - (FPTR_VOID) ERR_post); + return CVT_make_string(desc, ttype, address, temp, length, ERR_post); } @@ -556,8 +554,7 @@ int MOV_make_string2( * **************************************/ - return CVT2_make_string2(desc, ttype, address, temp, length, ptr, - (FPTR_VOID) ERR_post); + return CVT2_make_string2(desc, ttype, address, temp, length, ptr, ERR_post); } @@ -574,7 +571,7 @@ void MOV_move(const dsc* from, dsc* to) * **************************************/ - CVT_move(from, to, (FPTR_VOID) ERR_post); + CVT_move(from, to, ERR_post); } diff --git a/src/jrd/opt.cpp b/src/jrd/opt.cpp index 0dfae00016..fee51df6ee 100644 --- a/src/jrd/opt.cpp +++ b/src/jrd/opt.cpp @@ -6155,7 +6155,7 @@ static JRD_NOD optimize_like(TDBB tdbb, JRD_NOD like_node) USHORT ch, escape_ch; USHORT p_count; UCHAR tmp_buffer[32]; /* large enough to hold 1 ch of escape string */ - TextType *text_obj; + TextType text_obj = NULL; SET_TDBB(tdbb); DEV_BLKCHK(like_node, type_nod); JRD_NOD search_node = like_node->nod_arg[1]; @@ -6173,7 +6173,6 @@ static JRD_NOD optimize_like(TDBB tdbb, JRD_NOD like_node) (escape_node && escape_desc->dsc_dtype > dtype_any_text)) return NULL; /* Get the escape character, if any */ - text_obj = NULL; if (escape_node) { /* Ensure escape string is same character set as search string diff --git a/src/jrd/par.cpp b/src/jrd/par.cpp index a1a546cd0d..9de7655eb8 100644 --- a/src/jrd/par.cpp +++ b/src/jrd/par.cpp @@ -1382,7 +1382,7 @@ static JRD_NOD par_literal(TDBB tdbb, CSB csb) l = BLR_WORD; q = csb->csb_running; dtype = - CVT_get_numeric(q, l, &scale, (double *) p, (FPTR_VOID) ERR_post); + CVT_get_numeric(q, l, &scale, (double *) p, ERR_post); literal->lit_desc.dsc_dtype = dtype; if (dtype == dtype_double) literal->lit_desc.dsc_length = sizeof(double); diff --git a/src/jrd/quad.cpp b/src/jrd/quad.cpp index 200dd42aaa..4bd8bf07b3 100644 --- a/src/jrd/quad.cpp +++ b/src/jrd/quad.cpp @@ -34,11 +34,7 @@ extern "C" { -#pragma FB_COMPILER_MESSAGE("Fix this! Ugly function pointer cast!") -typedef void (*pfn_quad_private_cludge) (int, int); - - -SQUAD QUAD_add(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) +SQUAD QUAD_add(SQUAD * arg1, SQUAD * arg2, FPTR_STATUS err) { /************************************** * @@ -51,7 +47,7 @@ SQUAD QUAD_add(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) * **************************************/ - reinterpret_cast < pfn_quad_private_cludge > (err) (gds_badblk, 0); /* not really badblk, but internal error */ + (*err) (gds_badblk, 0); /* not really badblk, but internal error */ /* IBERROR (224); *//* msg 224 quad word arithmetic not supported */ SQUAD temp = { 0, 0 }; @@ -84,7 +80,7 @@ SSHORT QUAD_compare(SQUAD * arg1, SQUAD * arg2) } -SQUAD QUAD_from_double(double *d, FPTR_VOID err) +SQUAD QUAD_from_double(double *d, FPTR_STATUS err) { /************************************** * @@ -97,7 +93,7 @@ SQUAD QUAD_from_double(double *d, FPTR_VOID err) * **************************************/ - reinterpret_cast < pfn_quad_private_cludge > (err) (gds_badblk, 0); /* not really badblk, but internal error */ + (*err) (gds_badblk, 0); /* not really badblk, but internal error */ /* BUGCHECK (190); *//* msg 190 conversion not supported for */ /* specified data types */ @@ -107,7 +103,7 @@ SQUAD QUAD_from_double(double *d, FPTR_VOID err) } -SQUAD QUAD_multiply(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) +SQUAD QUAD_multiply(SQUAD * arg1, SQUAD * arg2, FPTR_STATUS err) { /************************************** * @@ -120,7 +116,7 @@ SQUAD QUAD_multiply(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) * **************************************/ - reinterpret_cast < pfn_quad_private_cludge > (err) (gds_badblk, 0); /* not really badblk, but internal error */ + (*err) (gds_badblk, 0); /* not really badblk, but internal error */ /* IBERROR (224); *//* msg 224 quad word arithmetic not supported */ SQUAD temp = { 0, 0 }; @@ -128,7 +124,7 @@ SQUAD QUAD_multiply(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) } -SQUAD QUAD_negate(SQUAD * arg1, FPTR_VOID err) +SQUAD QUAD_negate(SQUAD * arg1, FPTR_STATUS err) { /************************************** * @@ -141,7 +137,7 @@ SQUAD QUAD_negate(SQUAD * arg1, FPTR_VOID err) * **************************************/ - reinterpret_cast < pfn_quad_private_cludge > (err) (gds_badblk, 0); /* not really badblk, but internal error */ + (*err) (gds_badblk, 0); /* not really badblk, but internal error */ /* IBERROR (224); *//* msg 224 quad word arithmetic not supported */ SQUAD temp = { 0, 0 }; @@ -149,7 +145,7 @@ SQUAD QUAD_negate(SQUAD * arg1, FPTR_VOID err) } -SQUAD QUAD_subtract(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) +SQUAD QUAD_subtract(SQUAD * arg1, SQUAD * arg2, FPTR_STATUS err) { /************************************** * @@ -162,7 +158,7 @@ SQUAD QUAD_subtract(SQUAD * arg1, SQUAD * arg2, FPTR_VOID err) * **************************************/ - reinterpret_cast < pfn_quad_private_cludge > (err) (gds_badblk, 0); /* not really badblk, but internal error */ + (*err) (gds_badblk, 0); /* not really badblk, but internal error */ /* IBERROR (224); *//* msg 224 quad word arithmetic not supported */ SQUAD temp = { 0, 0 }; diff --git a/src/jrd/quad_proto.h b/src/jrd/quad_proto.h index d091d71f3c..27fd60d053 100644 --- a/src/jrd/quad_proto.h +++ b/src/jrd/quad_proto.h @@ -42,12 +42,12 @@ extern "C" { #endif -SQUAD QUAD_add(SQUAD *, SQUAD *, FPTR_VOID); +SQUAD QUAD_add(SQUAD *, SQUAD *, FPTR_STATUS); SSHORT QUAD_compare(SQUAD *, SQUAD *); -SQUAD QUAD_from_double(double *, FPTR_VOID); -SQUAD QUAD_multiply(SQUAD *, SQUAD *, FPTR_VOID); -SQUAD QUAD_negate(SQUAD *, FPTR_VOID); -SQUAD QUAD_subtract(SQUAD *, SQUAD *, FPTR_VOID); +SQUAD QUAD_from_double(double *, FPTR_STATUS); +SQUAD QUAD_multiply(SQUAD *, SQUAD *, FPTR_STATUS); +SQUAD QUAD_negate(SQUAD *, FPTR_STATUS); +SQUAD QUAD_subtract(SQUAD *, SQUAD *, FPTR_STATUS); #ifdef __cplusplus } /* extern "C" */ diff --git a/src/remote/interface.cpp b/src/remote/interface.cpp index 9e99142896..374a9ebba1 100644 --- a/src/remote/interface.cpp +++ b/src/remote/interface.cpp @@ -6211,7 +6211,7 @@ static ISC_STATUS mov_dsql_message( UCHAR* from_msg, to = *to_desc; from.dsc_address = from_msg + (SLONG) from.dsc_address; to.dsc_address = to_msg + (SLONG) to.dsc_address; - CVT_move(&from, &to, (FPTR_VOID) move_error); + CVT_move(&from, &to, move_error); } } // try