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 #include <i18nutil/oneToOneMapping.hxx>
25 
26 namespace com { namespace sun { namespace star { namespace i18n {
27 
oneToOneMapping(OneToOneMappingTable_t * rpTable,const size_t rnBytes,const size_t rnUnitSize)28 oneToOneMapping::oneToOneMapping( OneToOneMappingTable_t *rpTable, const size_t rnBytes, const size_t rnUnitSize )
29     : mpTable( rpTable ),
30       mnSize( rnBytes / rnUnitSize )
31 {
32 }
33 
~oneToOneMapping()34 oneToOneMapping::~oneToOneMapping()
35 {
36 }
37 
find(const sal_Unicode nKey) const38 sal_Unicode oneToOneMapping::find(const sal_Unicode nKey) const
39 {
40     if( mpTable )
41     {
42         // binary search
43 	    int bottom = 0;
44 	    int top = mnSize - 1;
45 	    int current;
46 
47 	    for (;;) {
48             current = (top + bottom) / 2;
49             if( nKey < mpTable[current].first )
50                 top = current - 1;
51             else if( nKey > mpTable[current].first )
52                 bottom = current + 1;
53             else
54                 return mpTable[current].second;
55 
56             if( bottom > top )
57                 return sal_Unicode( nKey );
58 	    }
59     }
60     else
61         return sal_Unicode( nKey );
62 }
63 
oneToOneMappingWithFlag(UnicodePairWithFlag * rpTableWF,const size_t rnSize,const UnicodePairFlag rnFlag)64 oneToOneMappingWithFlag::oneToOneMappingWithFlag( UnicodePairWithFlag *rpTableWF, const size_t rnSize, const UnicodePairFlag rnFlag )
65     : oneToOneMapping( NULL, rnSize, sizeof(UnicodePairWithFlag) ),
66       mpTableWF ( rpTableWF ),
67       mnFlag    ( rnFlag ),
68       mbHasIndex( sal_False )
69 {
70 }
71 
~oneToOneMappingWithFlag()72 oneToOneMappingWithFlag::~oneToOneMappingWithFlag()
73 {
74 	if( mbHasIndex )
75         for( int i = 0; i < 256; i++ )
76             if( mpIndex[i] )
77                 delete [] mpIndex[i];
78 }
79 
80 
makeIndex()81 void oneToOneMappingWithFlag::makeIndex()
82 {
83     if( !mbHasIndex && mpTableWF )
84     {
85         int i, j, high, low, current = -1;
86 
87         for( i = 0; i < 256; i++ )
88             mpIndex[i] = NULL;
89 
90         for( size_t k = 0; k < mnSize; k++ )
91         {
92             high = (mpTableWF[k].first >> 8) & 0xFF;
93             low  = (mpTableWF[k].first)      & 0xFF;
94             if( high != current )
95             {
96                 current = high;
97                 mpIndex[high] = new UnicodePairWithFlag*[256];
98 
99                 for( j = 0; j < 256; j++ )
100                     mpIndex[high][j] = NULL;
101             }
102             mpIndex[high][low] = &mpTableWF[k];
103         }
104 
105         mbHasIndex = sal_True;
106     }
107 }
108 
find(const sal_Unicode nKey) const109 sal_Unicode oneToOneMappingWithFlag::find( const sal_Unicode nKey ) const
110 {
111     if( mpTableWF )
112     {
113         if( mbHasIndex )
114         {
115             // index search
116             int high, low;
117             high = (nKey >> 8) & 0xFF;
118             low = nKey & 0xFF;
119             if( mpIndex[high] != NULL &&
120                 mpIndex[high][low] != NULL &&
121                 mpIndex[high][low]->flag & mnFlag )
122                 return mpIndex[high][low]->second;
123             else
124                 return sal_Unicode( nKey );
125         }
126         else
127         {
128             // binary search
129             int bottom = 0;
130             int top = mnSize - 1;
131             int current;
132 
133             for (;;) {
134                 current = (top + bottom) / 2;
135                 if( nKey < mpTableWF[current].first )
136                     top = current - 1;
137                 else if( nKey > mpTableWF[current].first )
138                     bottom = current + 1;
139                 else
140                 {
141                     if( mpTableWF[current].flag & mnFlag )
142                         return mpTableWF[current].second;
143                     else
144                         return sal_Unicode( nKey );
145                 }
146 
147                 if( bottom > top )
148                     return sal_Unicode( nKey );
149             }
150 	    }
151 	}
152     else
153         return sal_Unicode( nKey );
154 }
155 
156 
157 } } } }
158