1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ************************************************************************************
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * Copyright (C) 2006-2009,2011, International Business Machines Corporation        *
4b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho * and others. All Rights Reserved.                                                 *
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ************************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h"
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_BREAK_ITERATION
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "brkeng.h"
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "dictbe.h"
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "triedict.h"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uchar.h"
16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uniset.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/chariter.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h"
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h"
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h"
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h"
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uscript.h"
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uvector.h"
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h"
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uresimp.h"
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ubrkimpl.h"
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLanguageBreakEngine::LanguageBreakEngine() {
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLanguageBreakEngine::~LanguageBreakEngine() {
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLanguageBreakFactory::LanguageBreakFactory() {
45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruLanguageBreakFactory::~LanguageBreakFactory() {
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnhandledEngine::UnhandledEngine(UErrorCode &/*status*/) {
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0])); ++i) {
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fHandled[i] = 0;
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnhandledEngine::~UnhandledEngine() {
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    for (int32_t i = 0; i < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0])); ++i) {
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fHandled[i] != 0) {
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete fHandled[i];
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnhandledEngine::handles(UChar32 c, int32_t breakType) const {
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        && fHandled[breakType] != 0 && fHandled[breakType]->contains(c));
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnhandledEngine::findBreaks( UText *text,
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 int32_t startPos,
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 int32_t endPos,
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 UBool reverse,
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 int32_t breakType,
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                                 UStack &/*foundBreaks*/ ) const {
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))) {
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar32 c = utext_current32(text);
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (reverse) {
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while((int32_t)utext_getNativeIndex(text) > startPos && fHandled[breakType]->contains(c)) {
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                c = utext_previous32(text);
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            while((int32_t)utext_getNativeIndex(text) < endPos && fHandled[breakType]->contains(c)) {
90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                utext_next32(text);            // TODO:  recast loop to work with post-increment operations.
91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                c = utext_current32(text);
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return 0;
96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnhandledEngine::handleCharacter(UChar32 c, int32_t breakType) {
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (breakType >= 0 && breakType < (int32_t)(sizeof(fHandled)/sizeof(fHandled[0]))) {
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (fHandled[breakType] == 0) {
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fHandled[breakType] = new UnicodeSet();
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fHandled[breakType] == 0) {
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                return;
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (!fHandled[breakType]->contains(c)) {
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            UErrorCode status = U_ZERO_ERROR;
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            // Apply the entire script of the character.
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            int32_t script = u_getIntPropertyValue(c, UCHAR_SCRIPT);
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            fHandled[breakType]->applyIntPropertyValue(UCHAR_SCRIPT, script, status);
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ******************************************************************
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruICULanguageBreakFactory::ICULanguageBreakFactory(UErrorCode &/*status*/) {
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    fEngines = 0;
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruICULanguageBreakFactory::~ICULanguageBreakFactory() {
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fEngines != 0) {
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        delete fEngines;
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_BEGIN
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void U_CALLCONV _deleteEngine(void *obj) {
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete (const U_NAMESPACE_QUALIFIER LanguageBreakEngine *) obj;
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_CDECL_END
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst LanguageBreakEngine *
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruICULanguageBreakFactory::getEngineFor(UChar32 c, int32_t breakType) {
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool       needsInit;
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t     i;
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const LanguageBreakEngine *lbe = NULL;
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode  status = U_ZERO_ERROR;
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // TODO: The global mutex should not be used.
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // The global mutex should only be used for short periods.
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // A ICULanguageBreakFactory specific mutex should be used.
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_lock(NULL);
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    needsInit = (UBool)(fEngines == NULL);
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (!needsInit) {
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        i = fEngines->size();
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        while (--i >= 0) {
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (lbe != NULL && lbe->handles(c, breakType)) {
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            lbe = NULL;
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_unlock(NULL);
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (lbe != NULL) {
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return lbe;
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (needsInit) {
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UStack  *engines = new UStack(_deleteEngine, NULL, status);
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_SUCCESS(status) && engines == NULL) {
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_MEMORY_ALLOCATION_ERROR;
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else if (U_FAILURE(status)) {
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete engines;
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            engines = NULL;
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        else {
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            umtx_lock(NULL);
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (fEngines == NULL) {
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                fEngines = engines;
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                engines = NULL;
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            umtx_unlock(NULL);
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete engines;
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (fEngines == NULL) {
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return NULL;
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // We didn't find an engine the first time through, or there was no
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // stack. Create an engine.
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const LanguageBreakEngine *newlbe = loadEngineFor(c, breakType);
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Now get the lock, and see if someone else has created it in the
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // meantime
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_lock(NULL);
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    i = fEngines->size();
198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    while (--i >= 0) {
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        lbe = (const LanguageBreakEngine *)(fEngines->elementAt(i));
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (lbe != NULL && lbe->handles(c, breakType)) {
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            break;
202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        lbe = NULL;
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (lbe == NULL && newlbe != NULL) {
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        fEngines->push((void *)newlbe, status);
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        lbe = newlbe;
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        newlbe = NULL;
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    umtx_unlock(NULL);
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    delete newlbe;
213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return lbe;
215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst LanguageBreakEngine *
218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruICULanguageBreakFactory::loadEngineFor(UChar32 c, int32_t breakType) {
219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UScriptCode code = uscript_getScript(c, &status);
221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const CompactTrieDictionary *dict = loadDictionaryFor(code, breakType);
223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (dict != NULL) {
224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            const LanguageBreakEngine *engine = NULL;
225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            switch(code) {
226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            case USCRIPT_THAI:
227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                engine = new ThaiBreakEngine(dict, status);
228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            case USCRIPT_KHMER:
230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                engine = new KhmerBreakEngine(dict, status);
231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                break;
232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            default:
233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                break;
234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            if (engine == NULL) {
236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete dict;
237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            else if (U_FAILURE(status)) {
239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                delete engine;
240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                engine = NULL;
241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            }
242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            return engine;
243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return NULL;
246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst CompactTrieDictionary *
249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruICULanguageBreakFactory::loadDictionaryFor(UScriptCode script, int32_t /*breakType*/) {
250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    // Open root from brkitr tree.
252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char dictnbuff[256];
253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    char ext[4]={'\0'};
254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UResourceBundle *b = ures_open(U_ICUDATA_BRKITR, "", &status);
256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b = ures_getByKeyWithFallback(b, "dictionaries", b, &status);
257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    b = ures_getByKeyWithFallback(b, uscript_getShortName(script), b, &status);
258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t dictnlength = 0;
259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UChar *dictfname = ures_getString(b, &dictnlength, &status);
260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status) && (size_t)dictnlength >= sizeof(dictnbuff)) {
261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dictnlength = 0;
262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        status = U_BUFFER_OVERFLOW_ERROR;
263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status) && dictfname) {
265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        UChar* extStart=u_strchr(dictfname, 0x002e);
266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        int len = 0;
267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if(extStart!=NULL){
26850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho            len = (int)(extStart-dictfname);
269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            u_UCharsToChars(extStart+1, ext, sizeof(ext)); // nul terminates the buff
270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            u_UCharsToChars(dictfname, dictnbuff, len);
271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        dictnbuff[len]=0; // nul terminate
273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ures_close(b);
275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UDataMemory *file = udata_open(U_ICUDATA_BRKITR, ext, dictnbuff, &status);
276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        const CompactTrieDictionary *dict = new CompactTrieDictionary(
278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            file, status);
279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_SUCCESS(status) && dict == NULL) {
280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status = U_MEMORY_ALLOCATION_ERROR;
281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        if (U_FAILURE(status)) {
283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            delete dict;
284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            dict = NULL;
285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        }
286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return dict;
287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return NULL;
289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
292b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
293b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_BREAK_ITERATION */
294