12e5b6d6dSopenharmony_ci// © 2017 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci/*
42e5b6d6dSopenharmony_ci*******************************************************************************
52e5b6d6dSopenharmony_ci*
62e5b6d6dSopenharmony_ci*   Copyright (C) 2009-2012, International Business Machines
72e5b6d6dSopenharmony_ci*   Corporation and others.  All Rights Reserved.
82e5b6d6dSopenharmony_ci*
92e5b6d6dSopenharmony_ci*******************************************************************************
102e5b6d6dSopenharmony_ci*/
112e5b6d6dSopenharmony_ci
122e5b6d6dSopenharmony_ci#ifndef COLL_FE_DEBUG
132e5b6d6dSopenharmony_ci#define COLL_FE_DEBUG 0
142e5b6d6dSopenharmony_ci#endif
152e5b6d6dSopenharmony_ci
162e5b6d6dSopenharmony_ci#include <icuglue/icuglue.h>
172e5b6d6dSopenharmony_ci#include <unicode/coll.h>
182e5b6d6dSopenharmony_ci//#include <unicode/tblcoll.h>
192e5b6d6dSopenharmony_ci#include <unicode/ucol.h>
202e5b6d6dSopenharmony_ci#include <string.h>
212e5b6d6dSopenharmony_ci#include <stdio.h>
222e5b6d6dSopenharmony_ci#include "unicode/ustring.h"
232e5b6d6dSopenharmony_ci
242e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
252e5b6d6dSopenharmony_ci#define debugfprintf(x) fprintf x
262e5b6d6dSopenharmony_ci#else
272e5b6d6dSopenharmony_ci#define debugfprintf(x)
282e5b6d6dSopenharmony_ci#endif
292e5b6d6dSopenharmony_ci
302e5b6d6dSopenharmony_ci/*
312e5b6d6dSopenharmony_ci * Before ICU 50.0.2 (50m2) - there was a different collator signature.
322e5b6d6dSopenharmony_ci * see: ticket:9460 ticket:9346
332e5b6d6dSopenharmony_ci */
342e5b6d6dSopenharmony_ci#if (U_ICU_VERSION_MAJOR_NUM < 50) || ((U_ICU_VERSION_MAJOR_NUM==50)&&(U_ICU_VERSION_MINOR_NUM==0)&&(U_ICU_VERSION_PATCHLEVEL_NUM<2))
352e5b6d6dSopenharmony_ci#define PRE_50_0_2_COLLATOR
362e5b6d6dSopenharmony_ci#define CONST_BEFORE_50_0_2 const
372e5b6d6dSopenharmony_ci#define CONST_AFTER_50_0_2
382e5b6d6dSopenharmony_ci#define REF_AFTER_50_0_2
392e5b6d6dSopenharmony_ci#else
402e5b6d6dSopenharmony_ci/* "current" API */
412e5b6d6dSopenharmony_ci#define CONST_BEFORE_50_0_2
422e5b6d6dSopenharmony_ci#define CONST_AFTER_50_0_2 const
432e5b6d6dSopenharmony_ci#define REF_AFTER_50_0_2 &
442e5b6d6dSopenharmony_ci#endif
452e5b6d6dSopenharmony_ci
462e5b6d6dSopenharmony_ci/**
472e5b6d6dSopenharmony_ci * Macro to define the Collator_glue_4_2 class
482e5b6d6dSopenharmony_ci */
492e5b6d6dSopenharmony_ci#define GLUE_VER(x) class GLUE_SYM_V( Collator, x ) : public Collator {  \
502e5b6d6dSopenharmony_ci    \
512e5b6d6dSopenharmony_ci  public:  static Collator *create(const Locale &loc, const char *ver); \
522e5b6d6dSopenharmony_ci  private: UCollator *_this; GLUE_SYM_V( Collator, x ) ( UCollator* tn ) : _this(tn){} \
532e5b6d6dSopenharmony_ci    virtual ~ GLUE_SYM_V ( Collator, x) ();                             \
542e5b6d6dSopenharmony_ci  public:                                                               \
552e5b6d6dSopenharmony_ci    virtual void* getDynamicClassID() const;                            \
562e5b6d6dSopenharmony_ci    static void* getStaticClassID() ;                                   \
572e5b6d6dSopenharmony_ci    virtual Collator* clone() const;                                    \
582e5b6d6dSopenharmony_ci    virtual UCollationResult compare(const UnicodeString&, const UnicodeString&, UErrorCode&) const; \
592e5b6d6dSopenharmony_ci    virtual UCollationResult compare(const UnicodeString&, const UnicodeString&, int32_t, UErrorCode&) const; \
602e5b6d6dSopenharmony_ci    virtual UCollationResult compare(const UChar*, int32_t, const UChar*, int32_t, UErrorCode&) const; \
612e5b6d6dSopenharmony_ci    virtual CollationKey& getCollationKey(const UnicodeString&, CollationKey&, UErrorCode&) const; \
622e5b6d6dSopenharmony_ci    virtual CollationKey& getCollationKey(const UChar*, int32_t, CollationKey&, UErrorCode&) const; \
632e5b6d6dSopenharmony_ci    virtual int32_t hashCode() const;                                   \
642e5b6d6dSopenharmony_ci    virtual CONST_BEFORE_50_0_2 Locale getLocale(ULocDataLocaleType, UErrorCode&) const; \
652e5b6d6dSopenharmony_ci    virtual ECollationStrength getStrength() const;                     \
662e5b6d6dSopenharmony_ci    virtual void setStrength(ECollationStrength);                       \
672e5b6d6dSopenharmony_ci    virtual void getVersion(uint8_t*) const;                            \
682e5b6d6dSopenharmony_ci    virtual void setAttribute(UColAttribute, UColAttributeValue, UErrorCode&) ; \
692e5b6d6dSopenharmony_ci    virtual UColAttributeValue getAttribute(UColAttribute, UErrorCode&) CONST_AFTER_50_0_2; \
702e5b6d6dSopenharmony_ci    virtual uint32_t setVariableTop(const UChar*, int32_t, UErrorCode&); \
712e5b6d6dSopenharmony_ci    virtual uint32_t setVariableTop(const UnicodeString REF_AFTER_50_0_2, UErrorCode&);        \
722e5b6d6dSopenharmony_ci    virtual void setVariableTop(uint32_t, UErrorCode&);                 \
732e5b6d6dSopenharmony_ci    virtual uint32_t getVariableTop(UErrorCode&) const;                 \
742e5b6d6dSopenharmony_ci    virtual Collator* safeClone() CONST_AFTER_50_0_2 ;                                      \
752e5b6d6dSopenharmony_ci    virtual int32_t getSortKey(const UnicodeString&, uint8_t*, int32_t) const; \
762e5b6d6dSopenharmony_ci    virtual int32_t getSortKey(const UChar*, int32_t, uint8_t*, int32_t) const; \
772e5b6d6dSopenharmony_ci  public: static int32_t countAvailable();                              \
782e5b6d6dSopenharmony_ci  public: static int32_t appendAvailable(UnicodeString* strs, int32_t i, int32_t count); \
792e5b6d6dSopenharmony_ci  public: virtual int32_t internalGetShortDefinitionString(const char *locale, char *buffer, int32_t capacity, UErrorCode &status) const; \
802e5b6d6dSopenharmony_ci  };
812e5b6d6dSopenharmony_ci
822e5b6d6dSopenharmony_ci/** ==================================== The following code runs inside the 'target' version (i.e. old ICU) ========== **/
832e5b6d6dSopenharmony_ci#if defined ( ICUGLUE_VER )
842e5b6d6dSopenharmony_ci
852e5b6d6dSopenharmony_ci
862e5b6d6dSopenharmony_ci// these from tblcoll.h
872e5b6d6dSopenharmony_cistatic Collator::ECollationStrength _getECollationStrength(
882e5b6d6dSopenharmony_ci                                       const UCollationStrength &strength)
892e5b6d6dSopenharmony_ci{
902e5b6d6dSopenharmony_ci    switch (strength)
912e5b6d6dSopenharmony_ci    {
922e5b6d6dSopenharmony_ci    case UCOL_PRIMARY :
932e5b6d6dSopenharmony_ci        return Collator::PRIMARY;
942e5b6d6dSopenharmony_ci    case UCOL_SECONDARY :
952e5b6d6dSopenharmony_ci        return Collator::SECONDARY;
962e5b6d6dSopenharmony_ci    case UCOL_TERTIARY :
972e5b6d6dSopenharmony_ci        return Collator::TERTIARY;
982e5b6d6dSopenharmony_ci    case UCOL_QUATERNARY :
992e5b6d6dSopenharmony_ci        return Collator::QUATERNARY;
1002e5b6d6dSopenharmony_ci    default :
1012e5b6d6dSopenharmony_ci        return Collator::IDENTICAL;
1022e5b6d6dSopenharmony_ci    }
1032e5b6d6dSopenharmony_ci}
1042e5b6d6dSopenharmony_ci
1052e5b6d6dSopenharmony_cistatic UCollationStrength _getUCollationStrength(
1062e5b6d6dSopenharmony_ci                             const Collator::ECollationStrength &strength)
1072e5b6d6dSopenharmony_ci{
1082e5b6d6dSopenharmony_ci    switch (strength)
1092e5b6d6dSopenharmony_ci    {
1102e5b6d6dSopenharmony_ci    case Collator::PRIMARY :
1112e5b6d6dSopenharmony_ci        return UCOL_PRIMARY;
1122e5b6d6dSopenharmony_ci    case Collator::SECONDARY :
1132e5b6d6dSopenharmony_ci        return UCOL_SECONDARY;
1142e5b6d6dSopenharmony_ci    case Collator::TERTIARY :
1152e5b6d6dSopenharmony_ci        return UCOL_TERTIARY;
1162e5b6d6dSopenharmony_ci    case Collator::QUATERNARY :
1172e5b6d6dSopenharmony_ci        return UCOL_QUATERNARY;
1182e5b6d6dSopenharmony_ci    default :
1192e5b6d6dSopenharmony_ci        return UCOL_IDENTICAL;
1202e5b6d6dSopenharmony_ci    }
1212e5b6d6dSopenharmony_ci}
1222e5b6d6dSopenharmony_ci
1232e5b6d6dSopenharmony_ci
1242e5b6d6dSopenharmony_ci
1252e5b6d6dSopenharmony_ci/* code for some version */
1262e5b6d6dSopenharmony_ci#include <icuglue/gluren.h>
1272e5b6d6dSopenharmony_ci
1282e5b6d6dSopenharmony_ci#include "oicu.h"
1292e5b6d6dSopenharmony_ci
1302e5b6d6dSopenharmony_ci/* Expand GLUE_VER to define the class */
1312e5b6d6dSopenharmony_ci#ifdef GLUE_VER
1322e5b6d6dSopenharmony_ciGLUE_VER( ICUGLUE_VER )
1332e5b6d6dSopenharmony_ci#endif
1342e5b6d6dSopenharmony_ci
1352e5b6d6dSopenharmony_ciGLUE_SYM ( Collator ) :: ~ GLUE_SYM(Collator) () {
1362e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
1372e5b6d6dSopenharmony_ci    fprintf(stderr, "VCF " ICUGLUE_VER_STR " ucol_close");
1382e5b6d6dSopenharmony_ci#endif
1392e5b6d6dSopenharmony_ci    OICU_ucol_close(_this);
1402e5b6d6dSopenharmony_ci}
1412e5b6d6dSopenharmony_ci
1422e5b6d6dSopenharmony_ci#if 0
1432e5b6d6dSopenharmony_ciU_CFUNC int32_t U_CALLCONV
1442e5b6d6dSopenharmony_ciGLUE_SYM ( glue_calcSortKey) (const    UCollator    *coll,
1452e5b6d6dSopenharmony_ci        const    UChar        *source,
1462e5b6d6dSopenharmony_ci        int32_t        sourceLength,
1472e5b6d6dSopenharmony_ci        uint8_t        **result,
1482e5b6d6dSopenharmony_ci        uint32_t        resultLength,
1492e5b6d6dSopenharmony_ci        UBool allocateSKBuffer,
1502e5b6d6dSopenharmony_ci        UErrorCode *status);
1512e5b6d6dSopenharmony_ci
1522e5b6d6dSopenharmony_ci#endif
1532e5b6d6dSopenharmony_ci
1542e5b6d6dSopenharmony_ciCollator *
1552e5b6d6dSopenharmony_ciGLUE_SYM ( Collator ) :: create (const Locale &loc, const char */*ver*/) {
1562e5b6d6dSopenharmony_ci  // TODO: save 'ver' off.
1572e5b6d6dSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
1582e5b6d6dSopenharmony_ci    char locBuf[200];
1592e5b6d6dSopenharmony_ci    char kwvBuf[200];
1602e5b6d6dSopenharmony_ci    int32_t len = loc.getKeywordValue("collation", kwvBuf, 200, status);
1612e5b6d6dSopenharmony_ci    strcpy(locBuf,loc.getBaseName());
1622e5b6d6dSopenharmony_ci    if(len>0) {
1632e5b6d6dSopenharmony_ci        strcat(locBuf,"@collator=");
1642e5b6d6dSopenharmony_ci        strcat(locBuf,kwvBuf);
1652e5b6d6dSopenharmony_ci    }
1662e5b6d6dSopenharmony_ci    UCollator * uc =  OICU_ucol_open( locBuf, status);
1672e5b6d6dSopenharmony_ci    if(U_FAILURE(status)) return NULL; // TODO: ERR?
1682e5b6d6dSopenharmony_ci    Collator *c =  new GLUE_SYM( Collator ) ( uc );
1692e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
1702e5b6d6dSopenharmony_ci    fprintf(stderr, "VCF " ICUGLUE_VER_STR " ucol_open=%s ->> %p\n", locBuf, c);
1712e5b6d6dSopenharmony_ci#endif
1722e5b6d6dSopenharmony_ci    return c;
1732e5b6d6dSopenharmony_ci}
1742e5b6d6dSopenharmony_ci
1752e5b6d6dSopenharmony_ciUOBJECT_DEFINE_RTTI_IMPLEMENTATION( GLUE_SYM( Collator ) )
1762e5b6d6dSopenharmony_ci
1772e5b6d6dSopenharmony_ciCollator* GLUE_SYM ( Collator ) :: clone() const  {
1782e5b6d6dSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
1792e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
1802e5b6d6dSopenharmony_ci    fprintf(stderr, "VCF " ICUGLUE_VER_STR " clone %p -> " , this);
1812e5b6d6dSopenharmony_ci#endif
1822e5b6d6dSopenharmony_ci    UCollator *clc = OICU_ucol_safeClone( _this, NULL, 0, &status);
1832e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
1842e5b6d6dSopenharmony_ci    fprintf(stderr, "VCF " ICUGLUE_VER_STR " .. safeclone %s _this %p-> %p " , u_errorName(status), _this, clc);
1852e5b6d6dSopenharmony_ci#endif
1862e5b6d6dSopenharmony_ci    if(U_FAILURE(status)||clc==NULL) return NULL;
1872e5b6d6dSopenharmony_ci    Collator *c = new GLUE_SYM( Collator ) ( clc );
1882e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
1892e5b6d6dSopenharmony_ci    fprintf(stderr, "VCF " ICUGLUE_VER_STR " .. wrap(%p) -> %p\n", clc, c);
1902e5b6d6dSopenharmony_ci#endif
1912e5b6d6dSopenharmony_ci
1922e5b6d6dSopenharmony_ci    return c;
1932e5b6d6dSopenharmony_ci}
1942e5b6d6dSopenharmony_ci
1952e5b6d6dSopenharmony_ci
1962e5b6d6dSopenharmony_ciUCollationResult GLUE_SYM ( Collator ) :: compare(const UnicodeString&, const UnicodeString&, UErrorCode&) const  {
1972e5b6d6dSopenharmony_ci    return (UCollationResult)0;
1982e5b6d6dSopenharmony_ci}
1992e5b6d6dSopenharmony_ci
2002e5b6d6dSopenharmony_ci
2012e5b6d6dSopenharmony_ciUCollationResult GLUE_SYM ( Collator ) :: compare(const UnicodeString&, const UnicodeString&, int32_t, UErrorCode&) const  {
2022e5b6d6dSopenharmony_ci    return (UCollationResult)0;
2032e5b6d6dSopenharmony_ci}
2042e5b6d6dSopenharmony_ci
2052e5b6d6dSopenharmony_ci
2062e5b6d6dSopenharmony_ciUCollationResult GLUE_SYM ( Collator ) :: compare(const UChar* s, int32_t sl, const UChar* d , int32_t dl, UErrorCode&/*e*/ ) const  {
2072e5b6d6dSopenharmony_ci    return OICU_ucol_strcoll(_this, s, sl, d, dl);
2082e5b6d6dSopenharmony_ci}
2092e5b6d6dSopenharmony_ci
2102e5b6d6dSopenharmony_ci#include "unicode/sortkey.h"
2112e5b6d6dSopenharmony_ci
2122e5b6d6dSopenharmony_cistatic CollationKey kk;
2132e5b6d6dSopenharmony_ci
2142e5b6d6dSopenharmony_ciCollationKey& GLUE_SYM ( Collator ) :: getCollationKey(const UnicodeString&, CollationKey&, UErrorCode&) const  {
2152e5b6d6dSopenharmony_ci  //#if COLL_FE_DEBUG
2162e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GCK - notimp");
2172e5b6d6dSopenharmony_ci    //#endif
2182e5b6d6dSopenharmony_cireturn kk;
2192e5b6d6dSopenharmony_ci}
2202e5b6d6dSopenharmony_ci
2212e5b6d6dSopenharmony_ci
2222e5b6d6dSopenharmony_ciCollationKey& GLUE_SYM ( Collator ) :: getCollationKey(const UChar*, int32_t, CollationKey&, UErrorCode&) const  {
2232e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GKK2 - notimp");
2242e5b6d6dSopenharmony_cireturn kk;
2252e5b6d6dSopenharmony_ci}
2262e5b6d6dSopenharmony_ci
2272e5b6d6dSopenharmony_ci
2282e5b6d6dSopenharmony_ciint32_t GLUE_SYM ( Collator ) :: hashCode() const  {
2292e5b6d6dSopenharmony_ci    return 0;
2302e5b6d6dSopenharmony_ci}
2312e5b6d6dSopenharmony_ci
2322e5b6d6dSopenharmony_ci
2332e5b6d6dSopenharmony_ciCONST_BEFORE_50_0_2 Locale GLUE_SYM ( Collator ) :: getLocale(ULocDataLocaleType, UErrorCode&) const  {
2342e5b6d6dSopenharmony_ci    return Locale();
2352e5b6d6dSopenharmony_ci}
2362e5b6d6dSopenharmony_ci
2372e5b6d6dSopenharmony_ci
2382e5b6d6dSopenharmony_ciCollator::ECollationStrength
2392e5b6d6dSopenharmony_ci GLUE_SYM ( Collator ) :: getStrength() const  {
2402e5b6d6dSopenharmony_ci    return _getECollationStrength(OICU_ucol_getStrength(_this));
2412e5b6d6dSopenharmony_ci}
2422e5b6d6dSopenharmony_ci
2432e5b6d6dSopenharmony_ci
2442e5b6d6dSopenharmony_civoid GLUE_SYM ( Collator ) :: setStrength(ECollationStrength s)  {
2452e5b6d6dSopenharmony_ci    OICU_ucol_setStrength(_this, _getUCollationStrength(s));
2462e5b6d6dSopenharmony_ci}
2472e5b6d6dSopenharmony_ci
2482e5b6d6dSopenharmony_ci
2492e5b6d6dSopenharmony_civoid GLUE_SYM ( Collator ) :: getVersion(uint8_t*) const  {
2502e5b6d6dSopenharmony_ci}
2512e5b6d6dSopenharmony_ci
2522e5b6d6dSopenharmony_ci
2532e5b6d6dSopenharmony_civoid GLUE_SYM ( Collator ) :: setAttribute(UColAttribute, UColAttributeValue, UErrorCode&) {
2542e5b6d6dSopenharmony_ci}
2552e5b6d6dSopenharmony_ci
2562e5b6d6dSopenharmony_ci
2572e5b6d6dSopenharmony_ciUColAttributeValue GLUE_SYM ( Collator ) :: getAttribute(UColAttribute, UErrorCode&) CONST_AFTER_50_0_2 {
2582e5b6d6dSopenharmony_cireturn (UColAttributeValue)0;
2592e5b6d6dSopenharmony_ci}
2602e5b6d6dSopenharmony_ci
2612e5b6d6dSopenharmony_ci
2622e5b6d6dSopenharmony_ciuint32_t GLUE_SYM ( Collator ) :: setVariableTop(const UChar*, int32_t, UErrorCode&)  {
2632e5b6d6dSopenharmony_cireturn 0;
2642e5b6d6dSopenharmony_ci}
2652e5b6d6dSopenharmony_ci
2662e5b6d6dSopenharmony_ci
2672e5b6d6dSopenharmony_ciuint32_t GLUE_SYM ( Collator ) :: setVariableTop(const UnicodeString REF_AFTER_50_0_2, UErrorCode&)  {
2682e5b6d6dSopenharmony_cireturn 0;
2692e5b6d6dSopenharmony_ci}
2702e5b6d6dSopenharmony_ci
2712e5b6d6dSopenharmony_ci
2722e5b6d6dSopenharmony_civoid GLUE_SYM ( Collator ) :: setVariableTop(uint32_t, UErrorCode&)  {
2732e5b6d6dSopenharmony_ci}
2742e5b6d6dSopenharmony_ci
2752e5b6d6dSopenharmony_ci
2762e5b6d6dSopenharmony_ciuint32_t GLUE_SYM ( Collator ) :: getVariableTop(UErrorCode&) const  {
2772e5b6d6dSopenharmony_cireturn 0;
2782e5b6d6dSopenharmony_ci}
2792e5b6d6dSopenharmony_ci
2802e5b6d6dSopenharmony_ci
2812e5b6d6dSopenharmony_ciCollator* GLUE_SYM ( Collator ) :: safeClone() CONST_AFTER_50_0_2 {
2822e5b6d6dSopenharmony_ci    return clone();
2832e5b6d6dSopenharmony_ci}
2842e5b6d6dSopenharmony_ci
2852e5b6d6dSopenharmony_ci
2862e5b6d6dSopenharmony_ciint32_t GLUE_SYM ( Collator ) :: getSortKey(const UnicodeString& s, uint8_t*buf, int32_t len) const  {
2872e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
2882e5b6d6dSopenharmony_ci  fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GSK");
2892e5b6d6dSopenharmony_ci#endif
2902e5b6d6dSopenharmony_ci    return getSortKey(s.getBuffer(),s.length(), buf, len);
2912e5b6d6dSopenharmony_ci}
2922e5b6d6dSopenharmony_ci
2932e5b6d6dSopenharmony_ci
2942e5b6d6dSopenharmony_ci
2952e5b6d6dSopenharmony_ci
2962e5b6d6dSopenharmony_ciint32_t GLUE_SYM ( Collator ) :: getSortKey(const UChar*s, int32_t l, uint8_t*d, int32_t b) const  {
2972e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
2982e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF " ICUGLUE_VER_STR " GKS");
2992e5b6d6dSopenharmony_ci#endif
3002e5b6d6dSopenharmony_ci    return OICU_ucol_getSortKey(_this, s,l,d,b);
3012e5b6d6dSopenharmony_ci}
3022e5b6d6dSopenharmony_ci
3032e5b6d6dSopenharmony_ciint32_t GLUE_SYM (Collator ) ::  internalGetShortDefinitionString(const char *locale, char *buffer, int32_t capacity, UErrorCode &status) const {
3042e5b6d6dSopenharmony_ci  if(U_FAILURE(status)) return 0;
3052e5b6d6dSopenharmony_ci  int32_t intRes = OICU_ucol_getShortDefinitionString(_this, locale, buffer, capacity, &status);
3062e5b6d6dSopenharmony_ci  int32_t newRes = (intRes += 7); /* _PICU38 */
3072e5b6d6dSopenharmony_ci  int32_t remainCap = capacity - newRes;
3082e5b6d6dSopenharmony_ci
3092e5b6d6dSopenharmony_ci  if(remainCap < 0 && U_SUCCESS(status)) {
3102e5b6d6dSopenharmony_ci    status = U_BUFFER_OVERFLOW_ERROR; /* ran out of space on our watch */
3112e5b6d6dSopenharmony_ci  }
3122e5b6d6dSopenharmony_ci  if(U_SUCCESS(status)) {
3132e5b6d6dSopenharmony_ci    char *p = buffer+strlen(buffer);
3142e5b6d6dSopenharmony_ci    strncat(p,"_PICU",5);
3152e5b6d6dSopenharmony_ci    p +=5 ;
3162e5b6d6dSopenharmony_ci    CPY_VERSTR(p, ICUGLUE_VER_STR);
3172e5b6d6dSopenharmony_ci    p +=2;
3182e5b6d6dSopenharmony_ci    if(remainCap>0) {
3192e5b6d6dSopenharmony_ci      *(p++)=0;
3202e5b6d6dSopenharmony_ci    }
3212e5b6d6dSopenharmony_ci  }
3222e5b6d6dSopenharmony_ci  return newRes;
3232e5b6d6dSopenharmony_ci}
3242e5b6d6dSopenharmony_ci
3252e5b6d6dSopenharmony_ci
3262e5b6d6dSopenharmony_ci
3272e5b6d6dSopenharmony_ci int32_t GLUE_SYM ( Collator ) :: countAvailable() {
3282e5b6d6dSopenharmony_ci    int32_t count =  OICU_ucol_countAvailable();
3292e5b6d6dSopenharmony_ci    return count;
3302e5b6d6dSopenharmony_ci }
3312e5b6d6dSopenharmony_ci
3322e5b6d6dSopenharmony_ci
3332e5b6d6dSopenharmony_ciint32_t GLUE_SYM ( Collator ) :: appendAvailable(UnicodeString* strs, int32_t i, int32_t /*count*/) {
3342e5b6d6dSopenharmony_ci   int avail = OICU_ucol_countAvailable();
3352e5b6d6dSopenharmony_ci   UErrorCode status = U_ZERO_ERROR;
3362e5b6d6dSopenharmony_ci   OICU_u_init(&status);
3372e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
3382e5b6d6dSopenharmony_ci   fprintf(stderr,  "VCF " ICUGLUE_VER_STR " avail %d - init %s\n", avail, u_errorName(status));
3392e5b6d6dSopenharmony_ci#endif
3402e5b6d6dSopenharmony_ci    for(int j=0;j<avail;j++) {
3412e5b6d6dSopenharmony_ci         strs[i+j].append(OICU_ucol_getAvailable(j));
3422e5b6d6dSopenharmony_ci         strs[i+j].append("@sp=icu");
3432e5b6d6dSopenharmony_ci
3442e5b6d6dSopenharmony_ci         if(IS_OLD_VERSTR(ICUGLUE_VER_STR)) {
3452e5b6d6dSopenharmony_ci           strs[i+j].append( ICUGLUE_VER_STR[OLD_VERSTR_MAJ] );  // X_y
3462e5b6d6dSopenharmony_ci           strs[i+j].append( ICUGLUE_VER_STR[OLD_VERSTR_MIN] );  // x_Y
3472e5b6d6dSopenharmony_ci         } else {
3482e5b6d6dSopenharmony_ci           strs[i+j].append( ICUGLUE_VER_STR[NEW_VERSTR_MAJ] );  // Xy_
3492e5b6d6dSopenharmony_ci           strs[i+j].append( ICUGLUE_VER_STR[NEW_VERSTR_MIN] );  // xY_
3502e5b6d6dSopenharmony_ci         }
3512e5b6d6dSopenharmony_ci
3522e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
3532e5b6d6dSopenharmony_ci         {
3542e5b6d6dSopenharmony_ci            char foo[999];
3552e5b6d6dSopenharmony_ci            const UChar *ss = strs[i+j].getTerminatedBuffer();
3562e5b6d6dSopenharmony_ci            u_austrcpy(foo, ss);
3572e5b6d6dSopenharmony_ci            debugfprintf((stderr,  "VCF " ICUGLUE_VER_STR " appending [%d+%d=%d] <<%s>>\n", i, j, i+j, foo));
3582e5b6d6dSopenharmony_ci        }
3592e5b6d6dSopenharmony_ci#endif
3602e5b6d6dSopenharmony_ci    }
3612e5b6d6dSopenharmony_ci    return OICU_ucol_countAvailable();
3622e5b6d6dSopenharmony_ci }
3632e5b6d6dSopenharmony_ci
3642e5b6d6dSopenharmony_ci
3652e5b6d6dSopenharmony_ci
3662e5b6d6dSopenharmony_ci#else
3672e5b6d6dSopenharmony_ci/** ==================================== The following code runs inside the 'provider' version (i.e. current ICU) ========== **/
3682e5b6d6dSopenharmony_ci
3692e5b6d6dSopenharmony_ci// define Collator_XX
3702e5b6d6dSopenharmony_ci#include "icuglue/glver.h"
3712e5b6d6dSopenharmony_ci
3722e5b6d6dSopenharmony_ci// generate list of versions
3732e5b6d6dSopenharmony_cistatic
3742e5b6d6dSopenharmony_ci#include <icuglue/fe_verlist.h>
3752e5b6d6dSopenharmony_ci
3762e5b6d6dSopenharmony_ciclass VersionCollatorFactory : public CollatorFactory {
3772e5b6d6dSopenharmony_cipublic:
3782e5b6d6dSopenharmony_ci  virtual Collator *createCollator(const Locale &loc);
3792e5b6d6dSopenharmony_ci  virtual const UnicodeString *getSupportedIDs(int32_t &count, UErrorCode &status);
3802e5b6d6dSopenharmony_ci  virtual void* getDynamicClassID() const;
3812e5b6d6dSopenharmony_ci  static void* getStaticClassID() ;
3822e5b6d6dSopenharmony_ci};
3832e5b6d6dSopenharmony_ci
3842e5b6d6dSopenharmony_ciUOBJECT_DEFINE_RTTI_IMPLEMENTATION( VersionCollatorFactory )
3852e5b6d6dSopenharmony_ci
3862e5b6d6dSopenharmony_ciCollator *VersionCollatorFactory::createCollator(const Locale &loc) {
3872e5b6d6dSopenharmony_ci    // pull off provider #
3882e5b6d6dSopenharmony_ci    char provider[200];
3892e5b6d6dSopenharmony_ci    UErrorCode status = U_ZERO_ERROR;
3902e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
3912e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF:CC %s\n", loc.getName());
3922e5b6d6dSopenharmony_ci#endif
3932e5b6d6dSopenharmony_ci    int32_t len = loc.getKeywordValue("sp", provider, 200, status);
3942e5b6d6dSopenharmony_ci    if(U_FAILURE(status)||len==0) return NULL;
3952e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
3962e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF:KWV> %s/%d\n", u_errorName(status), len);
3972e5b6d6dSopenharmony_ci#endif
3982e5b6d6dSopenharmony_ci    provider[len]=0;
3992e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
4002e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF:KWV %s\n", provider);
4012e5b6d6dSopenharmony_ci#endif
4022e5b6d6dSopenharmony_ci    if(strncmp(provider,"icu",3)) return NULL;
4032e5b6d6dSopenharmony_ci    const char *icuver=provider+3;
4042e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
4052e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF:ICUV %s\n", icuver);
4062e5b6d6dSopenharmony_ci#endif
4072e5b6d6dSopenharmony_ci
4082e5b6d6dSopenharmony_ci#if defined(GLUE_VER)
4092e5b6d6dSopenharmony_ci#undef GLUE_VER
4102e5b6d6dSopenharmony_ci#endif
4112e5b6d6dSopenharmony_ci
4122e5b6d6dSopenharmony_ci#define GLUE_VER(x) \
4132e5b6d6dSopenharmony_ci    debugfprintf((stderr,"%c/%c|%c/%c\n", icuver[0],(#x)[0],icuver[1],(#x)[2]));  \
4142e5b6d6dSopenharmony_ci    if(CMP_VERSTR(icuver, (#x))) {                                      \
4152e5b6d6dSopenharmony_ci      Collator *c = glue ## Collator ## x :: create(loc, icuver); \
4162e5b6d6dSopenharmony_ci      debugfprintf((stderr, "VCF::CC %s -> %p\n", loc.getName(), c)); \
4172e5b6d6dSopenharmony_ci      return c; \
4182e5b6d6dSopenharmony_ci    }
4192e5b6d6dSopenharmony_ci
4202e5b6d6dSopenharmony_ci#include "icuglue/glver.h"
4212e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
4222e5b6d6dSopenharmony_ci    fprintf(stderr,  "VCF:CC %s failed\n", loc.getName());
4232e5b6d6dSopenharmony_ci#endif
4242e5b6d6dSopenharmony_ci
4252e5b6d6dSopenharmony_ci    return NULL;
4262e5b6d6dSopenharmony_ci}
4272e5b6d6dSopenharmony_ci
4282e5b6d6dSopenharmony_ci
4292e5b6d6dSopenharmony_cistatic const UnicodeString *gLocales = NULL;
4302e5b6d6dSopenharmony_cistatic  int32_t gLocCount = 0;
4312e5b6d6dSopenharmony_ci
4322e5b6d6dSopenharmony_ciconst UnicodeString
4332e5b6d6dSopenharmony_ci*VersionCollatorFactory::getSupportedIDs(int32_t &count, UErrorCode &/*status*/) {
4342e5b6d6dSopenharmony_ci  if(gLocales==NULL) {
4352e5b6d6dSopenharmony_ci    count = 0;
4362e5b6d6dSopenharmony_ci
4372e5b6d6dSopenharmony_ci
4382e5b6d6dSopenharmony_ci    /* gather counts */
4392e5b6d6dSopenharmony_ci#if defined(GLUE_VER)
4402e5b6d6dSopenharmony_ci#undef GLUE_VER
4412e5b6d6dSopenharmony_ci#endif
4422e5b6d6dSopenharmony_ci#define GLUE_VER(x) count += glue ## Collator ## x :: countAvailable();
4432e5b6d6dSopenharmony_ci#include "icuglue/glver.h"
4442e5b6d6dSopenharmony_ci
4452e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
4462e5b6d6dSopenharmony_ci    printf("VCF: count=%d\n", count);
4472e5b6d6dSopenharmony_ci#endif
4482e5b6d6dSopenharmony_ci    UnicodeString *strs = new  UnicodeString[count];
4492e5b6d6dSopenharmony_ci    int32_t i = 0;
4502e5b6d6dSopenharmony_ci
4512e5b6d6dSopenharmony_ci#if defined(GLUE_VER)
4522e5b6d6dSopenharmony_ci#undef GLUE_VER
4532e5b6d6dSopenharmony_ci#endif
4542e5b6d6dSopenharmony_ci#define GLUE_VER(x) i += glue ## Collator ## x :: appendAvailable(strs, i, count);
4552e5b6d6dSopenharmony_ci#include "icuglue/glver.h"
4562e5b6d6dSopenharmony_ci
4572e5b6d6dSopenharmony_ci#if COLL_FE_DEBUG
4582e5b6d6dSopenharmony_ci    printf("VCF: appended count=%d\n", count);
4592e5b6d6dSopenharmony_ci#endif
4602e5b6d6dSopenharmony_ci
4612e5b6d6dSopenharmony_ci    gLocCount = count;
4622e5b6d6dSopenharmony_ci    gLocales = strs;
4632e5b6d6dSopenharmony_ci  }
4642e5b6d6dSopenharmony_ci  count = gLocCount;
4652e5b6d6dSopenharmony_ci  return gLocales;
4662e5b6d6dSopenharmony_ci}
4672e5b6d6dSopenharmony_ci
4682e5b6d6dSopenharmony_ci
4692e5b6d6dSopenharmony_ci/* Plugin Code */
4702e5b6d6dSopenharmony_ci
4712e5b6d6dSopenharmony_ci#include <stdio.h>
4722e5b6d6dSopenharmony_ci#include <unicode/uversion.h>
4732e5b6d6dSopenharmony_ci
4742e5b6d6dSopenharmony_cistatic URegistryKey rk = NULL;
4752e5b6d6dSopenharmony_ci
4762e5b6d6dSopenharmony_civoid coll_provider_register(UErrorCode &status) {
4772e5b6d6dSopenharmony_ci  rk = Collator::registerFactory(new VersionCollatorFactory(), status);
4782e5b6d6dSopenharmony_ci}
4792e5b6d6dSopenharmony_ci
4802e5b6d6dSopenharmony_civoid coll_provider_unregister(UErrorCode &status) {
4812e5b6d6dSopenharmony_ci  Collator::unregister(rk, status);
4822e5b6d6dSopenharmony_ci}
4832e5b6d6dSopenharmony_ci
4842e5b6d6dSopenharmony_ci/* Plugin- only ICU 4.4+ */
4852e5b6d6dSopenharmony_ci#if (U_ICU_VERSION_MAJOR_NUM > 4) || ((U_ICU_VERSION_MAJOR_NUM==4)&&(U_ICU_VERSION_MINOR_NUM>3))
4862e5b6d6dSopenharmony_ci#include "unicode/icuplug.h"
4872e5b6d6dSopenharmony_ci
4882e5b6d6dSopenharmony_ciU_CAPI UPlugTokenReturn U_EXPORT2 coll_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status);
4892e5b6d6dSopenharmony_ci
4902e5b6d6dSopenharmony_ciU_CAPI UPlugTokenReturn U_EXPORT2 coll_provider_plugin (UPlugData *data, UPlugReason reason, UErrorCode *status)
4912e5b6d6dSopenharmony_ci{
4922e5b6d6dSopenharmony_ci  switch(reason) {
4932e5b6d6dSopenharmony_ci  case UPLUG_REASON_QUERY:
4942e5b6d6dSopenharmony_ci    uplug_setPlugName(data, "Collation Provider Plugin");
4952e5b6d6dSopenharmony_ci    uplug_setPlugLevel(data, UPLUG_LEVEL_HIGH);
4962e5b6d6dSopenharmony_ci    break;
4972e5b6d6dSopenharmony_ci  case UPLUG_REASON_LOAD:
4982e5b6d6dSopenharmony_ci    coll_provider_register(*status);
4992e5b6d6dSopenharmony_ci    break;
5002e5b6d6dSopenharmony_ci  case UPLUG_REASON_UNLOAD:
5012e5b6d6dSopenharmony_ci    coll_provider_unregister(*status);
5022e5b6d6dSopenharmony_ci    break;
5032e5b6d6dSopenharmony_ci  default:
5042e5b6d6dSopenharmony_ci    break; /* not handled */
5052e5b6d6dSopenharmony_ci  }
5062e5b6d6dSopenharmony_ci  return UPLUG_TOKEN;
5072e5b6d6dSopenharmony_ci}
5082e5b6d6dSopenharmony_ci#else
5092e5b6d6dSopenharmony_ci
5102e5b6d6dSopenharmony_ci/*
5112e5b6d6dSopenharmony_ci   Note: this ICU version must explicitly call 'coll_provider_plugin'
5122e5b6d6dSopenharmony_ci*/
5132e5b6d6dSopenharmony_ci
5142e5b6d6dSopenharmony_ci#endif /* plugin */
5152e5b6d6dSopenharmony_ci
5162e5b6d6dSopenharmony_ci#endif /* provider side (vs target) */
517