8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 00:03:02 +01:00

Work on collation attributes:

1) Define a common format for it
2) Merge attributes of the base collation in the attributes of the derived one
This commit is contained in:
asfernandes 2006-07-30 20:31:25 +00:00
parent 74f67c23a9
commit c13b4cc61a
25 changed files with 603 additions and 92 deletions

View File

@ -50,7 +50,8 @@ INTL_Files1= ld.cpp cv_narrow.cpp \
cs_gb2312.cpp cv_gb2312.cpp lc_gb2312.cpp \
cs_jis.cpp cv_jis.cpp lc_jis.cpp \
cs_ksc.cpp cv_ksc.cpp lc_ksc.cpp \
cs_icu.cpp cv_icu.cpp lc_icu.cpp
cs_icu.cpp cv_icu.cpp lc_icu.cpp \
../jrd/IntlUtil.cpp
# INTL_Sources = $(INTL_Files1)

View File

@ -43,7 +43,7 @@ JRD_ServerFiles= blob_filter.cpp dpm.epp dyn.epp dyn_def.epp \
sdw.cpp shut.cpp sort.cpp sqz.cpp \
svc.cpp sym.cpp TempSpace.cpp tpc.cpp tra.cpp validation.cpp vio.cpp \
nodebug.cpp nbak.cpp sha.cpp $(Physical_IO_Module) ThreadData.cpp thd.cpp \
unicode_util.cpp
unicode_util.cpp IntlUtil.cpp
JRD_Files = $(JRD_ClientFiles) $(JRD_ServerFiles)

View File

@ -305,6 +305,10 @@ SOURCE=..\..\..\src\jrd\IntlManager.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\inuse.cpp
# End Source File
# Begin Source File
@ -912,6 +916,10 @@ SOURCE=..\..\..\src\jrd\intlobj_new.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\inuse_proto.h
# End Source File
# Begin Source File

View File

@ -296,6 +296,10 @@ SOURCE=..\..\..\src\jrd\IntlManager.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\inuse.cpp
# End Source File
# Begin Source File
@ -881,6 +885,10 @@ SOURCE=..\..\..\src\jrd\intlobj_new.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\inuse_proto.h
# End Source File
# Begin Source File

View File

@ -284,6 +284,10 @@ SOURCE=..\..\..\src\jrd\IntlManager.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\inuse.cpp
# End Source File
# Begin Source File
@ -885,6 +889,10 @@ SOURCE=..\..\..\src\jrd\intlobj_new.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\inuse_proto.h
# End Source File
# Begin Source File

View File

@ -529,6 +529,10 @@ SOURCE=..\..\..\src\intl\collations\db866ru0.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.h
# End Source File
# Begin Source File
SOURCE=..\..\..\src\intl\kanji.h
# End Source File
# Begin Source File
@ -735,6 +739,10 @@ SOURCE=..\..\..\src\common\classes\alloc.cpp
SOURCE=..\..\..\src\common\fb_exception.cpp
# End Source File
# Begin Source File
SOURCE=..\..\..\src\jrd\IntlUtil.cpp
# End Source File
# End Group
# Begin Source File

View File

@ -255,6 +255,9 @@
<File
RelativePath="..\..\..\src\jrd\IntlManager.cpp">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp">
</File>
<File
RelativePath="..\..\..\src\jrd\inuse.cpp">
</File>
@ -673,6 +676,9 @@
<File
RelativePath="..\..\..\src\jrd\intlobj_new.h">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h">
</File>
<File
RelativePath="..\..\..\src\jrd\inuse_proto.h">
</File>

View File

@ -255,6 +255,9 @@
<File
RelativePath="..\..\..\src\jrd\IntlManager.cpp">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp">
</File>
<File
RelativePath="..\..\..\src\jrd\inuse.cpp">
</File>
@ -673,6 +676,9 @@
<File
RelativePath="..\..\..\src\jrd\intlobj_new.h">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h">
</File>
<File
RelativePath="..\..\..\src\jrd\inuse_proto.h">
</File>

View File

@ -259,6 +259,9 @@
<File
RelativePath="..\..\..\src\jrd\IntlManager.cpp">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp">
</File>
<File
RelativePath="..\..\..\src\jrd\inuse.cpp">
</File>
@ -674,6 +677,9 @@
<File
RelativePath="..\..\..\src\jrd\intlobj_new.h">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h">
</File>
<File
RelativePath="..\..\..\src\jrd\inuse_proto.h">
</File>

View File

@ -482,6 +482,9 @@
<File
RelativePath="..\..\..\src\intl\collations\db866ru0.h">
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h">
</File>
<File
RelativePath="..\..\..\src\intl\kanji.h">
</File>
@ -652,6 +655,16 @@
<File
RelativePath="..\..\..\src\common\fb_exception.cpp">
</File>
<File
RelativePath="..\..\..\src\common\classes\fb_string.cpp">
</File>
</Filter>
<Filter
Name="JRD files"
Filter="">
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp">
</File>
</Filter>
<File
RelativePath="..\defs\intl.def">

View File

@ -344,6 +344,10 @@
RelativePath="..\..\..\src\jrd\IntlManager.cpp"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp"
>
</File>
<File
RelativePath="..\..\..\src\jrd\inuse.cpp"
>
@ -900,6 +904,10 @@
RelativePath="..\..\..\src\jrd\intlobj_new.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\inuse_proto.h"
>

View File

@ -344,6 +344,10 @@
RelativePath="..\..\..\src\jrd\IntlManager.cpp"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp"
>
</File>
<File
RelativePath="..\..\..\src\jrd\inuse.cpp"
>
@ -900,6 +904,10 @@
RelativePath="..\..\..\src\jrd\intlobj_new.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\inuse_proto.h"
>

View File

@ -348,6 +348,10 @@
RelativePath="..\..\..\src\jrd\IntlManager.cpp"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp"
>
</File>
<File
RelativePath="..\..\..\src\jrd\inuse.cpp"
>
@ -900,6 +904,10 @@
RelativePath="..\..\..\src\jrd\intlobj_new.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\inuse_proto.h"
>

View File

@ -652,6 +652,10 @@
RelativePath="..\..\..\src\intl\collations\db866ru0.h"
>
</File>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.h"
>
</File>
<File
RelativePath="..\..\..\src\intl\kanji.h"
>
@ -877,6 +881,14 @@
>
</File>
</Filter>
<Filter
Name="JRD files"
>
<File
RelativePath="..\..\..\src\jrd\IntlUtil.cpp"
>
</File>
</Filter>
<File
RelativePath="..\defs\intl.def"
>

View File

@ -116,6 +116,16 @@ public:
return false;
}
bool getFirst() { return tree.getFirst(); }
bool getLast() { return tree.getLast(); }
bool getNext() { return tree.getNext(); }
bool getPrev() { return tree.getPrev(); }
KeyValuePair* current() const { return tree.current(); }
bool exist(const KeyType& key)
{
return tree.locate(key);

View File

@ -24,7 +24,8 @@
#include "firebird.h"
#include "../intl/ldcommon.h"
#include "ld_proto.h"
#include "../intl/ld_proto.h"
#include "../jrd/IntlUtil.h"
static ULONG fam2_str_to_upper(TEXTTYPE obj, ULONG iLen, const BYTE* pStr, ULONG iOutLen, BYTE *pOutStr);
static ULONG fam2_str_to_lower(TEXTTYPE obj, ULONG iLen, const BYTE* pStr, ULONG iOutLen, BYTE *pOutStr);
@ -32,7 +33,11 @@ static ULONG fam2_str_to_lower(TEXTTYPE obj, ULONG iLen, const BYTE* pStr, ULONG
#include "lc_narrow.h"
#include "lc_dos.h"
using namespace Firebird;
static inline bool FAMILY2(TEXTTYPE cache,
charset* cs,
SSHORT country,
USHORT flags,
const SortOrderTblEntry* NoCaseOrderTbl,
@ -44,11 +49,18 @@ static inline bool FAMILY2(TEXTTYPE cache,
USHORT attributes,
const UCHAR* specific_attributes,
ULONG specific_attributes_length)
//#define FAMILY2(id_number, name, charset, country)
{
if ((attributes & ~TEXTTYPE_ATTR_PAD_SPACE) || specific_attributes_length)
return false;
IntlUtil::SpecificAttributesMap map;
if (!IntlUtil::parseSpecificAttributes(cs, specific_attributes_length, specific_attributes, &map) ||
map.count() != 0)
{
return false;
}
cache->texttype_version = TEXTTYPE_VERSION_1;
cache->texttype_name = POSIX;
cache->texttype_country = country;
@ -73,6 +85,7 @@ static inline bool FAMILY2(TEXTTYPE cache,
static inline bool FAMILY3(TEXTTYPE cache,
charset* cs,
SSHORT country,
USHORT flags,
const SortOrderTblEntry* NoCaseOrderTbl,
@ -87,21 +100,28 @@ static inline bool FAMILY3(TEXTTYPE cache,
{
bool multiLevel = false;
if (specific_attributes_length == 13)
IntlUtil::SpecificAttributesMap map;
if (!IntlUtil::parseSpecificAttributes(cs, specific_attributes_length, specific_attributes, &map))
return false;
string value;
if (map.get("MULTI-LEVEL", value))
{
if (memcmp(specific_attributes, "MULTI-LEVEL=0", 13) == 0)
{
if (value == "0")
multiLevel = false;
specific_attributes_length = 0;
}
else if (memcmp(specific_attributes, "MULTI-LEVEL=1", 13) == 0)
{
else if (value == "1")
multiLevel = true;
specific_attributes_length = 0;
}
else
return false;
map.remove("MULTI-LEVEL");
}
if (FAMILY2(cache, country, flags, NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
string newSpecificAttributes = IntlUtil::generateSpecificAttributes(cs, map);
specific_attributes = (const UCHAR*)newSpecificAttributes.begin();
specific_attributes_length = newSpecificAttributes.length();
if (FAMILY2(cache, cs, country, flags, NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX,
attributes & ~(TEXTTYPE_ATTR_CASE_INSENSITIVE | TEXTTYPE_ATTR_ACCENT_INSENSITIVE),
specific_attributes, specific_attributes_length))
@ -154,7 +174,7 @@ TEXTTYPE_ENTRY(KOI8R_c1_init)
#include "../intl/collations/koi8r_ru.h"
return FAMILY2(cache, CC_RUSSIA, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_RUSSIA, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -166,7 +186,7 @@ TEXTTYPE_ENTRY(KOI8U_c1_init)
#include "../intl/collations/koi8u_ua.h"
return FAMILY2(cache, CC_INTL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_INTL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -178,7 +198,7 @@ TEXTTYPE_ENTRY(ISO88591_39_init)
#include "../intl/collations/bl88591da0.h"
return FAMILY2(cache, CC_DENMARK, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_DENMARK, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -190,7 +210,7 @@ TEXTTYPE_ENTRY(ISO88591_40_init)
#include "../intl/collations/bl88591nl0.h"
return FAMILY2(cache, CC_NEDERLANDS, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_NEDERLANDS, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -202,7 +222,7 @@ TEXTTYPE_ENTRY(ISO88591_41_init)
#include "../intl/collations/bl88591fi0.h"
return FAMILY2(cache, CC_FINLAND, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_FINLAND, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -214,7 +234,7 @@ TEXTTYPE_ENTRY(ISO88591_42_init)
#include "../intl/collations/bl88591fr0.h"
return FAMILY2(cache, CC_FRANCE, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_FRANCE, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -226,7 +246,7 @@ TEXTTYPE_ENTRY(ISO88591_43_init)
#include "../intl/collations/bl88591ca0.h"
return FAMILY2(cache, CC_FRENCHCAN, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_FRENCHCAN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -238,7 +258,7 @@ TEXTTYPE_ENTRY(ISO88591_44_init)
#include "../intl/collations/bl88591de0.h"
return FAMILY2(cache, CC_GERMANY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_GERMANY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -250,7 +270,7 @@ TEXTTYPE_ENTRY(ISO88591_45_init)
#include "../intl/collations/bl88591is0.h"
return FAMILY2(cache, CC_ICELAND, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_ICELAND, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -262,7 +282,7 @@ TEXTTYPE_ENTRY(ISO88591_46_init)
#include "../intl/collations/bl88591it0.h"
return FAMILY2(cache, CC_ITALY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_ITALY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -275,7 +295,7 @@ TEXTTYPE_ENTRY(ISO88591_48_init)
#include "../intl/collations/bl88591no0.h"
return FAMILY2(cache, CC_NORWAY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_NORWAY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -287,7 +307,7 @@ TEXTTYPE_ENTRY(ISO88591_49_init)
#include "../intl/collations/bl88591es0.h"
return FAMILY3(cache, CC_SPAIN, LDRV_TIEBREAK,
return FAMILY3(cache, cs, CC_SPAIN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -299,7 +319,7 @@ TEXTTYPE_ENTRY(ISO88591_51_init)
#include "../intl/collations/bl88591sv0.h"
return FAMILY2(cache, CC_SWEDEN, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_SWEDEN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -311,7 +331,7 @@ TEXTTYPE_ENTRY(ISO88591_52_init)
#include "../intl/collations/bl88591uk0.h"
return FAMILY2(cache, CC_UK, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_UK, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -323,7 +343,7 @@ TEXTTYPE_ENTRY(ISO88591_53_init)
#include "../intl/collations/bl88591us0.h"
return FAMILY2(cache, CC_US, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_US, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -335,7 +355,7 @@ TEXTTYPE_ENTRY(ISO88591_54_init)
#include "../intl/collations/bl88591pt0.h"
return FAMILY2(cache, CC_PORTUGAL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_PORTUGAL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -347,7 +367,7 @@ TEXTTYPE_ENTRY(ISO88591_55_init)
#include "../intl/collations/bl88591ptbr0.h"
return FAMILY3(cache, CC_BRAZIL, LDRV_TIEBREAK,
return FAMILY3(cache, cs, CC_BRAZIL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -359,7 +379,7 @@ TEXTTYPE_ENTRY(ISO88591_56_init)
#include "../intl/collations/bl88591es0.h"
return FAMILY3(cache, CC_SPAIN, LDRV_TIEBREAK,
return FAMILY3(cache, cs, CC_SPAIN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -371,7 +391,7 @@ TEXTTYPE_ENTRY(WIN1250_c1_init)
#include "../intl/collations/pw1250czech.h"
return FAMILY2(cache, CC_CZECH, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_CZECH, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -383,7 +403,7 @@ TEXTTYPE_ENTRY(WIN1250_c2_init)
#include "../intl/collations/pw1250hundc.h"
return FAMILY2(cache, CC_HUNGARY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_HUNGARY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -395,7 +415,7 @@ TEXTTYPE_ENTRY(WIN1250_c3_init)
#include "../intl/collations/pw1250polish.h"
return FAMILY2(cache, CC_POLAND, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_POLAND, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -407,7 +427,7 @@ TEXTTYPE_ENTRY(WIN1250_c4_init)
#include "../intl/collations/pw1250slov.h"
return FAMILY2(cache, CC_YUGOSLAVIA, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_YUGOSLAVIA, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -419,7 +439,7 @@ TEXTTYPE_ENTRY (WIN1250_c5_init)
#include "../intl/collations/pw1250hun.h"
return FAMILY2(cache, CC_HUNGARY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_HUNGARY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -431,7 +451,7 @@ TEXTTYPE_ENTRY(WIN1250_c6_init)
#include "../intl/collations/win1250bsba.h"
return FAMILY2(cache, CC_YUGOSLAVIA, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_YUGOSLAVIA, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -443,7 +463,7 @@ TEXTTYPE_ENTRY(WIN1250_c7_init)
#include "../intl/collations/win_cz.h"
return FAMILY3(cache, CC_CZECH, LDRV_TIEBREAK,
return FAMILY3(cache, cs, CC_CZECH, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -455,7 +475,7 @@ TEXTTYPE_ENTRY(WIN1250_c8_init)
#include "../intl/collations/win_cz_ci_ai.h"
return FAMILY3(cache, CC_CZECH, LDRV_TIEBREAK,
return FAMILY3(cache, cs, CC_CZECH, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -467,7 +487,7 @@ TEXTTYPE_ENTRY(WIN1251_c1_init)
#include "../intl/collations/pw1251cyrr.h"
return FAMILY2(cache, CC_RUSSIA, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_RUSSIA, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -479,7 +499,7 @@ TEXTTYPE_ENTRY(WIN1251_c2_init)
#include "../intl/collations/xx1251_ua.h"
return FAMILY2(cache, CC_RUSSIA, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_RUSSIA, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -491,7 +511,7 @@ TEXTTYPE_ENTRY(WIN1252_c1_init)
#include "../intl/collations/pw1252intl.h"
return FAMILY2(cache, CC_INTL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_INTL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -503,7 +523,7 @@ TEXTTYPE_ENTRY(WIN1252_c2_init)
#include "../intl/collations/pw1252i850.h"
return FAMILY2(cache, CC_INTL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_INTL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -515,7 +535,7 @@ TEXTTYPE_ENTRY(WIN1252_c3_init)
#include "../intl/collations/pw1252nor4.h"
return FAMILY2(cache, CC_NORDAN, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_NORDAN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -527,7 +547,7 @@ TEXTTYPE_ENTRY(WIN1252_c4_init)
#include "../intl/collations/pw1252span.h"
return FAMILY2(cache, CC_SPAIN, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_SPAIN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -539,7 +559,7 @@ TEXTTYPE_ENTRY(WIN1252_c5_init)
#include "../intl/collations/pw1252swfn.h"
return FAMILY2(cache, CC_SWEDFIN, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_SWEDFIN, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -551,7 +571,7 @@ TEXTTYPE_ENTRY(WIN1252_c6_init)
#include "../intl/collations/pw1252ptbr.h"
return FAMILY3(cache, CC_BRAZIL, LDRV_TIEBREAK,
return FAMILY3(cache, cs, CC_BRAZIL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -563,7 +583,7 @@ TEXTTYPE_ENTRY(WIN1253_c1_init)
#include "../intl/collations/pw1253greek1.h"
return FAMILY2(cache, CC_GREECE, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_GREECE, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -575,7 +595,7 @@ TEXTTYPE_ENTRY(WIN1254_c1_init)
#include "../intl/collations/pw1254turk.h"
return FAMILY2(cache, CC_TURKEY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_TURKEY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -587,7 +607,7 @@ TEXTTYPE_ENTRY(WIN1257_c1_init)
#include "../intl/collations/win1257_ee.h"
return FAMILY2(cache, CC_INTL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_INTL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -599,7 +619,7 @@ TEXTTYPE_ENTRY(WIN1257_c2_init)
#include "../intl/collations/win1257_lt.h"
return FAMILY2(cache, CC_INTL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_INTL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -611,7 +631,7 @@ TEXTTYPE_ENTRY(WIN1257_c3_init)
#include "../intl/collations/win1257_lv.h"
return FAMILY2(cache, CC_INTL, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_INTL, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -623,7 +643,7 @@ TEXTTYPE_ENTRY(NEXT_c1_init)
#include "../intl/collations/blNEXTus0.h"
return FAMILY2(cache, CC_US, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_US, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -635,7 +655,7 @@ TEXTTYPE_ENTRY(NEXT_c2_init)
#include "../intl/collations/blNEXTde0.h"
return FAMILY2(cache, CC_GERMANY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_GERMANY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -647,7 +667,7 @@ TEXTTYPE_ENTRY(NEXT_c3_init)
#include "../intl/collations/blNEXTfr0.h"
return FAMILY2(cache, CC_FRANCE, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_FRANCE, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}
@ -659,7 +679,7 @@ TEXTTYPE_ENTRY(NEXT_c4_init)
#include "../intl/collations/blNEXTit0.h"
return FAMILY2(cache, CC_ITALY, LDRV_TIEBREAK,
return FAMILY2(cache, cs, CC_ITALY, LDRV_TIEBREAK,
NoCaseOrderTbl, ToUpperConversionTbl, ToLowerConversionTbl,
CompressTbl, ExpansionTbl, POSIX, attributes, specific_attributes, specific_attributes_length);
}

View File

@ -38,7 +38,7 @@
void gds__log(UCHAR*, ...);
*/
#define EXTERN_texttype(name) INTL_BOOL name (TEXTTYPE, const ASCII*, const ASCII*, USHORT, const UCHAR*, ULONG)
#define EXTERN_texttype(name) INTL_BOOL name (TEXTTYPE, charset*, const ASCII*, const ASCII*, USHORT, const UCHAR*, ULONG)
// #define EXTERN_convert(name) INTL_BOOL name (csconvert*, const ASCII*, const ASCII*)
#define EXTERN_charset(name) INTL_BOOL name (charset*, const ASCII*)
@ -334,32 +334,47 @@ INTL_BOOL FB_DLL_EXPORT LD_lookup_texttype(texttype* tt, const ASCII* texttype_n
try
{
#define CHARSET(cs_name, cs_id, coll_id, bytes, num, cs_symbol, cp_symbol, coll_attr) \
if (strcmp(charset_name, cs_name) == 0) { \
if (strcmp(charset_name, cs_name) == 0) \
{ \
EXTERN_charset((*lookup_cs_symbol)) = cs_symbol; \
EXTERN_texttype((*lookup_symbol)) = cp_symbol; \
\
if (lookup_symbol != NULL && strcmp(texttype_name, cs_name) == 0) \
charset cs; \
memset(&cs, 0, sizeof(cs)); \
\
if (lookup_cs_symbol != NULL && lookup_cs_symbol(&cs, charset_name) && \
lookup_symbol != NULL && strcmp(texttype_name, cs_name) == 0) \
{ \
return lookup_symbol( \
tt, texttype_name, charset_name, \
INTL_BOOL ret = lookup_symbol( \
tt, &cs, texttype_name, charset_name, \
(ignore_attributes ? coll_attr : attributes), \
(ignore_attributes ? NULL : specific_attributes), \
(ignore_attributes ? 0 : specific_attributes_length)); \
} \
}
\
if (cs.charset_fn_destroy) \
cs.charset_fn_destroy(&cs); \
\
return ret; \
}
#define CSALIAS(name, cs_id)
#define END_CHARSET }
#define END_CHARSET \
}
#define COLLATION(tt_name, cc_id, cs_id, coll_id, symbol, coll_attr) \
{ \
EXTERN_texttype((*lookup_symbol)) = symbol; \
\
if (lookup_symbol && strcmp(texttype_name, tt_name) == 0) \
{ \
return lookup_symbol( \
tt, texttype_name, charset_name, \
INTL_BOOL ret = lookup_symbol( \
tt, &cs, texttype_name, charset_name, \
(ignore_attributes ? coll_attr : attributes), \
(ignore_attributes ? NULL : specific_attributes), \
(ignore_attributes ? 0 : specific_attributes_length)); \
\
if (cs.charset_fn_destroy) \
cs.charset_fn_destroy(&cs); \
\
return ret; \
} \
}
#define COLLATE_ALIAS(name, coll_id)

View File

@ -44,9 +44,10 @@ typedef USHORT UNICODE;
#define TEXTTYPE_ENTRY(name) INTL_BOOL name (TEXTTYPE cache, const ASCII* tt_name, const ASCII* cs_name, \
USHORT attributes, const UCHAR* specific_attributes, \
ULONG specific_attributes_length)
#define TEXTTYPE_ENTRY(name) INTL_BOOL name (TEXTTYPE cache, charset* cs, \
const ASCII* tt_name, const ASCII* cs_name, \
USHORT attributes, \
const UCHAR* specific_attributes, ULONG specific_attributes_length)

224
src/jrd/IntlUtil.cpp Normal file
View File

@ -0,0 +1,224 @@
/*
* PROGRAM: JRD International support
* MODULE: IntlUtil.cpp
* DESCRIPTION: INTL Utility functions
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2004 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#include "firebird.h"
#include "../jrd/IntlUtil.h"
#include "../jrd/intlobj_new.h"
#include "../jrd/unicode_util.h"
namespace Firebird {
Firebird::string IntlUtil::generateSpecificAttributes(
charset* cs, SpecificAttributesMap& map)
{
bool found = map.getFirst();
string s;
while (found)
{
UCHAR c[sizeof(ULONG)];
USHORT errCode;
ULONG errPos;
ULONG size;
SpecificAttribute* attribute = map.current();
s += attribute->first;
const USHORT equalChar = '=';
size = cs->charset_from_unicode.csconvert_fn_convert(
&cs->charset_from_unicode,
sizeof(equalChar), (const UCHAR*)&equalChar,
sizeof(c), c, &errCode, &errPos);
s += string((const char*)&c, size);
s += attribute->second;
found = map.getNext();
if (found)
{
const USHORT semiColonChar = ';';
size = cs->charset_from_unicode.csconvert_fn_convert(
&cs->charset_from_unicode,
sizeof(semiColonChar), (const UCHAR*)&semiColonChar, sizeof(c),
c, &errCode, &errPos);
s += string((const char*)&c, size);
}
}
return s;
}
bool IntlUtil::parseSpecificAttributes(
charset* cs, ULONG len, const UCHAR* s, SpecificAttributesMap* map)
{
// Note that the map isn't cleared.
// Old attributes will be combined with the new ones.
const UCHAR* p = s;
const UCHAR* end = s + len;
ULONG size = 0;
readChar(cs, &p, end, &size);
while (p < end)
{
while (p < end && size == cs->charset_space_length &&
memcmp(p, cs->charset_space_character, cs->charset_space_length) == 0)
{
if (!readChar(cs, &p, end, &size))
return true;
}
const UCHAR* start = p;
UCHAR uc[sizeof(ULONG)];
USHORT errCode;
ULONG errPos;
ULONG uSize;
while (p < end)
{
uSize = cs->charset_to_unicode.csconvert_fn_convert(
&cs->charset_to_unicode, size, p, sizeof(uc), uc, &errCode, &errPos);
if (uSize == INTL_BAD_STR_LENGTH)
return false;
else if (uSize == 2 &&
((*(USHORT*)uc >= 'A' && *(USHORT*)uc <= 'Z') ||
(*(USHORT*)uc >= 'a' && *(USHORT*)uc <= 'z') ||
*(USHORT*)uc == '-' || *(USHORT*)uc == '_'))
{
if (!readChar(cs, &p, end, &size))
return false;
}
else
break;
}
if (p - start == 0)
return false;
string name = string((const char*)start, p - start);
name.trim();
while (p < end && size == cs->charset_space_length &&
memcmp(p, cs->charset_space_character, cs->charset_space_length) == 0)
{
if (!readChar(cs, &p, end, &size))
return false;
}
uSize = cs->charset_to_unicode.csconvert_fn_convert(
&cs->charset_to_unicode, size, p, sizeof(uc), uc, &errCode, &errPos);
if (uSize == INTL_BAD_STR_LENGTH ||
uSize != 2 ||
*(USHORT*)uc != '=' ||
!readChar(cs, &p, end, &size))
{
return false;
}
start = p;
while (p < end)
{
uSize = cs->charset_to_unicode.csconvert_fn_convert(
&cs->charset_to_unicode, size, p, sizeof(uc), uc, &errCode, &errPos);
if (uSize == INTL_BAD_STR_LENGTH)
return false;
else if (uSize != 2 || *(USHORT*)uc != ';')
{
if (!readChar(cs, &p, end, &size))
break;
}
else
break;
}
string value = string((const char*)start, p - start);
value.trim();
if (p < end)
readChar(cs, &p, end, &size); // skip the semicolon
map->put(name, value);
}
return true;
}
bool IntlUtil::readChar(charset* cs, const UCHAR** s, const UCHAR* end, ULONG* size)
{
(*s) += *size;
if (*s >= end)
{
(*s) = end;
*size = 0;
return false;
}
UCHAR c[sizeof(ULONG)];
if (cs->charset_fn_substring)
*size = cs->charset_fn_substring(cs, end - *s, *s, sizeof(c), c, 0, 1);
else if (cs->charset_min_bytes_per_char == cs->charset_max_bytes_per_char)
*size = cs->charset_min_bytes_per_char;
else
{
UCHAR uc[sizeof(ULONG)];
USHORT errCode;
ULONG errPos;
ULONG uSize;
ULONG n = cs->charset_min_bytes_per_char;
while ((uSize = cs->charset_to_unicode.csconvert_fn_convert(
&cs->charset_to_unicode, n, *s, sizeof(uc), uc, &errCode, &errPos)) == 0)
{
++n;
if (n > cs->charset_max_bytes_per_char)
return false;
}
*size = n;
}
return true;
}
} // namespace Firebird

57
src/jrd/IntlUtil.h Normal file
View File

@ -0,0 +1,57 @@
/*
* PROGRAM: JRD International support
* MODULE: IntlUtil.h
* DESCRIPTION: INTL Utility functions
*
* The contents of this file are subject to the Initial
* Developer's Public License Version 1.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
* http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_idpl.
*
* Software distributed under the License is distributed AS IS,
* WITHOUT WARRANTY OF ANY KIND, either express or implied.
* See the License for the specific language governing rights
* and limitations under the License.
*
* The Original Code was created by Adriano dos Santos Fernandes
* for the Firebird Open Source RDBMS project.
*
* Copyright (c) 2004 Adriano dos Santos Fernandes <adrianosf@uol.com.br>
* and all contributors signed below.
*
* All Rights Reserved.
* Contributor(s): ______________________________________.
*/
#ifndef JRD_INTLUTIL_H
#define JRD_INTLUTIL_H
#include "../common/classes/GenericMap.h"
#include "../common/classes/fb_string.h"
struct charset;
struct texttype;
namespace Firebird {
class IntlUtil
{
public:
typedef Firebird::Pair<Firebird::Full<
Firebird::string, Firebird::string> > SpecificAttribute;
typedef Firebird::GenericMap<SpecificAttribute> SpecificAttributesMap;
public:
static Firebird::string generateSpecificAttributes(
charset* cs, SpecificAttributesMap& map);
static bool parseSpecificAttributes(
charset* cs, ULONG len, const UCHAR* s, SpecificAttributesMap* map);
private:
static bool readChar(charset* cs, const UCHAR** s, const UCHAR* end, ULONG* size);
};
} // namespace Firebird
#endif // JRD_INTLUTIL_H

View File

@ -723,6 +723,31 @@ USHORT DYN_get_string(const TEXT** ptr, Firebird::PathName& field, size_t, bool)
}
USHORT DYN_get_string(const TEXT** ptr, Firebird::Array<UCHAR>& array, size_t, bool err_flag)
{
/**************************************
*
* D Y N _ g e t _ s t r i n g
*
**************************************
*
* Functional description
* Pick up a string, move to a target. Return length
* of string. Copy all available data ignoring err_flag.
*
**************************************/
const TEXT* p = *ptr;
USHORT length = (UCHAR) *p++;
length |= ((USHORT) ((UCHAR) (*p++))) << 8;
memcpy(array.getBuffer(length), p, length);
p += length;
*ptr = p;
return length;
}
USHORT DYN_put_blr_blob(Global* gbl, const UCHAR** ptr, bid* blob_id)
{
/**************************************

View File

@ -87,6 +87,7 @@ void DYN_execute(Jrd::Global*, const UCHAR**, const Firebird::MetaName*, Firebir
SLONG DYN_get_number(const UCHAR**);
USHORT DYN_get_string(const TEXT**, Firebird::MetaName&, size_t, bool);
USHORT DYN_get_string(const TEXT**, Firebird::PathName&, size_t, bool);
USHORT DYN_get_string(const TEXT**, Firebird::Array<UCHAR>&, size_t, bool);
USHORT DYN_get_string(const TEXT**, TEXT*, size_t, bool);
// This function is not defined anywhere.

View File

@ -80,6 +80,7 @@
#include "../jrd/os/path_utils.h"
#include "../common/utils_proto.h"
#include "../jrd/IntlManager.h"
#include "../jrd/IntlUtil.h"
using namespace Jrd;
@ -171,12 +172,12 @@ void DYN_define_collation( Global* gbl, const UCHAR** ptr)
STORE(REQUEST_HANDLE request TRANSACTION_HANDLE gbl->gbl_transaction)
X IN RDB$COLLATIONS
CharSet* cs = NULL;
SubtypeInfo info;
USHORT attributes_on = 0;
USHORT attributes_off = 0;
SSHORT specific_attributes_charset = CS_NONE;
info.attributes = 0;
Firebird::Array<UCHAR> specific_attributes;
X.RDB$SYSTEM_FLAG = 0;
X.RDB$SYSTEM_FLAG.NULL = FALSE;
@ -191,6 +192,8 @@ void DYN_define_collation( Global* gbl, const UCHAR** ptr)
{
X.RDB$CHARACTER_SET_ID.NULL = FALSE;
X.RDB$CHARACTER_SET_ID = DYN_get_number(ptr);
cs = INTL_charset_lookup(tdbb, X.RDB$CHARACTER_SET_ID);
// ASF: User collations are created with the last number available,
// to minimize the possibility of conflicts with future system collations.
@ -241,13 +244,32 @@ void DYN_define_collation( Global* gbl, const UCHAR** ptr)
}
case isc_dyn_coll_from:
{
//// TODO: verify return value
MET_get_char_coll_subtype_info(tdbb, DYN_get_number(ptr), &info);
fb_assert(cs);
if (cs)
{
if (info.specificAttributes.getCount() != 0)
{
Firebird::HalfStaticArray<UCHAR, 32> temp;
ULONG size = info.specificAttributes.getCount() * cs->maxBytesPerChar();
size = INTL_convert_bytes(tdbb, X.RDB$CHARACTER_SET_ID,
temp.getBuffer(size), size,
CS_METADATA, info.specificAttributes.begin(),
info.specificAttributes.getCount(), ERR_post);
temp.shrink(size);
info.specificAttributes = temp;
}
}
X.RDB$BASE_COLLATION_NAME.NULL = FALSE;
strcpy(X.RDB$BASE_COLLATION_NAME, info.baseCollationName.c_str());
break;
}
case isc_dyn_coll_attribute:
{
@ -278,20 +300,24 @@ void DYN_define_collation( Global* gbl, const UCHAR** ptr)
case isc_dyn_coll_specific_attributes:
{
UCHAR bpb[] = {isc_bpb_version1,
isc_bpb_source_type, 1, isc_blob_text, isc_bpb_source_interp, 1, 0,
isc_bpb_target_type, 1, isc_blob_text, isc_bpb_target_interp, 1, 0};
GET_STRING_2(ptr, specific_attributes);
bpb[6] = specific_attributes_charset; // from charset
bpb[12] = CS_METADATA; // to charset
fb_assert(cs);
if (cs)
{
if (specific_attributes.getCount() != 0)
{
Firebird::Array<UCHAR> temp;
ULONG size = specific_attributes.getCount() * cs->maxBytesPerChar();
X.RDB$SPECIFIC_ATTRIBUTES.NULL = FALSE;
DYN_put_text_blob(gbl, ptr, &X.RDB$SPECIFIC_ATTRIBUTES, sizeof(bpb), bpb);
// ASF: retrieve RDB$SPECIFIC_ATTRIBUTES with UNICODE_FSS character set
blb* blob = BLB_open(tdbb, gbl->gbl_transaction, &X.RDB$SPECIFIC_ATTRIBUTES);
BLB_get_data(tdbb, blob, info.specificAttributes.getBuffer(blob->blb_length),
blob->blb_length);
size = INTL_convert_bytes(tdbb, X.RDB$CHARACTER_SET_ID,
temp.getBuffer(size), size,
specific_attributes_charset, specific_attributes.begin(),
specific_attributes.getCount(), ERR_post);
temp.shrink(size);
specific_attributes = temp;
}
}
break;
}
@ -304,16 +330,37 @@ void DYN_define_collation( Global* gbl, const UCHAR** ptr)
strcpy(X.RDB$COLLATION_NAME, collation_name.c_str());
X.RDB$COLLATION_ATTRIBUTES = (info.attributes | attributes_on) & (~attributes_off);
// If isc_dyn_coll_specific_attributes is not provided, then inherit from the base collation
if (X.RDB$SPECIFIC_ATTRIBUTES.NULL && info.specificAttributes.getCount() != 0)
fb_assert(cs);
if (cs)
{
Firebird::IntlUtil::SpecificAttributesMap map;
if (!Firebird::IntlUtil::parseSpecificAttributes(
cs->getObj(), info.specificAttributes.getCount(), info.specificAttributes.begin(), &map) ||
!Firebird::IntlUtil::parseSpecificAttributes(
cs->getObj(), specific_attributes.getCount(), specific_attributes.begin(), &map))
{
DYN_error_punt(false, 222, NULL, NULL, NULL, NULL, NULL);
// msg: 222: "Invalid collation attributes"
}
Firebird::string s = Firebird::IntlUtil::generateSpecificAttributes(cs->getObj(), map);
memcpy(specific_attributes.getBuffer(s.length()), s.begin(), s.length());
}
if (specific_attributes.getCount() != 0)
{
X.RDB$SPECIFIC_ATTRIBUTES.NULL = FALSE;
// ASF: Transliteration should not occur here because
// info.specificAttributes and X.RDB$SPECIFIC_ATTRIBUTES
// are already in UNICODE_FSS character set.
blb* blob = BLB_create(tdbb, gbl->gbl_transaction, &X.RDB$SPECIFIC_ATTRIBUTES);
BLB_put_segment(tdbb, blob, info.specificAttributes.begin(), info.specificAttributes.getCount());
UCHAR bpb[] = {isc_bpb_version1,
isc_bpb_source_type, 1, isc_blob_text, isc_bpb_source_interp, 1, 0,
isc_bpb_target_type, 1, isc_blob_text, isc_bpb_target_interp, 1, 0};
bpb[6] = X.RDB$CHARACTER_SET_ID; // from charset
bpb[12] = CS_METADATA; // to charset
blb* blob = BLB_create2(tdbb, gbl->gbl_transaction, &X.RDB$SPECIFIC_ATTRIBUTES, sizeof(bpb), bpb);
BLB_put_segment(tdbb, blob, specific_attributes.begin(), specific_attributes.getCount());
BLB_close(tdbb, blob);
}

View File

@ -211,13 +211,18 @@ public:
virtual ULONG length(thread_db* tdbb, ULONG srcLen, const UCHAR* src, bool countTrailingSpaces) const = 0;
virtual ULONG substring(thread_db* tdbb, ULONG srcLen, const UCHAR* src, ULONG dstLen, UCHAR* dst, ULONG startPos, ULONG length) const = 0;
charset* getObj()
{
return cs;
}
private:
CHARSET_ID id;
charset* cs;
UCHAR sqlMatchAny[sizeof(ULONG)];
UCHAR sqlMatchOne[sizeof(ULONG)];
BYTE sqlMatchAnyLength;
BYTE sqlMatchOneLength;
charset* cs;
};
class TextType

View File

@ -48,6 +48,12 @@ namespace Jrd {
struct SubtypeInfo
{
SubtypeInfo()
: attributes(0),
ignoreAttributes(true)
{
}
Firebird::string charsetName;
Firebird::string collationName;
Firebird::string baseCollationName;