Home | History | Annotate | Download | only in common
      1 /*
      2 ********************************************************************************
      3 *   Copyright (C) 1996-2008, International Business Machines
      4 *   Corporation and others.  All Rights Reserved.
      5 ********************************************************************************
      6 */
      7 
      8 #include "unicode/utypes.h"
      9 
     10 #if !UCONFIG_NO_BREAK_ITERATION
     11 
     12 #include "unicode/ubrk.h"
     13 
     14 #include "unicode/brkiter.h"
     15 #include "unicode/uloc.h"
     16 #include "unicode/ustring.h"
     17 #include "unicode/uchriter.h"
     18 #include "unicode/rbbi.h"
     19 #include "rbbirb.h"
     20 #include "uassert.h"
     21 
     22 U_NAMESPACE_USE
     23 
     24 //------------------------------------------------------------------------------
     25 //
     26 //    ubrk_open      Create a canned type of break iterator based on type (word, line, etc.)
     27 //                   and locale.
     28 //
     29 //------------------------------------------------------------------------------
     30 U_CAPI UBreakIterator* U_EXPORT2
     31 ubrk_open(UBreakIteratorType type,
     32       const char *locale,
     33       const UChar *text,
     34       int32_t textLength,
     35       UErrorCode *status)
     36 {
     37 
     38   if(U_FAILURE(*status)) return 0;
     39 
     40   BreakIterator *result = 0;
     41 
     42   switch(type) {
     43 
     44   case UBRK_CHARACTER:
     45     result = BreakIterator::createCharacterInstance(Locale(locale), *status);
     46     break;
     47 
     48   case UBRK_WORD:
     49     result = BreakIterator::createWordInstance(Locale(locale), *status);
     50     break;
     51 
     52   case UBRK_LINE:
     53     result = BreakIterator::createLineInstance(Locale(locale), *status);
     54     break;
     55 
     56   case UBRK_SENTENCE:
     57     result = BreakIterator::createSentenceInstance(Locale(locale), *status);
     58     break;
     59 
     60   case UBRK_TITLE:
     61     result = BreakIterator::createTitleInstance(Locale(locale), *status);
     62     break;
     63 
     64   default:
     65     *status = U_ILLEGAL_ARGUMENT_ERROR;
     66   }
     67 
     68   // check for allocation error
     69   if (U_FAILURE(*status)) {
     70      return 0;
     71   }
     72   if(result == 0) {
     73     *status = U_MEMORY_ALLOCATION_ERROR;
     74     return 0;
     75   }
     76 
     77 
     78   UBreakIterator *uBI = (UBreakIterator *)result;
     79   if (text != NULL) {
     80       ubrk_setText(uBI, text, textLength, status);
     81   }
     82   return uBI;
     83 }
     84 
     85 
     86 
     87 //------------------------------------------------------------------------------
     88 //
     89 //   ubrk_openRules      open a break iterator from a set of break rules.
     90 //                       Invokes the rule builder.
     91 //
     92 //------------------------------------------------------------------------------
     93 U_CAPI UBreakIterator* U_EXPORT2
     94 ubrk_openRules(  const UChar        *rules,
     95                        int32_t       rulesLength,
     96                  const UChar        *text,
     97                        int32_t       textLength,
     98                        UParseError  *parseErr,
     99                        UErrorCode   *status)  {
    100 
    101     if (status == NULL || U_FAILURE(*status)){
    102         return 0;
    103     }
    104 
    105     BreakIterator *result = 0;
    106     UnicodeString ruleString(rules, rulesLength);
    107     result = RBBIRuleBuilder::createRuleBasedBreakIterator(ruleString, parseErr, *status);
    108     if(U_FAILURE(*status)) {
    109         return 0;
    110     }
    111 
    112     UBreakIterator *uBI = (UBreakIterator *)result;
    113     if (text != NULL) {
    114         ubrk_setText(uBI, text, textLength, status);
    115     }
    116     return uBI;
    117 }
    118 
    119 
    120 
    121 
    122 
    123 U_CAPI UBreakIterator * U_EXPORT2
    124 ubrk_safeClone(
    125           const UBreakIterator *bi,
    126           void *stackBuffer,
    127           int32_t *pBufferSize,
    128           UErrorCode *status)
    129 {
    130     if (status == NULL || U_FAILURE(*status)){
    131         return 0;
    132     }
    133     if (!pBufferSize || !bi){
    134        *status = U_ILLEGAL_ARGUMENT_ERROR;
    135         return 0;
    136     }
    137     // Clear any incoming Safe Clone Allocated warning.
    138     //  Propagating this through to our return would really
    139     //  confuse our caller.
    140     if (*status==U_SAFECLONE_ALLOCATED_WARNING) {
    141         *status = U_ZERO_ERROR;
    142     }
    143     return (UBreakIterator *)(((BreakIterator*)bi)->
    144         createBufferClone(stackBuffer, *pBufferSize, *status));
    145 }
    146 
    147 
    148 
    149 U_CAPI void U_EXPORT2
    150 ubrk_close(UBreakIterator *bi)
    151 {
    152     BreakIterator *ubi = (BreakIterator*) bi;
    153     if (ubi) {
    154         if (ubi->isBufferClone()) {
    155             ubi->~BreakIterator();
    156             *(uint32_t *)ubi = 0xdeadbeef;
    157         } else {
    158             delete ubi;
    159         }
    160     }
    161 }
    162 
    163 U_CAPI void U_EXPORT2
    164 ubrk_setText(UBreakIterator* bi,
    165              const UChar*    text,
    166              int32_t         textLength,
    167              UErrorCode*     status)
    168 {
    169     if (bi == NULL) {
    170         if (U_SUCCESS(*status)) {
    171             *status = U_ILLEGAL_ARGUMENT_ERROR;
    172         }
    173         return;
    174     }
    175 
    176     BreakIterator *brit = (BreakIterator *)bi;
    177     UText  ut = UTEXT_INITIALIZER;
    178     utext_openUChars(&ut, text, textLength, status);
    179     brit->setText(&ut, *status);
    180     // A stack allocated UText wrapping a UCHar * string
    181     //   can be dumped without explicitly closing it.
    182 }
    183 
    184 
    185 
    186 U_CAPI void U_EXPORT2
    187 ubrk_setUText(UBreakIterator *bi,
    188              UText          *text,
    189              UErrorCode     *status)
    190 {
    191     if (bi == NULL) {
    192         if (U_SUCCESS(*status)) {
    193             *status = U_ILLEGAL_ARGUMENT_ERROR;
    194         }
    195         return;
    196     }
    197 
    198     RuleBasedBreakIterator *brit = (RuleBasedBreakIterator *)bi;
    199     brit->RuleBasedBreakIterator::setText(text, *status);
    200 }
    201 
    202 
    203 
    204 
    205 
    206 U_CAPI int32_t U_EXPORT2
    207 ubrk_current(const UBreakIterator *bi)
    208 {
    209 
    210   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::current();
    211 }
    212 
    213 U_CAPI int32_t U_EXPORT2
    214 ubrk_next(UBreakIterator *bi)
    215 {
    216 
    217   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::next();
    218 }
    219 
    220 U_CAPI int32_t U_EXPORT2
    221 ubrk_previous(UBreakIterator *bi)
    222 {
    223 
    224   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::previous();
    225 }
    226 
    227 U_CAPI int32_t U_EXPORT2
    228 ubrk_first(UBreakIterator *bi)
    229 {
    230 
    231   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::first();
    232 }
    233 
    234 U_CAPI int32_t U_EXPORT2
    235 ubrk_last(UBreakIterator *bi)
    236 {
    237 
    238   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::last();
    239 }
    240 
    241 U_CAPI int32_t U_EXPORT2
    242 ubrk_preceding(UBreakIterator *bi,
    243            int32_t offset)
    244 {
    245 
    246   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::preceding(offset);
    247 }
    248 
    249 U_CAPI int32_t U_EXPORT2
    250 ubrk_following(UBreakIterator *bi,
    251            int32_t offset)
    252 {
    253 
    254   return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::following(offset);
    255 }
    256 
    257 U_CAPI const char* U_EXPORT2
    258 ubrk_getAvailable(int32_t index)
    259 {
    260 
    261   return uloc_getAvailable(index);
    262 }
    263 
    264 U_CAPI int32_t U_EXPORT2
    265 ubrk_countAvailable()
    266 {
    267 
    268   return uloc_countAvailable();
    269 }
    270 
    271 
    272 U_CAPI  UBool U_EXPORT2
    273 ubrk_isBoundary(UBreakIterator *bi, int32_t offset)
    274 {
    275     return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::isBoundary(offset);
    276 }
    277 
    278 
    279 U_CAPI  int32_t U_EXPORT2
    280 ubrk_getRuleStatus(UBreakIterator *bi)
    281 {
    282     return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatus();
    283 }
    284 
    285 U_CAPI  int32_t U_EXPORT2
    286 ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status)
    287 {
    288     return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatusVec(fillInVec, capacity, *status);
    289 }
    290 
    291 
    292 U_CAPI const char* U_EXPORT2
    293 ubrk_getLocaleByType(const UBreakIterator *bi,
    294                      ULocDataLocaleType type,
    295                      UErrorCode* status)
    296 {
    297     if (bi == NULL) {
    298         if (U_SUCCESS(*status)) {
    299             *status = U_ILLEGAL_ARGUMENT_ERROR;
    300         }
    301         return NULL;
    302     }
    303     return ((BreakIterator*)bi)->getLocaleID(type, *status);
    304 }
    305 
    306 
    307 #endif /* #if !UCONFIG_NO_BREAK_ITERATION */
    308