LCOV - code coverage report
Current view: top level - intl/icu/source/i18n - ucol.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 231 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 34 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // © 2016 and later: Unicode, Inc. and others.
       2             : // License & terms of use: http://www.unicode.org/copyright.html
       3             : /*
       4             : *******************************************************************************
       5             : *   Copyright (C) 1996-2015, International Business Machines
       6             : *   Corporation and others.  All Rights Reserved.
       7             : *******************************************************************************
       8             : *   file name:  ucol.cpp
       9             : *   encoding:   UTF-8
      10             : *   tab size:   8 (not used)
      11             : *   indentation:4
      12             : *
      13             : * Modification history
      14             : * Date        Name      Comments
      15             : * 1996-1999   various members of ICU team maintained C API for collation framework
      16             : * 02/16/2001  synwee    Added internal method getPrevSpecialCE
      17             : * 03/01/2001  synwee    Added maxexpansion functionality.
      18             : * 03/16/2001  weiv      Collation framework is rewritten in C and made UCA compliant
      19             : * 2012-2014   markus    Rewritten in C++ again.
      20             : */
      21             : 
      22             : #include "unicode/utypes.h"
      23             : 
      24             : #if !UCONFIG_NO_COLLATION
      25             : 
      26             : #include "unicode/coll.h"
      27             : #include "unicode/tblcoll.h"
      28             : #include "unicode/bytestream.h"
      29             : #include "unicode/coleitr.h"
      30             : #include "unicode/ucoleitr.h"
      31             : #include "unicode/ustring.h"
      32             : #include "cmemory.h"
      33             : #include "collation.h"
      34             : #include "cstring.h"
      35             : #include "putilimp.h"
      36             : #include "uassert.h"
      37             : #include "utracimp.h"
      38             : 
      39             : U_NAMESPACE_USE
      40             : 
      41             : U_CAPI UCollator* U_EXPORT2
      42           0 : ucol_openBinary(const uint8_t *bin, int32_t length,
      43             :                 const UCollator *base,
      44             :                 UErrorCode *status)
      45             : {
      46           0 :     if(U_FAILURE(*status)) { return NULL; }
      47             :     RuleBasedCollator *coll = new RuleBasedCollator(
      48             :             bin, length,
      49           0 :             RuleBasedCollator::rbcFromUCollator(base),
      50           0 :             *status);
      51           0 :     if(coll == NULL) {
      52           0 :         *status = U_MEMORY_ALLOCATION_ERROR;
      53           0 :         return NULL;
      54             :     }
      55           0 :     if(U_FAILURE(*status)) {
      56           0 :         delete coll;
      57           0 :         return NULL;
      58             :     }
      59           0 :     return coll->toUCollator();
      60             : }
      61             : 
      62             : U_CAPI int32_t U_EXPORT2
      63           0 : ucol_cloneBinary(const UCollator *coll,
      64             :                  uint8_t *buffer, int32_t capacity,
      65             :                  UErrorCode *status)
      66             : {
      67           0 :     if(U_FAILURE(*status)) {
      68           0 :         return 0;
      69             :     }
      70           0 :     const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll);
      71           0 :     if(rbc == NULL && coll != NULL) {
      72           0 :         *status = U_UNSUPPORTED_ERROR;
      73           0 :         return 0;
      74             :     }
      75           0 :     return rbc->cloneBinary(buffer, capacity, *status);
      76             : }
      77             : 
      78             : U_CAPI UCollator* U_EXPORT2
      79           0 : ucol_safeClone(const UCollator *coll, void * /*stackBuffer*/, int32_t * pBufferSize, UErrorCode *status)
      80             : {
      81           0 :     if (status == NULL || U_FAILURE(*status)){
      82           0 :         return NULL;
      83             :     }
      84           0 :     if (coll == NULL) {
      85           0 :        *status = U_ILLEGAL_ARGUMENT_ERROR;
      86           0 :         return NULL;
      87             :     }
      88           0 :     if (pBufferSize != NULL) {
      89           0 :         int32_t inputSize = *pBufferSize;
      90           0 :         *pBufferSize = 1;
      91           0 :         if (inputSize == 0) {
      92           0 :             return NULL;  // preflighting for deprecated functionality
      93             :         }
      94             :     }
      95           0 :     Collator *newColl = Collator::fromUCollator(coll)->clone();
      96           0 :     if (newColl == NULL) {
      97           0 :         *status = U_MEMORY_ALLOCATION_ERROR;
      98             :     } else {
      99           0 :         *status = U_SAFECLONE_ALLOCATED_WARNING;
     100             :     }
     101           0 :     return newColl->toUCollator();
     102             : }
     103             : 
     104             : U_CAPI void U_EXPORT2
     105           0 : ucol_close(UCollator *coll)
     106             : {
     107             :     UTRACE_ENTRY_OC(UTRACE_UCOL_CLOSE);
     108             :     UTRACE_DATA1(UTRACE_INFO, "coll = %p", coll);
     109           0 :     if(coll != NULL) {
     110           0 :         delete Collator::fromUCollator(coll);
     111             :     }
     112             :     UTRACE_EXIT();
     113           0 : }
     114             : 
     115             : U_CAPI int32_t U_EXPORT2
     116           0 : ucol_mergeSortkeys(const uint8_t *src1, int32_t src1Length,
     117             :                    const uint8_t *src2, int32_t src2Length,
     118             :                    uint8_t *dest, int32_t destCapacity) {
     119             :     /* check arguments */
     120           0 :     if( src1==NULL || src1Length<-1 || src1Length==0 || (src1Length>0 && src1[src1Length-1]!=0) ||
     121           0 :         src2==NULL || src2Length<-1 || src2Length==0 || (src2Length>0 && src2[src2Length-1]!=0) ||
     122           0 :         destCapacity<0 || (destCapacity>0 && dest==NULL)
     123             :     ) {
     124             :         /* error, attempt to write a zero byte and return 0 */
     125           0 :         if(dest!=NULL && destCapacity>0) {
     126           0 :             *dest=0;
     127             :         }
     128           0 :         return 0;
     129             :     }
     130             : 
     131             :     /* check lengths and capacity */
     132           0 :     if(src1Length<0) {
     133           0 :         src1Length=(int32_t)uprv_strlen((const char *)src1)+1;
     134             :     }
     135           0 :     if(src2Length<0) {
     136           0 :         src2Length=(int32_t)uprv_strlen((const char *)src2)+1;
     137             :     }
     138             : 
     139           0 :     int32_t destLength=src1Length+src2Length;
     140           0 :     if(destLength>destCapacity) {
     141             :         /* the merged sort key does not fit into the destination */
     142           0 :         return destLength;
     143             :     }
     144             : 
     145             :     /* merge the sort keys with the same number of levels */
     146           0 :     uint8_t *p=dest;
     147             :     for(;;) {
     148             :         /* copy level from src1 not including 00 or 01 */
     149             :         uint8_t b;
     150           0 :         while((b=*src1)>=2) {
     151           0 :             ++src1;
     152           0 :             *p++=b;
     153             :         }
     154             : 
     155             :         /* add a 02 merge separator */
     156           0 :         *p++=2;
     157             : 
     158             :         /* copy level from src2 not including 00 or 01 */
     159           0 :         while((b=*src2)>=2) {
     160           0 :             ++src2;
     161           0 :             *p++=b;
     162             :         }
     163             : 
     164             :         /* if both sort keys have another level, then add a 01 level separator and continue */
     165           0 :         if(*src1==1 && *src2==1) {
     166           0 :             ++src1;
     167           0 :             ++src2;
     168           0 :             *p++=1;
     169             :         } else {
     170             :             break;
     171             :         }
     172           0 :     }
     173             : 
     174             :     /*
     175             :      * here, at least one sort key is finished now, but the other one
     176             :      * might have some contents left from containing more levels;
     177             :      * that contents is just appended to the result
     178             :      */
     179           0 :     if(*src1!=0) {
     180             :         /* src1 is not finished, therefore *src2==0, and src1 is appended */
     181           0 :         src2=src1;
     182             :     }
     183             :     /* append src2, "the other, unfinished sort key" */
     184           0 :     while((*p++=*src2++)!=0) {}
     185             : 
     186             :     /* the actual length might be less than destLength if either sort key contained illegally embedded zero bytes */
     187           0 :     return (int32_t)(p-dest);
     188             : }
     189             : 
     190             : U_CAPI int32_t U_EXPORT2
     191           0 : ucol_getSortKey(const    UCollator    *coll,
     192             :         const    UChar        *source,
     193             :         int32_t        sourceLength,
     194             :         uint8_t        *result,
     195             :         int32_t        resultLength)
     196             : {
     197             :     UTRACE_ENTRY(UTRACE_UCOL_GET_SORTKEY);
     198             :     if (UTRACE_LEVEL(UTRACE_VERBOSE)) {
     199             :         UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source string = %vh ", coll, source,
     200             :             ((sourceLength==-1 && source!=NULL) ? u_strlen(source) : sourceLength));
     201             :     }
     202             : 
     203           0 :     int32_t keySize = Collator::fromUCollator(coll)->
     204           0 :             getSortKey(source, sourceLength, result, resultLength);
     205             : 
     206             :     UTRACE_DATA2(UTRACE_VERBOSE, "Sort Key = %vb", result, keySize);
     207             :     UTRACE_EXIT_VALUE(keySize);
     208           0 :     return keySize;
     209             : }
     210             : 
     211             : U_CAPI int32_t U_EXPORT2
     212           0 : ucol_nextSortKeyPart(const UCollator *coll,
     213             :                      UCharIterator *iter,
     214             :                      uint32_t state[2],
     215             :                      uint8_t *dest, int32_t count,
     216             :                      UErrorCode *status)
     217             : {
     218             :     /* error checking */
     219           0 :     if(status==NULL || U_FAILURE(*status)) {
     220           0 :         return 0;
     221             :     }
     222             :     UTRACE_ENTRY(UTRACE_UCOL_NEXTSORTKEYPART);
     223             :     UTRACE_DATA6(UTRACE_VERBOSE, "coll=%p, iter=%p, state=%d %d, dest=%p, count=%d",
     224             :                   coll, iter, state[0], state[1], dest, count);
     225             : 
     226           0 :     int32_t i = Collator::fromUCollator(coll)->
     227           0 :             internalNextSortKeyPart(iter, state, dest, count, *status);
     228             : 
     229             :     // Return number of meaningful sortkey bytes.
     230             :     UTRACE_DATA4(UTRACE_VERBOSE, "dest = %vb, state=%d %d",
     231             :                   dest,i, state[0], state[1]);
     232             :     UTRACE_EXIT_VALUE_STATUS(i, *status);
     233           0 :     return i;
     234             : }
     235             : 
     236             : /**
     237             :  * Produce a bound for a given sortkey and a number of levels.
     238             :  */
     239             : U_CAPI int32_t U_EXPORT2
     240           0 : ucol_getBound(const uint8_t       *source,
     241             :         int32_t             sourceLength,
     242             :         UColBoundMode       boundType,
     243             :         uint32_t            noOfLevels,
     244             :         uint8_t             *result,
     245             :         int32_t             resultLength,
     246             :         UErrorCode          *status)
     247             : {
     248             :     // consistency checks
     249           0 :     if(status == NULL || U_FAILURE(*status)) {
     250           0 :         return 0;
     251             :     }
     252           0 :     if(source == NULL) {
     253           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     254           0 :         return 0;
     255             :     }
     256             : 
     257           0 :     int32_t sourceIndex = 0;
     258             :     // Scan the string until we skip enough of the key OR reach the end of the key
     259           0 :     do {
     260           0 :         sourceIndex++;
     261           0 :         if(source[sourceIndex] == Collation::LEVEL_SEPARATOR_BYTE) {
     262           0 :             noOfLevels--;
     263             :         }
     264             :     } while (noOfLevels > 0
     265           0 :         && (source[sourceIndex] != 0 || sourceIndex < sourceLength));
     266             : 
     267           0 :     if((source[sourceIndex] == 0 || sourceIndex == sourceLength)
     268           0 :         && noOfLevels > 0) {
     269           0 :             *status = U_SORT_KEY_TOO_SHORT_WARNING;
     270             :     }
     271             : 
     272             : 
     273             :     // READ ME: this code assumes that the values for boundType
     274             :     // enum will not changes. They are set so that the enum value
     275             :     // corresponds to the number of extra bytes each bound type
     276             :     // needs.
     277           0 :     if(result != NULL && resultLength >= sourceIndex+boundType) {
     278           0 :         uprv_memcpy(result, source, sourceIndex);
     279           0 :         switch(boundType) {
     280             :             // Lower bound just gets terminated. No extra bytes
     281             :         case UCOL_BOUND_LOWER: // = 0
     282           0 :             break;
     283             :             // Upper bound needs one extra byte
     284             :         case UCOL_BOUND_UPPER: // = 1
     285           0 :             result[sourceIndex++] = 2;
     286           0 :             break;
     287             :             // Upper long bound needs two extra bytes
     288             :         case UCOL_BOUND_UPPER_LONG: // = 2
     289           0 :             result[sourceIndex++] = 0xFF;
     290           0 :             result[sourceIndex++] = 0xFF;
     291           0 :             break;
     292             :         default:
     293           0 :             *status = U_ILLEGAL_ARGUMENT_ERROR;
     294           0 :             return 0;
     295             :         }
     296           0 :         result[sourceIndex++] = 0;
     297             : 
     298           0 :         return sourceIndex;
     299             :     } else {
     300           0 :         return sourceIndex+boundType+1;
     301             :     }
     302             : }
     303             : 
     304             : U_CAPI void U_EXPORT2
     305           0 : ucol_setMaxVariable(UCollator *coll, UColReorderCode group, UErrorCode *pErrorCode) {
     306           0 :     if(U_FAILURE(*pErrorCode)) { return; }
     307           0 :     Collator::fromUCollator(coll)->setMaxVariable(group, *pErrorCode);
     308             : }
     309             : 
     310             : U_CAPI UColReorderCode U_EXPORT2
     311           0 : ucol_getMaxVariable(const UCollator *coll) {
     312           0 :     return Collator::fromUCollator(coll)->getMaxVariable();
     313             : }
     314             : 
     315             : U_CAPI uint32_t  U_EXPORT2
     316           0 : ucol_setVariableTop(UCollator *coll, const UChar *varTop, int32_t len, UErrorCode *status) {
     317           0 :     if(U_FAILURE(*status) || coll == NULL) {
     318           0 :         return 0;
     319             :     }
     320           0 :     return Collator::fromUCollator(coll)->setVariableTop(varTop, len, *status);
     321             : }
     322             : 
     323           0 : U_CAPI uint32_t U_EXPORT2 ucol_getVariableTop(const UCollator *coll, UErrorCode *status) {
     324           0 :     if(U_FAILURE(*status) || coll == NULL) {
     325           0 :         return 0;
     326             :     }
     327           0 :     return Collator::fromUCollator(coll)->getVariableTop(*status);
     328             : }
     329             : 
     330             : U_CAPI void  U_EXPORT2
     331           0 : ucol_restoreVariableTop(UCollator *coll, const uint32_t varTop, UErrorCode *status) {
     332           0 :     if(U_FAILURE(*status) || coll == NULL) {
     333           0 :         return;
     334             :     }
     335           0 :     Collator::fromUCollator(coll)->setVariableTop(varTop, *status);
     336             : }
     337             : 
     338             : U_CAPI void  U_EXPORT2
     339           0 : ucol_setAttribute(UCollator *coll, UColAttribute attr, UColAttributeValue value, UErrorCode *status) {
     340           0 :     if(U_FAILURE(*status) || coll == NULL) {
     341           0 :       return;
     342             :     }
     343             : 
     344           0 :     Collator::fromUCollator(coll)->setAttribute(attr, value, *status);
     345             : }
     346             : 
     347             : U_CAPI UColAttributeValue  U_EXPORT2
     348           0 : ucol_getAttribute(const UCollator *coll, UColAttribute attr, UErrorCode *status) {
     349           0 :     if(U_FAILURE(*status) || coll == NULL) {
     350           0 :       return UCOL_DEFAULT;
     351             :     }
     352             : 
     353           0 :     return Collator::fromUCollator(coll)->getAttribute(attr, *status);
     354             : }
     355             : 
     356             : U_CAPI void U_EXPORT2
     357           0 : ucol_setStrength(    UCollator                *coll,
     358             :             UCollationStrength        strength)
     359             : {
     360           0 :     UErrorCode status = U_ZERO_ERROR;
     361           0 :     ucol_setAttribute(coll, UCOL_STRENGTH, strength, &status);
     362           0 : }
     363             : 
     364             : U_CAPI UCollationStrength U_EXPORT2
     365           0 : ucol_getStrength(const UCollator *coll)
     366             : {
     367           0 :     UErrorCode status = U_ZERO_ERROR;
     368           0 :     return ucol_getAttribute(coll, UCOL_STRENGTH, &status);
     369             : }
     370             : 
     371             : U_CAPI int32_t U_EXPORT2 
     372           0 : ucol_getReorderCodes(const UCollator *coll,
     373             :                     int32_t *dest,
     374             :                     int32_t destCapacity,
     375             :                     UErrorCode *status) {
     376           0 :     if (U_FAILURE(*status)) {
     377           0 :         return 0;
     378             :     }
     379             : 
     380           0 :     return Collator::fromUCollator(coll)->getReorderCodes(dest, destCapacity, *status);
     381             : }
     382             : 
     383             : U_CAPI void U_EXPORT2 
     384           0 : ucol_setReorderCodes(UCollator* coll,
     385             :                     const int32_t* reorderCodes,
     386             :                     int32_t reorderCodesLength,
     387             :                     UErrorCode *status) {
     388           0 :     if (U_FAILURE(*status)) {
     389           0 :         return;
     390             :     }
     391             : 
     392           0 :     Collator::fromUCollator(coll)->setReorderCodes(reorderCodes, reorderCodesLength, *status);
     393             : }
     394             : 
     395             : U_CAPI int32_t U_EXPORT2 
     396           0 : ucol_getEquivalentReorderCodes(int32_t reorderCode,
     397             :                     int32_t* dest,
     398             :                     int32_t destCapacity,
     399             :                     UErrorCode *pErrorCode) {
     400           0 :     return Collator::getEquivalentReorderCodes(reorderCode, dest, destCapacity, *pErrorCode);
     401             : }
     402             : 
     403             : U_CAPI void U_EXPORT2
     404           0 : ucol_getVersion(const UCollator* coll,
     405             :                 UVersionInfo versionInfo)
     406             : {
     407           0 :     Collator::fromUCollator(coll)->getVersion(versionInfo);
     408           0 : }
     409             : 
     410             : U_CAPI UCollationResult U_EXPORT2
     411           0 : ucol_strcollIter( const UCollator    *coll,
     412             :                  UCharIterator *sIter,
     413             :                  UCharIterator *tIter,
     414             :                  UErrorCode         *status)
     415             : {
     416           0 :     if(!status || U_FAILURE(*status)) {
     417           0 :         return UCOL_EQUAL;
     418             :     }
     419             : 
     420             :     UTRACE_ENTRY(UTRACE_UCOL_STRCOLLITER);
     421             :     UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, sIter=%p, tIter=%p", coll, sIter, tIter);
     422             : 
     423           0 :     if(sIter == NULL || tIter == NULL || coll == NULL) {
     424           0 :         *status = U_ILLEGAL_ARGUMENT_ERROR;
     425             :         UTRACE_EXIT_VALUE_STATUS(UCOL_EQUAL, *status);
     426           0 :         return UCOL_EQUAL;
     427             :     }
     428             : 
     429           0 :     UCollationResult result = Collator::fromUCollator(coll)->compare(*sIter, *tIter, *status);
     430             : 
     431             :     UTRACE_EXIT_VALUE_STATUS(result, *status);
     432           0 :     return result;
     433             : }
     434             : 
     435             : 
     436             : /*                                                                      */
     437             : /* ucol_strcoll     Main public API string comparison function          */
     438             : /*                                                                      */
     439             : U_CAPI UCollationResult U_EXPORT2
     440           0 : ucol_strcoll( const UCollator    *coll,
     441             :               const UChar        *source,
     442             :               int32_t            sourceLength,
     443             :               const UChar        *target,
     444             :               int32_t            targetLength)
     445             : {
     446             :     UTRACE_ENTRY(UTRACE_UCOL_STRCOLL);
     447             :     if (UTRACE_LEVEL(UTRACE_VERBOSE)) {
     448             :         UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source=%p, target=%p", coll, source, target);
     449             :         UTRACE_DATA2(UTRACE_VERBOSE, "source string = %vh ", source, sourceLength);
     450             :         UTRACE_DATA2(UTRACE_VERBOSE, "target string = %vh ", target, targetLength);
     451             :     }
     452             : 
     453           0 :     UErrorCode status = U_ZERO_ERROR;
     454           0 :     UCollationResult returnVal = Collator::fromUCollator(coll)->
     455           0 :             compare(source, sourceLength, target, targetLength, status);
     456             :     UTRACE_EXIT_VALUE_STATUS(returnVal, status);
     457           0 :     return returnVal;
     458             : }
     459             : 
     460             : U_CAPI UCollationResult U_EXPORT2
     461           0 : ucol_strcollUTF8(
     462             :         const UCollator *coll,
     463             :         const char      *source,
     464             :         int32_t         sourceLength,
     465             :         const char      *target,
     466             :         int32_t         targetLength,
     467             :         UErrorCode      *status)
     468             : {
     469             :     UTRACE_ENTRY(UTRACE_UCOL_STRCOLLUTF8);
     470             :     if (UTRACE_LEVEL(UTRACE_VERBOSE)) {
     471             :         UTRACE_DATA3(UTRACE_VERBOSE, "coll=%p, source=%p, target=%p", coll, source, target);
     472             :         UTRACE_DATA2(UTRACE_VERBOSE, "source string = %vb ", source, sourceLength);
     473             :         UTRACE_DATA2(UTRACE_VERBOSE, "target string = %vb ", target, targetLength);
     474             :     }
     475             : 
     476           0 :     if (U_FAILURE(*status)) {
     477             :         /* do nothing */
     478             :         UTRACE_EXIT_VALUE_STATUS(UCOL_EQUAL, *status);
     479           0 :         return UCOL_EQUAL;
     480             :     }
     481             : 
     482           0 :     UCollationResult returnVal = Collator::fromUCollator(coll)->internalCompareUTF8(
     483           0 :             source, sourceLength, target, targetLength, *status);
     484             :     UTRACE_EXIT_VALUE_STATUS(returnVal, *status);
     485           0 :     return returnVal;
     486             : }
     487             : 
     488             : 
     489             : /* convenience function for comparing strings */
     490             : U_CAPI UBool U_EXPORT2
     491           0 : ucol_greater(    const    UCollator        *coll,
     492             :         const    UChar            *source,
     493             :         int32_t            sourceLength,
     494             :         const    UChar            *target,
     495             :         int32_t            targetLength)
     496             : {
     497           0 :     return (ucol_strcoll(coll, source, sourceLength, target, targetLength)
     498           0 :         == UCOL_GREATER);
     499             : }
     500             : 
     501             : /* convenience function for comparing strings */
     502             : U_CAPI UBool U_EXPORT2
     503           0 : ucol_greaterOrEqual(    const    UCollator    *coll,
     504             :             const    UChar        *source,
     505             :             int32_t        sourceLength,
     506             :             const    UChar        *target,
     507             :             int32_t        targetLength)
     508             : {
     509           0 :     return (ucol_strcoll(coll, source, sourceLength, target, targetLength)
     510           0 :         != UCOL_LESS);
     511             : }
     512             : 
     513             : /* convenience function for comparing strings */
     514             : U_CAPI UBool U_EXPORT2
     515           0 : ucol_equal(        const    UCollator        *coll,
     516             :             const    UChar            *source,
     517             :             int32_t            sourceLength,
     518             :             const    UChar            *target,
     519             :             int32_t            targetLength)
     520             : {
     521           0 :     return (ucol_strcoll(coll, source, sourceLength, target, targetLength)
     522           0 :         == UCOL_EQUAL);
     523             : }
     524             : 
     525             : U_CAPI void U_EXPORT2
     526           0 : ucol_getUCAVersion(const UCollator* coll, UVersionInfo info) {
     527           0 :     const Collator *c = Collator::fromUCollator(coll);
     528           0 :     if(c != NULL) {
     529             :         UVersionInfo v;
     530           0 :         c->getVersion(v);
     531             :         // Note: This is tied to how the current implementation encodes the UCA version
     532             :         // in the overall getVersion().
     533             :         // Alternatively, we could load the root collator and get at lower-level data from there.
     534             :         // Either way, it will reflect the input collator's UCA version only
     535             :         // if it is a known implementation.
     536             :         // It would be cleaner to make this a virtual Collator method.
     537           0 :         info[0] = v[1] >> 3;
     538           0 :         info[1] = v[1] & 7;
     539           0 :         info[2] = v[2] >> 6;
     540           0 :         info[3] = 0;
     541             :     }
     542           0 : }
     543             : 
     544             : U_CAPI const UChar * U_EXPORT2
     545           0 : ucol_getRules(const UCollator *coll, int32_t *length) {
     546           0 :     const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll);
     547             :     // OK to crash if coll==NULL: We do not want to check "this" pointers.
     548           0 :     if(rbc != NULL || coll == NULL) {
     549           0 :         const UnicodeString &rules = rbc->getRules();
     550           0 :         U_ASSERT(rules.getBuffer()[rules.length()] == 0);
     551           0 :         *length = rules.length();
     552           0 :         return rules.getBuffer();
     553             :     }
     554             :     static const UChar _NUL = 0;
     555           0 :     *length = 0;
     556           0 :     return &_NUL;
     557             : }
     558             : 
     559             : U_CAPI int32_t U_EXPORT2
     560           0 : ucol_getRulesEx(const UCollator *coll, UColRuleOption delta, UChar *buffer, int32_t bufferLen) {
     561           0 :     UnicodeString rules;
     562           0 :     const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll);
     563           0 :     if(rbc != NULL || coll == NULL) {
     564           0 :         rbc->getRules(delta, rules);
     565             :     }
     566           0 :     if(buffer != NULL && bufferLen > 0) {
     567           0 :         UErrorCode errorCode = U_ZERO_ERROR;
     568           0 :         return rules.extract(buffer, bufferLen, errorCode);
     569             :     } else {
     570           0 :         return rules.length();
     571             :     }
     572             : }
     573             : 
     574             : U_CAPI const char * U_EXPORT2
     575           0 : ucol_getLocale(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) {
     576           0 :     return ucol_getLocaleByType(coll, type, status);
     577             : }
     578             : 
     579             : U_CAPI const char * U_EXPORT2
     580           0 : ucol_getLocaleByType(const UCollator *coll, ULocDataLocaleType type, UErrorCode *status) {
     581           0 :     if(U_FAILURE(*status)) {
     582           0 :         return NULL;
     583             :     }
     584             :     UTRACE_ENTRY(UTRACE_UCOL_GETLOCALE);
     585             :     UTRACE_DATA1(UTRACE_INFO, "coll=%p", coll);
     586             : 
     587             :     const char *result;
     588           0 :     const RuleBasedCollator *rbc = RuleBasedCollator::rbcFromUCollator(coll);
     589           0 :     if(rbc == NULL && coll != NULL) {
     590           0 :         *status = U_UNSUPPORTED_ERROR;
     591           0 :         result = NULL;
     592             :     } else {
     593           0 :         result = rbc->internalGetLocaleID(type, *status);
     594             :     }
     595             : 
     596             :     UTRACE_DATA1(UTRACE_INFO, "result = %s", result);
     597             :     UTRACE_EXIT_STATUS(*status);
     598           0 :     return result;
     599             : }
     600             : 
     601             : U_CAPI USet * U_EXPORT2
     602           0 : ucol_getTailoredSet(const UCollator *coll, UErrorCode *status) {
     603           0 :     if(U_FAILURE(*status)) {
     604           0 :         return NULL;
     605             :     }
     606           0 :     UnicodeSet *set = Collator::fromUCollator(coll)->getTailoredSet(*status);
     607           0 :     if(U_FAILURE(*status)) {
     608           0 :         delete set;
     609           0 :         return NULL;
     610             :     }
     611           0 :     return set->toUSet();
     612             : }
     613             : 
     614             : U_CAPI UBool U_EXPORT2
     615           0 : ucol_equals(const UCollator *source, const UCollator *target) {
     616           0 :     return source == target ||
     617           0 :         (*Collator::fromUCollator(source)) == (*Collator::fromUCollator(target));
     618             : }
     619             : 
     620             : #endif /* #if !UCONFIG_NO_COLLATION */

Generated by: LCOV version 1.13