OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 2013-2014, International Business Machines | 3 * Copyright (C) 2013-2014, International Business Machines |
4 * Corporation and others. All Rights Reserved. | 4 * Corporation and others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 * collationrootelements.cpp | 6 * collationrootelements.cpp |
7 * | 7 * |
8 * created on: 2013mar05 | 8 * created on: 2013mar05 |
9 * created by: Markus W. Scherer | 9 * created by: Markus W. Scherer |
10 */ | 10 */ |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 CollationRootElements::getSecondaryBefore(uint32_t p, uint32_t s) const { | 117 CollationRootElements::getSecondaryBefore(uint32_t p, uint32_t s) const { |
118 int32_t index; | 118 int32_t index; |
119 uint32_t previousSec, sec; | 119 uint32_t previousSec, sec; |
120 if(p == 0) { | 120 if(p == 0) { |
121 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; | 121 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; |
122 // Gap at the beginning of the secondary CE range. | 122 // Gap at the beginning of the secondary CE range. |
123 previousSec = 0; | 123 previousSec = 0; |
124 sec = elements[index] >> 16; | 124 sec = elements[index] >> 16; |
125 } else { | 125 } else { |
126 index = findPrimary(p) + 1; | 126 index = findPrimary(p) + 1; |
127 previousSec = Collation::MERGE_SEPARATOR_WEIGHT16; | 127 previousSec = Collation::BEFORE_WEIGHT16; |
128 sec = Collation::COMMON_WEIGHT16; | 128 sec = getFirstSecTerForPrimary(index) >> 16; |
129 } | 129 } |
130 U_ASSERT(s >= sec); | 130 U_ASSERT(s >= sec); |
131 while(s > sec) { | 131 while(s > sec) { |
132 previousSec = sec; | 132 previousSec = sec; |
133 U_ASSERT((elements[index] & SEC_TER_DELTA_FLAG) != 0); | 133 U_ASSERT((elements[index] & SEC_TER_DELTA_FLAG) != 0); |
134 sec = elements[index++] >> 16; | 134 sec = elements[index++] >> 16; |
135 } | 135 } |
136 U_ASSERT(sec == s); | 136 U_ASSERT(sec == s); |
137 return previousSec; | 137 return previousSec; |
138 } | 138 } |
139 | 139 |
140 uint32_t | 140 uint32_t |
141 CollationRootElements::getTertiaryBefore(uint32_t p, uint32_t s, uint32_t t) con
st { | 141 CollationRootElements::getTertiaryBefore(uint32_t p, uint32_t s, uint32_t t) con
st { |
142 U_ASSERT((t & ~Collation::ONLY_TERTIARY_MASK) == 0); | 142 U_ASSERT((t & ~Collation::ONLY_TERTIARY_MASK) == 0); |
143 int32_t index; | 143 int32_t index; |
144 uint32_t previousTer, secTer; | 144 uint32_t previousTer, secTer; |
145 if(p == 0) { | 145 if(p == 0) { |
146 if(s == 0) { | 146 if(s == 0) { |
147 index = (int32_t)elements[IX_FIRST_TERTIARY_INDEX]; | 147 index = (int32_t)elements[IX_FIRST_TERTIARY_INDEX]; |
148 // Gap at the beginning of the tertiary CE range. | 148 // Gap at the beginning of the tertiary CE range. |
149 previousTer = 0; | 149 previousTer = 0; |
150 } else { | 150 } else { |
151 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; | 151 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; |
152 previousTer = Collation::MERGE_SEPARATOR_WEIGHT16; | 152 previousTer = Collation::BEFORE_WEIGHT16; |
153 } | 153 } |
154 secTer = elements[index] & ~SEC_TER_DELTA_FLAG; | 154 secTer = elements[index] & ~SEC_TER_DELTA_FLAG; |
155 } else { | 155 } else { |
156 index = findPrimary(p) + 1; | 156 index = findPrimary(p) + 1; |
157 previousTer = Collation::MERGE_SEPARATOR_WEIGHT16; | 157 previousTer = Collation::BEFORE_WEIGHT16; |
158 secTer = Collation::COMMON_SEC_AND_TER_CE; | 158 secTer = getFirstSecTerForPrimary(index); |
159 } | 159 } |
160 uint32_t st = (s << 16) | t; | 160 uint32_t st = (s << 16) | t; |
161 while(st > secTer) { | 161 while(st > secTer) { |
162 if((secTer >> 16) == s) { previousTer = secTer; } | 162 if((secTer >> 16) == s) { previousTer = secTer; } |
163 U_ASSERT((elements[index] & SEC_TER_DELTA_FLAG) != 0); | 163 U_ASSERT((elements[index] & SEC_TER_DELTA_FLAG) != 0); |
164 secTer = elements[index++] & ~SEC_TER_DELTA_FLAG; | 164 secTer = elements[index++] & ~SEC_TER_DELTA_FLAG; |
165 } | 165 } |
166 U_ASSERT(secTer == st); | 166 U_ASSERT(secTer == st); |
167 return previousTer & 0xffff; | 167 return previousTer & 0xffff; |
168 } | 168 } |
(...skipping 15 matching lines...) Expand all Loading... |
184 while((q & SEC_TER_DELTA_FLAG) != 0) { | 184 while((q & SEC_TER_DELTA_FLAG) != 0) { |
185 q = elements[++index]; | 185 q = elements[++index]; |
186 } | 186 } |
187 U_ASSERT((q & PRIMARY_STEP_MASK) == 0); | 187 U_ASSERT((q & PRIMARY_STEP_MASK) == 0); |
188 return q; | 188 return q; |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 uint32_t | 192 uint32_t |
193 CollationRootElements::getSecondaryAfter(int32_t index, uint32_t s) const { | 193 CollationRootElements::getSecondaryAfter(int32_t index, uint32_t s) const { |
| 194 uint32_t secTer; |
194 uint32_t secLimit; | 195 uint32_t secLimit; |
195 if(index == 0) { | 196 if(index == 0) { |
196 // primary = 0 | 197 // primary = 0 |
| 198 U_ASSERT(s != 0); |
197 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; | 199 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; |
| 200 secTer = elements[index]; |
198 // Gap at the end of the secondary CE range. | 201 // Gap at the end of the secondary CE range. |
199 secLimit = 0x10000; | 202 secLimit = 0x10000; |
200 } else { | 203 } else { |
201 U_ASSERT(index >= (int32_t)elements[IX_FIRST_PRIMARY_INDEX]); | 204 U_ASSERT(index >= (int32_t)elements[IX_FIRST_PRIMARY_INDEX]); |
202 ++index; | 205 secTer = getFirstSecTerForPrimary(index + 1); |
| 206 // If this is an explicit sec/ter unit, then it will be read once more. |
203 // Gap for secondaries of primary CEs. | 207 // Gap for secondaries of primary CEs. |
204 secLimit = getSecondaryBoundary(); | 208 secLimit = getSecondaryBoundary(); |
205 } | 209 } |
206 for(;;) { | 210 for(;;) { |
207 uint32_t secTer = elements[index]; | |
208 if((secTer & SEC_TER_DELTA_FLAG) == 0) { return secLimit; } | |
209 uint32_t sec = secTer >> 16; | 211 uint32_t sec = secTer >> 16; |
210 if(sec > s) { return sec; } | 212 if(sec > s) { return sec; } |
211 ++index; | 213 secTer = elements[++index]; |
| 214 if((secTer & SEC_TER_DELTA_FLAG) == 0) { return secLimit; } |
212 } | 215 } |
213 } | 216 } |
214 | 217 |
215 uint32_t | 218 uint32_t |
216 CollationRootElements::getTertiaryAfter(int32_t index, uint32_t s, uint32_t t) c
onst { | 219 CollationRootElements::getTertiaryAfter(int32_t index, uint32_t s, uint32_t t) c
onst { |
| 220 uint32_t secTer; |
217 uint32_t terLimit; | 221 uint32_t terLimit; |
218 if(index == 0) { | 222 if(index == 0) { |
219 // primary = 0 | 223 // primary = 0 |
220 if(s == 0) { | 224 if(s == 0) { |
| 225 U_ASSERT(t != 0); |
221 index = (int32_t)elements[IX_FIRST_TERTIARY_INDEX]; | 226 index = (int32_t)elements[IX_FIRST_TERTIARY_INDEX]; |
222 // Gap at the end of the tertiary CE range. | 227 // Gap at the end of the tertiary CE range. |
223 terLimit = 0x4000; | 228 terLimit = 0x4000; |
224 } else { | 229 } else { |
225 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; | 230 index = (int32_t)elements[IX_FIRST_SECONDARY_INDEX]; |
226 // Gap for tertiaries of primary/secondary CEs. | 231 // Gap for tertiaries of primary/secondary CEs. |
227 terLimit = getTertiaryBoundary(); | 232 terLimit = getTertiaryBoundary(); |
228 } | 233 } |
| 234 secTer = elements[index] & ~SEC_TER_DELTA_FLAG; |
229 } else { | 235 } else { |
230 U_ASSERT(index >= (int32_t)elements[IX_FIRST_PRIMARY_INDEX]); | 236 U_ASSERT(index >= (int32_t)elements[IX_FIRST_PRIMARY_INDEX]); |
231 ++index; | 237 secTer = getFirstSecTerForPrimary(index + 1); |
| 238 // If this is an explicit sec/ter unit, then it will be read once more. |
232 terLimit = getTertiaryBoundary(); | 239 terLimit = getTertiaryBoundary(); |
233 } | 240 } |
234 uint32_t st = (s << 16) | t; | 241 uint32_t st = (s << 16) | t; |
235 for(;;) { | 242 for(;;) { |
236 uint32_t secTer = elements[index]; | 243 if(secTer > st) { |
| 244 U_ASSERT((secTer >> 16) == s); |
| 245 return secTer & 0xffff; |
| 246 } |
| 247 secTer = elements[++index]; |
237 // No tertiary greater than t for this primary+secondary. | 248 // No tertiary greater than t for this primary+secondary. |
238 if((secTer & SEC_TER_DELTA_FLAG) == 0 || (secTer >> 16) > s) { return te
rLimit; } | 249 if((secTer & SEC_TER_DELTA_FLAG) == 0 || (secTer >> 16) > s) { return te
rLimit; } |
239 secTer &= ~SEC_TER_DELTA_FLAG; | 250 secTer &= ~SEC_TER_DELTA_FLAG; |
240 if(secTer > st) { return secTer & 0xffff; } | |
241 ++index; | |
242 } | 251 } |
243 } | 252 } |
244 | 253 |
| 254 uint32_t |
| 255 CollationRootElements::getFirstSecTerForPrimary(int32_t index) const { |
| 256 uint32_t secTer = elements[index]; |
| 257 if((secTer & SEC_TER_DELTA_FLAG) == 0) { |
| 258 // No sec/ter delta. |
| 259 return Collation::COMMON_SEC_AND_TER_CE; |
| 260 } |
| 261 secTer &= ~SEC_TER_DELTA_FLAG; |
| 262 if(secTer > Collation::COMMON_SEC_AND_TER_CE) { |
| 263 // Implied sec/ter. |
| 264 return Collation::COMMON_SEC_AND_TER_CE; |
| 265 } |
| 266 // Explicit sec/ter below common/common. |
| 267 return secTer; |
| 268 } |
| 269 |
245 int32_t | 270 int32_t |
246 CollationRootElements::findPrimary(uint32_t p) const { | 271 CollationRootElements::findPrimary(uint32_t p) const { |
247 // Requirement: p must occur as a root primary. | 272 // Requirement: p must occur as a root primary. |
248 U_ASSERT((p & 0xff) == 0); // at most a 3-byte primary | 273 U_ASSERT((p & 0xff) == 0); // at most a 3-byte primary |
249 int32_t index = findP(p); | 274 int32_t index = findP(p); |
250 // If p is in a range, then we just assume that p is an actual primary in th
is range. | 275 // If p is in a range, then we just assume that p is an actual primary in th
is range. |
251 // (Too cumbersome/expensive to check.) | 276 // (Too cumbersome/expensive to check.) |
252 // Otherwise, it must be an exact match. | 277 // Otherwise, it must be an exact match. |
253 U_ASSERT(isEndOfPrimaryRange(elements[index + 1]) || p == (elements[index] &
0xffffff00)); | 278 U_ASSERT(isEndOfPrimaryRange(elements[index + 1]) || p == (elements[index] &
0xffffff00)); |
254 return index; | 279 return index; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 } else { | 330 } else { |
306 start = i; | 331 start = i; |
307 } | 332 } |
308 } | 333 } |
309 return start; | 334 return start; |
310 } | 335 } |
311 | 336 |
312 U_NAMESPACE_END | 337 U_NAMESPACE_END |
313 | 338 |
314 #endif // !UCONFIG_NO_COLLATION | 339 #endif // !UCONFIG_NO_COLLATION |
OLD | NEW |