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
22U_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//------------------------------------------------------------------------------
30U_CAPI UBreakIterator* U_EXPORT2
31ubrk_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//------------------------------------------------------------------------------
93U_CAPI UBreakIterator* U_EXPORT2
94ubrk_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
123U_CAPI UBreakIterator * U_EXPORT2
124ubrk_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
149U_CAPI void U_EXPORT2
150ubrk_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
163U_CAPI void U_EXPORT2
164ubrk_setText(UBreakIterator* bi,
165             const UChar*    text,
166             int32_t         textLength,
167             UErrorCode*     status)
168{
169    BreakIterator *brit = (BreakIterator *)bi;
170    UText  ut = UTEXT_INITIALIZER;
171    utext_openUChars(&ut, text, textLength, status);
172    brit->setText(&ut, *status);
173    // A stack allocated UText wrapping a UCHar * string
174    //   can be dumped without explicitly closing it.
175}
176
177
178
179U_CAPI void U_EXPORT2
180ubrk_setUText(UBreakIterator *bi,
181             UText          *text,
182             UErrorCode     *status)
183{
184    RuleBasedBreakIterator *brit = (RuleBasedBreakIterator *)bi;
185    brit->RuleBasedBreakIterator::setText(text, *status);
186}
187
188
189
190
191
192U_CAPI int32_t U_EXPORT2
193ubrk_current(const UBreakIterator *bi)
194{
195
196  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::current();
197}
198
199U_CAPI int32_t U_EXPORT2
200ubrk_next(UBreakIterator *bi)
201{
202
203  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::next();
204}
205
206U_CAPI int32_t U_EXPORT2
207ubrk_previous(UBreakIterator *bi)
208{
209
210  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::previous();
211}
212
213U_CAPI int32_t U_EXPORT2
214ubrk_first(UBreakIterator *bi)
215{
216
217  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::first();
218}
219
220U_CAPI int32_t U_EXPORT2
221ubrk_last(UBreakIterator *bi)
222{
223
224  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::last();
225}
226
227U_CAPI int32_t U_EXPORT2
228ubrk_preceding(UBreakIterator *bi,
229           int32_t offset)
230{
231
232  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::preceding(offset);
233}
234
235U_CAPI int32_t U_EXPORT2
236ubrk_following(UBreakIterator *bi,
237           int32_t offset)
238{
239
240  return ((RuleBasedBreakIterator*)bi)->RuleBasedBreakIterator::following(offset);
241}
242
243U_CAPI const char* U_EXPORT2
244ubrk_getAvailable(int32_t index)
245{
246
247  return uloc_getAvailable(index);
248}
249
250U_CAPI int32_t U_EXPORT2
251ubrk_countAvailable()
252{
253
254  return uloc_countAvailable();
255}
256
257
258U_CAPI  UBool U_EXPORT2
259ubrk_isBoundary(UBreakIterator *bi, int32_t offset)
260{
261    return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::isBoundary(offset);
262}
263
264
265U_CAPI  int32_t U_EXPORT2
266ubrk_getRuleStatus(UBreakIterator *bi)
267{
268    return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatus();
269}
270
271U_CAPI  int32_t U_EXPORT2
272ubrk_getRuleStatusVec(UBreakIterator *bi, int32_t *fillInVec, int32_t capacity, UErrorCode *status)
273{
274    return ((RuleBasedBreakIterator *)bi)->RuleBasedBreakIterator::getRuleStatusVec(fillInVec, capacity, *status);
275}
276
277
278U_CAPI const char* U_EXPORT2
279ubrk_getLocaleByType(const UBreakIterator *bi,
280                     ULocDataLocaleType type,
281                     UErrorCode* status)
282{
283    if (bi == NULL) {
284        if (U_SUCCESS(*status)) {
285            *status = U_ILLEGAL_ARGUMENT_ERROR;
286        }
287        return NULL;
288    }
289    return ((BreakIterator*)bi)->getLocaleID(type, *status);
290}
291
292
293#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
294