1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* Copyright (C) 1996-2014, International Business Machines 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************* 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* file name: ucol.cpp 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* encoding: US-ASCII 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* tab size: 8 (not used) 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* indentation:4 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Modification history 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Date Name Comments 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 1996-1999 various members of ICU team maintained C API for collation framework 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 02/16/2001 synwee Added internal method getPrevSpecialCE 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/01/2001 synwee Added maxexpansion functionality. 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* 03/16/2001 weiv Collation framework is rewritten in C and made UCA compliant 17fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius* 2012-2014 markus Rewritten in C++ again. 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 24fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/coll.h" 25fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/tblcoll.h" 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/bytestream.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/coleitr.h" 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/ucoleitr.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 31fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "collation.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h" 34c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru#include "uassert.h" 35fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "utracimp.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_USE 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 39fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI UCollator* U_EXPORT2 40fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_openBinary(const uint8_t *bin, int32_t length, 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UCollator *base, 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode *status) 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 44fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status)) { return NULL; } 45fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RuleBasedCollator *coll = new RuleBasedCollator( 46fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius bin, length, 47fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius RuleBasedCollator::rbcFromUCollator(base), 48fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status); 49fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(coll == NULL) { 50fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_MEMORY_ALLOCATION_ERROR; 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 53fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status)) { 54fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete coll; 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return NULL; 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 57fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return coll->toUCollator(); 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 60c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 61c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queruucol_cloneBinary(const UCollator *coll, 62c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru uint8_t *buffer, int32_t capacity, 63c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode *status) 64c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 65c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if(U_FAILURE(*status)) { 66fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 67c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 68fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll); 69fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(rbc == NULL && coll != NULL) { 70fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_UNSUPPORTED_ERROR; 71fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 72c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 73fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return rbc->cloneBinary(buffer, capacity, *status); 74c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru} 75c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UCollator* U_EXPORT2 7759d709d503bab6e2b61931737e662dd293b40578ccorneliusucol_safeClone(const UCollator *coll, void * /*stackBuffer*/, int32_t * pBufferSize, UErrorCode *status) 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (status == NULL || U_FAILURE(*status)){ 8059d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 8259d709d503bab6e2b61931737e662dd293b40578ccornelius if (coll == NULL) { 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *status = U_ILLEGAL_ARGUMENT_ERROR; 8459d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 8659d709d503bab6e2b61931737e662dd293b40578ccornelius if (pBufferSize != NULL) { 8759d709d503bab6e2b61931737e662dd293b40578ccornelius int32_t inputSize = *pBufferSize; 8859d709d503bab6e2b61931737e662dd293b40578ccornelius *pBufferSize = 1; 8959d709d503bab6e2b61931737e662dd293b40578ccornelius if (inputSize == 0) { 9059d709d503bab6e2b61931737e662dd293b40578ccornelius return NULL; // preflighting for deprecated functionality 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 93fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Collator *newColl = Collator::fromUCollator(coll)->clone(); 94fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (newColl == NULL) { 9559d709d503bab6e2b61931737e662dd293b40578ccornelius *status = U_MEMORY_ALLOCATION_ERROR; 96fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 97fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_SAFECLONE_ALLOCATED_WARNING; 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 99fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return newColl->toUCollator(); 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_close(UCollator *coll) 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_ENTRY_OC(UTRACE_UCOL_CLOSE); 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_DATA1(UTRACE_INFO, "coll = %p", coll); 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(coll != NULL) { 108fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete Collator::fromUCollator(coll); 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_EXIT(); 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 113fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 114fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_mergeSortkeys(const uint8_t *src1, int32_t src1Length, 115fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const uint8_t *src2, int32_t src2Length, 116fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *dest, int32_t destCapacity) { 117fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* check arguments */ 118fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if( src1==NULL || src1Length<-1 || src1Length==0 || (src1Length>0 && src1[src1Length-1]!=0) || 119fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius src2==NULL || src2Length<-1 || src2Length==0 || (src2Length>0 && src2[src2Length-1]!=0) || 120fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius destCapacity<0 || (destCapacity>0 && dest==NULL) 121fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ) { 122fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* error, attempt to write a zero byte and return 0 */ 123fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(dest!=NULL && destCapacity>0) { 124fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *dest=0; 125c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 126fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 129fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* check lengths and capacity */ 130fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(src1Length<0) { 131fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius src1Length=(int32_t)uprv_strlen((const char *)src1)+1; 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 133fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(src2Length<0) { 134fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius src2Length=(int32_t)uprv_strlen((const char *)src2)+1; 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 137fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t destLength=src1Length+src2Length; 138fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(destLength>destCapacity) { 139fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* the merged sort key does not fit into the destination */ 140fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return destLength; 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 143fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* merge the sort keys with the same number of levels */ 144fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *p=dest; 145fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for(;;) { 146fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* copy level from src1 not including 00 or 01 */ 147fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t b; 148fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while((b=*src1)>=2) { 149fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++src1; 150fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *p++=b; 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 153fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* add a 02 merge separator */ 154fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *p++=2; 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 156fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* copy level from src2 not including 00 or 01 */ 157fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while((b=*src2)>=2) { 158fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++src2; 159fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *p++=b; 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 162fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* if both sort keys have another level, then add a 01 level separator and continue */ 163fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(*src1==1 && *src2==1) { 164fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++src1; 165fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ++src2; 166fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *p++=1; 167fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 168fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 172fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* 173fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * here, at least one sort key is finished now, but the other one 174fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * might have some contents left from containing more levels; 175fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * that contents is just appended to the result 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 177fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(*src1!=0) { 178fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* src1 is not finished, therefore *src2==0, and src1 is appended */ 179fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius src2=src1; 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 181fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* append src2, "the other, unfinished sort key" */ 182fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius while((*p++=*src2++)!=0) {} 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 184fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* the actual length might be less than destLength if either sort key contained illegally embedded zero bytes */ 185fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return (int32_t)(p-dest); 186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 188fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 189fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getSortKey(const UCollator *coll, 190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UChar *source, 191fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t sourceLength, 192fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *result, 193fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t resultLength) 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 195fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_ENTRY(UTRACE_UCOL_GET_SORTKEY); 196fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (UTRACE_LEVEL(UTRACE_VERBOSE)) { 197fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source string = %vh ", coll, source, 198fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ((sourceLength==-1 && source!=NULL) ? u_strlen(source) : sourceLength)); 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 201fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t keySize = Collator::fromUCollator(coll)-> 202fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius getSortKey(source, sourceLength, result, resultLength); 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 204fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_DATA2(UTRACE_VERBOSE, "Sort Key = %vb", result, keySize); 205fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_EXIT_VALUE(keySize); 206fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return keySize; 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 209fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 210fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_nextSortKeyPart(const UCollator *coll, 211fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UCharIterator *iter, 212fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint32_t state[2], 213fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *dest, int32_t count, 214fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *status) 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 216fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius /* error checking */ 217fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(status==NULL || U_FAILURE(*status)) { 218fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 220fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_ENTRY(UTRACE_UCOL_NEXTSORTKEYPART); 221fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_DATA6(UTRACE_VERBOSE, "coll=%p, iter=%p, state=%d %d, dest=%p, count=%d", 222fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius coll, iter, state[0], state[1], dest, count); 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 224fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t i = Collator::fromUCollator(coll)-> 225fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius internalNextSortKeyPart(iter, state, dest, count, *status); 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 227fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Return number of meaningful sortkey bytes. 228fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_DATA4(UTRACE_VERBOSE, "dest = %vb, state=%d %d", 229fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius dest,i, state[0], state[1]); 230fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_EXIT_VALUE_STATUS(i, *status); 231fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return i; 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 234fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius/** 235fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Produce a bound for a given sortkey and a number of levels. 236fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius */ 237fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 238fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getBound(const uint8_t *source, 239fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t sourceLength, 240fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UColBoundMode boundType, 241fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint32_t noOfLevels, 242fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uint8_t *result, 243fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t resultLength, 244fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *status) 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 246fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // consistency checks 247fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(status == NULL || U_FAILURE(*status)) { 248fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 250fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(source == NULL) { 251fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_ILLEGAL_ARGUMENT_ERROR; 252fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 255fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t sourceIndex = 0; 256fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Scan the string until we skip enough of the key OR reach the end of the key 257fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius do { 258fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius sourceIndex++; 259fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(source[sourceIndex] == Collation::LEVEL_SEPARATOR_BYTE) { 260fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius noOfLevels--; 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 262fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } while (noOfLevels > 0 263fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius && (source[sourceIndex] != 0 || sourceIndex < sourceLength)); 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 265fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if((source[sourceIndex] == 0 || sourceIndex == sourceLength) 266fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius && noOfLevels > 0) { 267fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_SORT_KEY_TOO_SHORT_WARNING; 26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 271fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // READ ME: this code assumes that the values for boundType 272fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // enum will not changes. They are set so that the enum value 273fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // corresponds to the number of extra bytes each bound type 274fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // needs. 275fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(result != NULL && resultLength >= sourceIndex+boundType) { 276fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius uprv_memcpy(result, source, sourceIndex); 277fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius switch(boundType) { 278fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Lower bound just gets terminated. No extra bytes 279fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case UCOL_BOUND_LOWER: // = 0 280fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 281fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Upper bound needs one extra byte 282fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case UCOL_BOUND_UPPER: // = 1 283fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result[sourceIndex++] = 2; 284fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 285fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Upper long bound needs two extra bytes 286fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case UCOL_BOUND_UPPER_LONG: // = 2 287fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result[sourceIndex++] = 0xFF; 288fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result[sourceIndex++] = 0xFF; 289fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 290fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius default: 291fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_ILLEGAL_ARGUMENT_ERROR; 292fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 293c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 294fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result[sourceIndex++] = 0; 295b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 296fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return sourceIndex; 297fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 298fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return sourceIndex+boundType+1; 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 302fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI void U_EXPORT2 303fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_setMaxVariable(UCollator *coll, UColReorderCode group, UErrorCode *pErrorCode) { 304fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*pErrorCode)) { return; } 305fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Collator::fromUCollator(coll)->setMaxVariable(group, *pErrorCode); 306fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 308fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI UColReorderCode U_EXPORT2 309fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getMaxVariable(const UCollator *coll) { 310fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return Collator::fromUCollator(coll)->getMaxVariable(); 311fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 312c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 313fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI uint32_t U_EXPORT2 314fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_setVariableTop(UCollator *coll, const UChar *varTop, int32_t len, UErrorCode *status) { 315fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status) || coll == NULL) { 316fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 317c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 318fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return Collator::fromUCollator(coll)->setVariableTop(varTop, len, *status); 319fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 321fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI uint32_t U_EXPORT2 ucol_getVariableTop(const UCollator *coll, UErrorCode *status) { 322fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status) || coll == NULL) { 323fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 325fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return Collator::fromUCollator(coll)->getVariableTop(*status); 326fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 328fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI void U_EXPORT2 329fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_restoreVariableTop(UCollator *coll, const uint32_t varTop, UErrorCode *status) { 330fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status) || coll == NULL) { 331fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 333fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Collator::fromUCollator(coll)->setVariableTop(varTop, *status); 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 336fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI void U_EXPORT2 337fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_setAttribute(UCollator *coll, UColAttribute attr, UColAttributeValue value, UErrorCode *status) { 338fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status) || coll == NULL) { 339fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 34050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 342fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Collator::fromUCollator(coll)->setAttribute(attr, value, *status); 343fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 344c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI UColAttributeValue U_EXPORT2 346fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getAttribute(const UCollator *coll, UColAttribute attr, UErrorCode *status) { 347fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status) || coll == NULL) { 348fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return UCOL_DEFAULT; 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 351fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return Collator::fromUCollator(coll)->getAttribute(attr, *status); 35254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 354fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI void U_EXPORT2 355fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_setStrength( UCollator *coll, 356fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UCollationStrength strength) 35754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{ 358fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode status = U_ZERO_ERROR; 359fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ucol_setAttribute(coll, UCOL_STRENGTH, strength, &status); 36054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 361c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru 362fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI UCollationStrength U_EXPORT2 363fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getStrength(const UCollator *coll) 36454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{ 365fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode status = U_ZERO_ERROR; 366fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return ucol_getAttribute(coll, UCOL_STRENGTH, &status); 367fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 36854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 369fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 370fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getReorderCodes(const UCollator *coll, 371fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t *dest, 372fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t destCapacity, 373fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *status) { 374fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(*status)) { 375fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return 0; 37654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 37754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 378fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return Collator::fromUCollator(coll)->getReorderCodes(dest, destCapacity, *status); 379fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 38054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 381fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI void U_EXPORT2 382fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_setReorderCodes(UCollator* coll, 383fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const int32_t* reorderCodes, 384fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t reorderCodesLength, 385fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *status) { 386fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(*status)) { 387fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 388fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 38954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 390fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Collator::fromUCollator(coll)->setReorderCodes(reorderCodes, reorderCodesLength, *status); 391fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 39254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 393fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 394fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getEquivalentReorderCodes(int32_t reorderCode, 395fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t* dest, 396fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t destCapacity, 397fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode *pErrorCode) { 398fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return Collator::getEquivalentReorderCodes(reorderCode, dest, destCapacity, *pErrorCode); 399fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 40054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 401fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI void U_EXPORT2 402fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getVersion(const UCollator* coll, 403fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UVersionInfo versionInfo) 404fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{ 405fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Collator::fromUCollator(coll)->getVersion(versionInfo); 40654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 40754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 40854dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UCollationResult U_EXPORT2 40954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusucol_strcollIter( const UCollator *coll, 41054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UCharIterator *sIter, 41154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UCharIterator *tIter, 41254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UErrorCode *status) 41354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{ 41454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(!status || U_FAILURE(*status)) { 41554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return UCOL_EQUAL; 41654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 41754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 41854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_ENTRY(UTRACE_UCOL_STRCOLLITER); 41954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, sIter=%p, tIter=%p", coll, sIter, tIter); 42054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 42154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(sIter == NULL || tIter == NULL || coll == NULL) { 42254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius *status = U_ILLEGAL_ARGUMENT_ERROR; 423fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_EXIT_VALUE_STATUS(UCOL_EQUAL, *status); 42454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return UCOL_EQUAL; 42554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 42654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 427fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UCollationResult result = Collator::fromUCollator(coll)->compare(*sIter, *tIter, *status); 42854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 429fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_EXIT_VALUE_STATUS(result, *status); 43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return result; 43154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* */ 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* ucol_strcoll Main public API string comparison function */ 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* */ 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UCollationResult U_EXPORT2 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_strcoll( const UCollator *coll, 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *source, 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceLength, 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *target, 442c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru int32_t targetLength) 443c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru{ 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_ALIGN_CODE(16); 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UTRACE_ENTRY(UTRACE_UCOL_STRCOLL); 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (UTRACE_LEVEL(UTRACE_VERBOSE)) { 448c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source=%p, target=%p", coll, source, target); 449c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTRACE_DATA2(UTRACE_VERBOSE, "source string = %vh ", source, sourceLength); 450c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UTRACE_DATA2(UTRACE_VERBOSE, "target string = %vh ", target, targetLength); 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 453c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 454fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UCollationResult returnVal = Collator::fromUCollator(coll)-> 455fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius compare(source, sourceLength, target, targetLength, status); 456fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_EXIT_VALUE_STATUS(returnVal, status); 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return returnVal; 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 46054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusU_CAPI UCollationResult U_EXPORT2 46154dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusucol_strcollUTF8( 46254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const UCollator *coll, 46354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const char *source, 46454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t sourceLength, 46554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const char *target, 46654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t targetLength, 46754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UErrorCode *status) 46854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{ 46954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_ALIGN_CODE(16); 47054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 47154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_ENTRY(UTRACE_UCOL_STRCOLLUTF8); 47254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (UTRACE_LEVEL(UTRACE_VERBOSE)) { 47354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source=%p, target=%p", coll, source, target); 47454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_DATA2(UTRACE_VERBOSE, "source string = %vb ", source, sourceLength); 47554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_DATA2(UTRACE_VERBOSE, "target string = %vb ", target, targetLength); 47654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 47754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 47854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (U_FAILURE(*status)) { 47954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius /* do nothing */ 48054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_EXIT_VALUE_STATUS(UCOL_EQUAL, *status); 48154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return UCOL_EQUAL; 48254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 48354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 484fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UCollationResult returnVal = Collator::fromUCollator(coll)->internalCompareUTF8( 485fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius source, sourceLength, target, targetLength, *status); 48654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UTRACE_EXIT_VALUE_STATUS(returnVal, *status); 48754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return returnVal; 48854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 48954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 49054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* convenience function for comparing strings */ 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_greater( const UCollator *coll, 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *source, 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceLength, 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *target, 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetLength) 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 499c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (ucol_strcoll(coll, source, sourceLength, target, targetLength) 500c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru == UCOL_GREATER); 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* convenience function for comparing strings */ 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_greaterOrEqual( const UCollator *coll, 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *source, 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceLength, 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *target, 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetLength) 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 511c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (ucol_strcoll(coll, source, sourceLength, target, targetLength) 512c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru != UCOL_LESS); 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* convenience function for comparing strings */ 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI UBool U_EXPORT2 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_equal( const UCollator *coll, 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *source, 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t sourceLength, 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UChar *target, 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t targetLength) 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 523c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return (ucol_strcoll(coll, source, sourceLength, target, targetLength) 524c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru == UCOL_EQUAL); 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CAPI void U_EXPORT2 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruucol_getUCAVersion(const UCollator* coll, UVersionInfo info) { 529fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const Collator *c = Collator::fromUCollator(coll); 530fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(c != NULL) { 531fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UVersionInfo v; 532fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius c->getVersion(v); 533fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Note: This is tied to how the current implementation encodes the UCA version 534fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // in the overall getVersion(). 535fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Alternatively, we could load the root collator and get at lower-level data from there. 536fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // Either way, it will reflect the input collator's UCA version only 537fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // if it is a known implementation. 538fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // It would be cleaner to make this a virtual Collator method. 539fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius info[0] = v[1] >> 3; 540fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius info[1] = v[1] & 7; 541fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius info[2] = v[2] >> 6; 542fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius info[3] = 0; 543fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 544fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 545fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 546fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI const UChar * U_EXPORT2 547fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getRules(const UCollator *coll, int32_t *length) { 548fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll); 549fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // OK to crash if coll==NULL: We do not want to check "this" pointers. 550fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(rbc != NULL || coll == NULL) { 551fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const UnicodeString &rules = rbc->getRules(); 552fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius U_ASSERT(rules.getBuffer()[rules.length()] == 0); 553fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *length = rules.length(); 554fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return rules.getBuffer(); 555fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 556fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius static const UChar _NUL = 0; 557fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *length = 0; 558fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return &_NUL; 559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 560fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 561fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI int32_t U_EXPORT2 562fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getRulesEx(const UCollator *coll, UColRuleOption delta, UChar *buffer, int32_t bufferLen) { 563fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString rules; 564fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll); 565fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(rbc != NULL || coll == NULL) { 566fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius rbc->getRules(delta, rules); 567fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 568fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(buffer != NULL && bufferLen > 0) { 569fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode errorCode = U_ZERO_ERROR; 570fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return rules.extract(buffer, bufferLen, errorCode); 571fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 572fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return rules.length(); 573fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 574fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 575fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 576fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI const char * U_EXPORT2 577fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getLocale(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) { 578fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return ucol_getLocaleByType(coll, type, status); 579fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 580fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 581fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI const char * U_EXPORT2 582fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getLocaleByType(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) { 583fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status)) { 584fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 586fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_ENTRY(UTRACE_UCOL_GETLOCALE); 587fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_DATA1(UTRACE_INFO, "coll=%p", coll); 588fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 589fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char *result; 590fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll); 591fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(rbc == NULL && coll != NULL) { 592fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius *status = U_UNSUPPORTED_ERROR; 593fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = NULL; 594fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 595fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius result = rbc->internalGetLocaleID(type, *status); 596fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 597fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 598fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_DATA1(UTRACE_INFO, "result = %s", result); 599fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UTRACE_EXIT_STATUS(*status); 600fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return result; 601fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 602fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 603fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI USet * U_EXPORT2 604fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_getTailoredSet(const UCollator *coll, UErrorCode *status) { 605fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status)) { 606fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 607fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 608fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeSet *set = Collator::fromUCollator(coll)->getTailoredSet(*status); 609fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if(U_FAILURE(*status)) { 610fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete set; 611fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 612fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 613fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return set->toUSet(); 614fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 615fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 616fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusU_CAPI UBool U_EXPORT2 617fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusucol_equals(const UCollator *source, const UCollator *target) { 618fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return source == target || 619fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (*Collator::fromUCollator(source)) == (*Collator::fromUCollator(target)); 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */ 623