LCOV - code coverage report
Current view: top level - intl/icu/source/common - ustrenum.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 160 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) 2002-2014, International Business Machines
       6             : * Corporation and others.  All Rights Reserved.
       7             : **********************************************************************
       8             : * Author: Alan Liu
       9             : * Created: November 11 2002
      10             : * Since: ICU 2.4
      11             : **********************************************************************
      12             : */
      13             : #include "utypeinfo.h"  // for 'typeid' to work 
      14             : 
      15             : #include "unicode/ustring.h"
      16             : #include "unicode/strenum.h"
      17             : #include "unicode/putil.h"
      18             : #include "uenumimp.h"
      19             : #include "ustrenum.h"
      20             : #include "cstring.h"
      21             : #include "cmemory.h"
      22             : #include "uassert.h"
      23             : 
      24             : U_NAMESPACE_BEGIN
      25             : // StringEnumeration implementation ---------------------------------------- ***
      26             : 
      27           0 : StringEnumeration::StringEnumeration()
      28           0 :     : chars(charsBuffer), charsCapacity(sizeof(charsBuffer)) {
      29           0 : }
      30             : 
      31           0 : StringEnumeration::~StringEnumeration() {
      32           0 :     if (chars != NULL && chars != charsBuffer) {
      33           0 :         uprv_free(chars);
      34             :     }
      35           0 : }
      36             : 
      37             : // StringEnumeration base class clone() default implementation, does not clone
      38             : StringEnumeration *
      39           0 : StringEnumeration::clone() const {
      40           0 :   return NULL;
      41             : }
      42             : 
      43             : const char *
      44           0 : StringEnumeration::next(int32_t *resultLength, UErrorCode &status) {
      45           0 :     const UnicodeString *s=snext(status);
      46           0 :     if(U_SUCCESS(status) && s!=NULL) {
      47           0 :         unistr=*s;
      48           0 :         ensureCharsCapacity(unistr.length()+1, status);
      49           0 :         if(U_SUCCESS(status)) {
      50           0 :             if(resultLength!=NULL) {
      51           0 :                 *resultLength=unistr.length();
      52             :             }
      53           0 :             unistr.extract(0, INT32_MAX, chars, charsCapacity, US_INV);
      54           0 :             return chars;
      55             :         }
      56             :     }
      57             : 
      58           0 :     return NULL;
      59             : }
      60             : 
      61             : const UChar *
      62           0 : StringEnumeration::unext(int32_t *resultLength, UErrorCode &status) {
      63           0 :     const UnicodeString *s=snext(status);
      64           0 :     if(U_SUCCESS(status) && s!=NULL) {
      65           0 :         unistr=*s;
      66           0 :         if(resultLength!=NULL) {
      67           0 :             *resultLength=unistr.length();
      68             :         }
      69           0 :         return unistr.getTerminatedBuffer();
      70             :     }
      71             : 
      72           0 :     return NULL;
      73             : }
      74             : 
      75             : const UnicodeString *
      76           0 : StringEnumeration::snext(UErrorCode &status) {
      77             :     int32_t length;
      78           0 :     const char *s=next(&length, status);
      79           0 :     return setChars(s, length, status);
      80             : }
      81             : 
      82             : void
      83           0 : StringEnumeration::ensureCharsCapacity(int32_t capacity, UErrorCode &status) {
      84           0 :     if(U_SUCCESS(status) && capacity>charsCapacity) {
      85           0 :         if(capacity<(charsCapacity+charsCapacity/2)) {
      86             :             // avoid allocation thrashing
      87           0 :             capacity=charsCapacity+charsCapacity/2;
      88             :         }
      89           0 :         if(chars!=charsBuffer) {
      90           0 :             uprv_free(chars);
      91             :         }
      92           0 :         chars=(char *)uprv_malloc(capacity);
      93           0 :         if(chars==NULL) {
      94           0 :             chars=charsBuffer;
      95           0 :             charsCapacity=sizeof(charsBuffer);
      96           0 :             status=U_MEMORY_ALLOCATION_ERROR;
      97             :         } else {
      98           0 :             charsCapacity=capacity;
      99             :         }
     100             :     }
     101           0 : }
     102             : 
     103             : UnicodeString *
     104           0 : StringEnumeration::setChars(const char *s, int32_t length, UErrorCode &status) {
     105           0 :     if(U_SUCCESS(status) && s!=NULL) {
     106           0 :         if(length<0) {
     107           0 :             length=(int32_t)uprv_strlen(s);
     108             :         }
     109             : 
     110           0 :         UChar *buffer=unistr.getBuffer(length+1);
     111           0 :         if(buffer!=NULL) {
     112           0 :             u_charsToUChars(s, buffer, length);
     113           0 :             buffer[length]=0;
     114           0 :             unistr.releaseBuffer(length);
     115           0 :             return &unistr;
     116             :         } else {
     117           0 :             status=U_MEMORY_ALLOCATION_ERROR;
     118             :         }
     119             :     }
     120             : 
     121           0 :     return NULL;
     122             : }
     123             : UBool 
     124           0 : StringEnumeration::operator==(const StringEnumeration& that)const {
     125           0 :     return typeid(*this) == typeid(that); 
     126             : }
     127             : 
     128             : UBool
     129           0 : StringEnumeration::operator!=(const StringEnumeration& that)const {
     130           0 :     return !operator==(that);
     131             : }
     132             : 
     133             : // UStringEnumeration implementation --------------------------------------- ***
     134             : 
     135             : UStringEnumeration * U_EXPORT2
     136           0 : UStringEnumeration::fromUEnumeration(
     137             :         UEnumeration *uenumToAdopt, UErrorCode &status) {
     138           0 :     if (U_FAILURE(status)) {
     139           0 :         uenum_close(uenumToAdopt);
     140           0 :         return NULL;
     141             :     }
     142           0 :     UStringEnumeration *result = new UStringEnumeration(uenumToAdopt);
     143           0 :     if (result == NULL) {
     144           0 :         status = U_MEMORY_ALLOCATION_ERROR;
     145           0 :         uenum_close(uenumToAdopt);
     146           0 :         return NULL;
     147             :     }
     148           0 :     return result;
     149             : }
     150             : 
     151           0 : UStringEnumeration::UStringEnumeration(UEnumeration* _uenum) :
     152           0 :     uenum(_uenum) {
     153           0 :     U_ASSERT(_uenum != 0);
     154           0 : }
     155             : 
     156           0 : UStringEnumeration::~UStringEnumeration() {
     157           0 :     uenum_close(uenum);
     158           0 : }
     159             : 
     160           0 : int32_t UStringEnumeration::count(UErrorCode& status) const {
     161           0 :     return uenum_count(uenum, &status);
     162             : }
     163             : 
     164           0 : const char *UStringEnumeration::next(int32_t *resultLength, UErrorCode &status) {
     165           0 :     return uenum_next(uenum, resultLength, &status);
     166             : }
     167             : 
     168           0 : const UnicodeString* UStringEnumeration::snext(UErrorCode& status) {
     169             :     int32_t length;
     170           0 :     const UChar* str = uenum_unext(uenum, &length, &status);
     171           0 :     if (str == 0 || U_FAILURE(status)) {
     172           0 :         return 0;
     173             :     }
     174           0 :     return &unistr.setTo(str, length);
     175             : }
     176             : 
     177           0 : void UStringEnumeration::reset(UErrorCode& status) {
     178           0 :     uenum_reset(uenum, &status);
     179           0 : }
     180             : 
     181           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(UStringEnumeration)
     182             : U_NAMESPACE_END
     183             : 
     184             : // C wrapper --------------------------------------------------------------- ***
     185             : 
     186             : #define THIS(en) ((icu::StringEnumeration*)(en->context))
     187             : 
     188             : U_CDECL_BEGIN
     189             : 
     190             : /**
     191             :  * Wrapper API to make StringEnumeration look like UEnumeration.
     192             :  */
     193             : static void U_CALLCONV
     194           0 : ustrenum_close(UEnumeration* en) {
     195           0 :     delete THIS(en);
     196           0 :     uprv_free(en);
     197           0 : }
     198             : 
     199             : /**
     200             :  * Wrapper API to make StringEnumeration look like UEnumeration.
     201             :  */
     202             : static int32_t U_CALLCONV
     203           0 : ustrenum_count(UEnumeration* en,
     204             :                UErrorCode* ec)
     205             : {
     206           0 :     return THIS(en)->count(*ec);
     207             : }
     208             : 
     209             : /**
     210             :  * Wrapper API to make StringEnumeration look like UEnumeration.
     211             :  */
     212             : static const UChar* U_CALLCONV
     213           0 : ustrenum_unext(UEnumeration* en,
     214             :                int32_t* resultLength,
     215             :                UErrorCode* ec)
     216             : {
     217           0 :     return THIS(en)->unext(resultLength, *ec);
     218             : }
     219             : 
     220             : /**
     221             :  * Wrapper API to make StringEnumeration look like UEnumeration.
     222             :  */
     223             : static const char* U_CALLCONV
     224           0 : ustrenum_next(UEnumeration* en,
     225             :               int32_t* resultLength,
     226             :               UErrorCode* ec)
     227             : {
     228           0 :     return THIS(en)->next(resultLength, *ec);
     229             : }
     230             : 
     231             : /**
     232             :  * Wrapper API to make StringEnumeration look like UEnumeration.
     233             :  */
     234             : static void U_CALLCONV
     235           0 : ustrenum_reset(UEnumeration* en,
     236             :                UErrorCode* ec)
     237             : {
     238           0 :     THIS(en)->reset(*ec);
     239           0 : }
     240             : 
     241             : /**
     242             :  * Pseudo-vtable for UEnumeration wrapper around StringEnumeration.
     243             :  * The StringEnumeration pointer will be stored in 'context'.
     244             :  */
     245             : static const UEnumeration USTRENUM_VT = {
     246             :     NULL,
     247             :     NULL, // store StringEnumeration pointer here
     248             :     ustrenum_close,
     249             :     ustrenum_count,
     250             :     ustrenum_unext,
     251             :     ustrenum_next,
     252             :     ustrenum_reset
     253             : };
     254             : 
     255             : U_CDECL_END
     256             : 
     257             : /**
     258             :  * Given a StringEnumeration, wrap it in a UEnumeration.  The
     259             :  * StringEnumeration is adopted; after this call, the caller must not
     260             :  * delete it (regardless of error status).
     261             :  */
     262             : U_CAPI UEnumeration* U_EXPORT2
     263           0 : uenum_openFromStringEnumeration(icu::StringEnumeration* adopted, UErrorCode* ec) { 
     264           0 :     UEnumeration* result = NULL;
     265           0 :     if (U_SUCCESS(*ec) && adopted != NULL) {
     266           0 :         result = (UEnumeration*) uprv_malloc(sizeof(UEnumeration));
     267           0 :         if (result == NULL) {
     268           0 :             *ec = U_MEMORY_ALLOCATION_ERROR;
     269             :         } else {
     270           0 :             uprv_memcpy(result, &USTRENUM_VT, sizeof(USTRENUM_VT));
     271           0 :             result->context = adopted;
     272             :         }
     273             :     }
     274           0 :     if (result == NULL) {
     275           0 :         delete adopted;
     276             :     }
     277           0 :     return result;
     278             : }
     279             : 
     280             : // C wrapper --------------------------------------------------------------- ***
     281             : 
     282             : U_CDECL_BEGIN
     283             : 
     284             : typedef struct UCharStringEnumeration {
     285             :     UEnumeration uenum;
     286             :     int32_t index, count;
     287             : } UCharStringEnumeration;
     288             : 
     289             : static void U_CALLCONV
     290           0 : ucharstrenum_close(UEnumeration* en) {
     291           0 :     uprv_free(en);
     292           0 : }
     293             : 
     294             : static int32_t U_CALLCONV
     295           0 : ucharstrenum_count(UEnumeration* en,
     296             :                    UErrorCode* /*ec*/) {
     297           0 :     return ((UCharStringEnumeration*)en)->count;
     298             : }
     299             : 
     300             : static const UChar* U_CALLCONV
     301           0 : ucharstrenum_unext(UEnumeration* en,
     302             :                   int32_t* resultLength,
     303             :                   UErrorCode* /*ec*/) {
     304           0 :     UCharStringEnumeration *e = (UCharStringEnumeration*) en;
     305           0 :     if (e->index >= e->count) {
     306           0 :         return NULL;
     307             :     }
     308           0 :     const UChar* result = ((const UChar**)e->uenum.context)[e->index++];
     309           0 :     if (resultLength) {
     310           0 :         *resultLength = (int32_t)u_strlen(result);
     311             :     }
     312           0 :     return result;
     313             : }
     314             : 
     315             : 
     316             : static const char* U_CALLCONV
     317           0 : ucharstrenum_next(UEnumeration* en,
     318             :                   int32_t* resultLength,
     319             :                   UErrorCode* /*ec*/) {
     320           0 :     UCharStringEnumeration *e = (UCharStringEnumeration*) en;
     321           0 :     if (e->index >= e->count) {
     322           0 :         return NULL;
     323             :     }
     324           0 :     const char* result = ((const char**)e->uenum.context)[e->index++];
     325           0 :     if (resultLength) {
     326           0 :         *resultLength = (int32_t)uprv_strlen(result);
     327             :     }
     328           0 :     return result;
     329             : }
     330             : 
     331             : static void U_CALLCONV
     332           0 : ucharstrenum_reset(UEnumeration* en,
     333             :                    UErrorCode* /*ec*/) {
     334           0 :     ((UCharStringEnumeration*)en)->index = 0;
     335           0 : }
     336             : 
     337             : static const UEnumeration UCHARSTRENUM_VT = {
     338             :     NULL,
     339             :     NULL, // store StringEnumeration pointer here
     340             :     ucharstrenum_close,
     341             :     ucharstrenum_count,
     342             :     uenum_unextDefault,
     343             :     ucharstrenum_next,
     344             :     ucharstrenum_reset
     345             : };
     346             : 
     347             : static const UEnumeration UCHARSTRENUM_U_VT = {
     348             :     NULL,
     349             :     NULL, // store StringEnumeration pointer here
     350             :     ucharstrenum_close,
     351             :     ucharstrenum_count,
     352             :     ucharstrenum_unext,
     353             :     uenum_nextDefault,
     354             :     ucharstrenum_reset
     355             : };
     356             : 
     357             : U_CDECL_END
     358             : 
     359             : U_CAPI UEnumeration* U_EXPORT2
     360           0 : uenum_openCharStringsEnumeration(const char* const strings[], int32_t count,
     361             :                                  UErrorCode* ec) {
     362           0 :     UCharStringEnumeration* result = NULL;
     363           0 :     if (U_SUCCESS(*ec) && count >= 0 && (count == 0 || strings != 0)) {
     364           0 :         result = (UCharStringEnumeration*) uprv_malloc(sizeof(UCharStringEnumeration));
     365           0 :         if (result == NULL) {
     366           0 :             *ec = U_MEMORY_ALLOCATION_ERROR;
     367             :         } else {
     368             :             U_ASSERT((char*)result==(char*)(&result->uenum));
     369           0 :             uprv_memcpy(result, &UCHARSTRENUM_VT, sizeof(UCHARSTRENUM_VT));
     370           0 :             result->uenum.context = (void*)strings;
     371           0 :             result->index = 0;
     372           0 :             result->count = count;
     373             :         }
     374             :     }
     375           0 :     return (UEnumeration*) result;
     376             : }
     377             : 
     378             : U_CAPI UEnumeration* U_EXPORT2
     379           0 : uenum_openUCharStringsEnumeration(const UChar* const strings[], int32_t count,
     380             :                                  UErrorCode* ec) {
     381           0 :     UCharStringEnumeration* result = NULL;
     382           0 :     if (U_SUCCESS(*ec) && count >= 0 && (count == 0 || strings != 0)) {
     383           0 :         result = (UCharStringEnumeration*) uprv_malloc(sizeof(UCharStringEnumeration));
     384           0 :         if (result == NULL) {
     385           0 :             *ec = U_MEMORY_ALLOCATION_ERROR;
     386             :         } else {
     387             :             U_ASSERT((char*)result==(char*)(&result->uenum));
     388           0 :             uprv_memcpy(result, &UCHARSTRENUM_U_VT, sizeof(UCHARSTRENUM_U_VT));
     389           0 :             result->uenum.context = (void*)strings;
     390           0 :             result->index = 0;
     391           0 :             result->count = count;
     392             :         }
     393             :     }
     394           0 :     return (UEnumeration*) result;
     395             : }
     396             : 
     397             : 
     398             : // end C Wrapper

Generated by: LCOV version 1.13