xref: /AOO41X/main/i18npool/source/breakiterator/breakiterator_ctl.cxx (revision 449ab281255486d6ec349c45a6ad7906d6939331)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_i18npool.hxx"
26 
27 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
28 #include <breakiterator_ctl.hxx>
29 
30 #include <string.h> // for memset
31 
32 using namespace ::com::sun::star::uno;
33 using namespace ::com::sun::star::lang;
34 using namespace ::rtl;
35 
36 namespace com { namespace sun { namespace star { namespace i18n {
37 
38 /**
39  * Constructor.
40  */
BreakIterator_CTL()41 BreakIterator_CTL::BreakIterator_CTL() :
42     cachedText(),
43     nextCellIndex( NULL ),
44     previousCellIndex( NULL ),
45     cellIndexSize( 512 )
46 {
47     cBreakIterator = "com.sun.star.i18n.BreakIterator_CTL";
48     // to improve performance, alloc big enough memory in construct.
49     nextCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32));
50     previousCellIndex = (sal_Int32*) calloc(cellIndexSize, sizeof(sal_Int32));
51     memset(nextCellIndex, 0, cellIndexSize * sizeof(sal_Int32));
52 }
53 
54 /**
55  * Deconstructor.
56  */
~BreakIterator_CTL()57 BreakIterator_CTL::~BreakIterator_CTL()
58 {
59     free(nextCellIndex);
60     free(previousCellIndex);
61 }
62 
previousCharacters(const OUString & Text,sal_Int32 nStartPos,const lang::Locale & rLocale,sal_Int16 nCharacterIteratorMode,sal_Int32 nCount,sal_Int32 & nDone)63 sal_Int32 SAL_CALL BreakIterator_CTL::previousCharacters( const OUString& Text,
64     sal_Int32 nStartPos, const lang::Locale& rLocale,
65     sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone )
66     throw(RuntimeException)
67 {
68     if (nCharacterIteratorMode == CharacterIteratorMode::SKIPCELL ) {
69         nDone = 0;
70         if (nStartPos > 0) {    // for others to skip cell.
71         makeIndex(Text, nStartPos);
72 
73         if (nextCellIndex[nStartPos-1] == 0) // not a CTL character
74             return BreakIterator_Unicode::previousCharacters(Text, nStartPos, rLocale,
75                 nCharacterIteratorMode, nCount, nDone);
76         else while (nCount > 0 && nextCellIndex[nStartPos - 1] > 0) {
77             nCount--; nDone++;
78             nStartPos = previousCellIndex[nStartPos - 1];
79         }
80         } else
81         nStartPos = 0;
82     } else { // for BS to delete one char.
83         nDone = (nStartPos > nCount) ? nCount : nStartPos;
84         nStartPos -= nDone;
85     }
86 
87     return nStartPos;
88 }
89 
nextCharacters(const OUString & Text,sal_Int32 nStartPos,const lang::Locale & rLocale,sal_Int16 nCharacterIteratorMode,sal_Int32 nCount,sal_Int32 & nDone)90 sal_Int32 SAL_CALL BreakIterator_CTL::nextCharacters(const OUString& Text,
91     sal_Int32 nStartPos, const lang::Locale& rLocale,
92     sal_Int16 nCharacterIteratorMode, sal_Int32 nCount, sal_Int32& nDone)
93     throw(RuntimeException)
94 {
95     sal_Int32 len = Text.getLength();
96     if (nCharacterIteratorMode == CharacterIteratorMode::SKIPCELL ) {
97         nDone = 0;
98         if (nStartPos < len) {
99         makeIndex(Text, nStartPos);
100 
101         if (nextCellIndex[nStartPos] == 0) // not a CTL character
102             return BreakIterator_Unicode::nextCharacters(Text, nStartPos, rLocale,
103                 nCharacterIteratorMode, nCount, nDone);
104         else while (nCount > 0 && nextCellIndex[nStartPos] > 0) {
105             nCount--; nDone++;
106             nStartPos = nextCellIndex[nStartPos];
107         }
108         } else
109         nStartPos = len;
110     } else {
111         nDone = (len - nStartPos > nCount) ? nCount : len - nStartPos;
112         nStartPos += nDone;
113     }
114 
115     return nStartPos;
116 }
117 
118 // This method should be overwritten by derived language specific class.
makeIndex(const OUString &,sal_Int32)119 void SAL_CALL BreakIterator_CTL::makeIndex(const OUString& /*text*/, sal_Int32 /*pos*/)
120     throw(RuntimeException)
121 {
122     throw RuntimeException();
123 }
124 
125 // Make sure line is broken on cell boundary if we implement cell iterator.
getLineBreak(const OUString & Text,sal_Int32 nStartPos,const lang::Locale & rLocale,sal_Int32 nMinBreakPos,const LineBreakHyphenationOptions & hOptions,const LineBreakUserOptions & bOptions)126 LineBreakResults SAL_CALL BreakIterator_CTL::getLineBreak(
127     const OUString& Text, sal_Int32 nStartPos,
128     const lang::Locale& rLocale, sal_Int32 nMinBreakPos,
129     const LineBreakHyphenationOptions& hOptions,
130     const LineBreakUserOptions& bOptions ) throw(RuntimeException)
131 {
132     LineBreakResults lbr = BreakIterator_Unicode::getLineBreak(Text, nStartPos,
133                     rLocale, nMinBreakPos, hOptions, bOptions );
134     if (lbr.breakIndex < Text.getLength()) {
135         makeIndex(Text, lbr.breakIndex);
136         lbr.breakIndex = previousCellIndex[ lbr.breakIndex ];
137     }
138     return lbr;
139 }
140 
141 } } } }
142